Skip to main content

fidl_fuchsia_hardware_power_charger/
fidl_fuchsia_hardware_power_charger.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_hardware_power_charger_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct ChargerWatchRequest {
16    pub lease: Option<fidl::EventPair>,
17}
18
19impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for ChargerWatchRequest {}
20
21#[derive(Debug, PartialEq)]
22pub struct ChargerWatchResponse {
23    pub status: Status,
24    pub wake_lease: Option<fidl::EventPair>,
25}
26
27impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for ChargerWatchResponse {}
28
29#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
30pub struct ChargerMarker;
31
32impl fidl::endpoints::ProtocolMarker for ChargerMarker {
33    type Proxy = ChargerProxy;
34    type RequestStream = ChargerRequestStream;
35    #[cfg(target_os = "fuchsia")]
36    type SynchronousProxy = ChargerSynchronousProxy;
37
38    const DEBUG_NAME: &'static str = "fuchsia.hardware.power.charger.Charger";
39}
40impl fidl::endpoints::DiscoverableProtocolMarker for ChargerMarker {}
41pub type ChargerGetSpecResult = Result<Spec, Error>;
42pub type ChargerGetStatusResult = Result<Status, Error>;
43pub type ChargerConfigureWatchResult = Result<WatchOptions, Error>;
44pub type ChargerWatchResult = Result<(Status, Option<fidl::EventPair>), Error>;
45
46pub trait ChargerProxyInterface: Send + Sync {
47    type GetSpecResponseFut: std::future::Future<Output = Result<ChargerGetSpecResult, fidl::Error>>
48        + Send;
49    fn r#get_spec(&self) -> Self::GetSpecResponseFut;
50    type GetStatusResponseFut: std::future::Future<Output = Result<ChargerGetStatusResult, fidl::Error>>
51        + Send;
52    fn r#get_status(&self) -> Self::GetStatusResponseFut;
53    type ConfigureWatchResponseFut: std::future::Future<Output = Result<ChargerConfigureWatchResult, fidl::Error>>
54        + Send;
55    fn r#configure_watch(&self, options: &WatchOptions) -> Self::ConfigureWatchResponseFut;
56    type WatchResponseFut: std::future::Future<Output = Result<ChargerWatchResult, fidl::Error>>
57        + Send;
58    fn r#watch(&self, lease: Option<fidl::EventPair>) -> Self::WatchResponseFut;
59}
60#[derive(Debug)]
61#[cfg(target_os = "fuchsia")]
62pub struct ChargerSynchronousProxy {
63    client: fidl::client::sync::Client,
64}
65
66#[cfg(target_os = "fuchsia")]
67impl fidl::endpoints::SynchronousProxy for ChargerSynchronousProxy {
68    type Proxy = ChargerProxy;
69    type Protocol = ChargerMarker;
70
71    fn from_channel(inner: fidl::Channel) -> Self {
72        Self::new(inner)
73    }
74
75    fn into_channel(self) -> fidl::Channel {
76        self.client.into_channel()
77    }
78
79    fn as_channel(&self) -> &fidl::Channel {
80        self.client.as_channel()
81    }
82}
83
84#[cfg(target_os = "fuchsia")]
85impl ChargerSynchronousProxy {
86    pub fn new(channel: fidl::Channel) -> Self {
87        Self { client: fidl::client::sync::Client::new(channel) }
88    }
89
90    pub fn into_channel(self) -> fidl::Channel {
91        self.client.into_channel()
92    }
93
94    /// Waits until an event arrives and returns it. It is safe for other
95    /// threads to make concurrent requests while waiting for an event.
96    pub fn wait_for_event(
97        &self,
98        deadline: zx::MonotonicInstant,
99    ) -> Result<ChargerEvent, fidl::Error> {
100        ChargerEvent::decode(self.client.wait_for_event::<ChargerMarker>(deadline)?)
101    }
102
103    /// Retrieves the static specification of the charger.
104    ///
105    /// Returns:
106    /// + `spec`: Static hardware characteristics and driver capabilities of the charger.
107    ///
108    /// Errors:
109    /// - `NOT_SUPPORTED`: Hardware does not supply a static specification.
110    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
111    /// - `INTERNAL`: Internal driver error.
112    pub fn r#get_spec(
113        &self,
114        ___deadline: zx::MonotonicInstant,
115    ) -> Result<ChargerGetSpecResult, fidl::Error> {
116        let _response = self.client.send_query::<
117            fidl::encoding::EmptyPayload,
118            fidl::encoding::FlexibleResultType<ChargerGetSpecResponse, Error>,
119            ChargerMarker,
120        >(
121            (),
122            0x4f1a5fc6df415db3,
123            fidl::encoding::DynamicFlags::FLEXIBLE,
124            ___deadline,
125        )?
126        .into_result::<ChargerMarker>("get_spec")?;
127        Ok(_response.map(|x| x.spec))
128    }
129
130    /// Retrieves an instantaneous snapshot of the charger status.
131    ///
132    /// Returns:
133    /// + `status`: Complete current telemetry snapshot of the charging regulator and its inputs.
134    ///
135    /// Errors:
136    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
137    /// - `INTERNAL`: Internal driver error.
138    pub fn r#get_status(
139        &self,
140        ___deadline: zx::MonotonicInstant,
141    ) -> Result<ChargerGetStatusResult, fidl::Error> {
142        let _response = self.client.send_query::<
143            fidl::encoding::EmptyPayload,
144            fidl::encoding::FlexibleResultType<ChargerGetStatusResponse, Error>,
145            ChargerMarker,
146        >(
147            (),
148            0x3c67651b7ec14d5e,
149            fidl::encoding::DynamicFlags::FLEXIBLE,
150            ___deadline,
151        )?
152        .into_result::<ChargerMarker>("get_status")?;
153        Ok(_response.map(|x| x.status))
154    }
155
156    /// Configures the fields of interest and wake triggers for this client connection.
157    ///
158    /// The driver filters the requested masks against hardware capabilities and returns the
159    /// effective configuration in `effective_options`.
160    ///
161    /// - **Partially supported options**: If some requested fields are supported and others are not
162    ///   (e.g., requesting passive fields like `input_voltage_uv` or `input_current_ua` that do not
163    ///   support active interrupt notifications), the driver enables the supported fields and
164    ///   returns the active subset in `effective_options`. The call succeeds (`Ok`).
165    /// - **Fully unsupported options**: If non-empty masks were specified but NONE of the requested
166    ///   fields are supported, the driver returns `NOT_SUPPORTED`.
167    ///
168    /// If `ConfigureWatch` is never called, `Watch` defaults to returning on ANY supported field
169    /// change. The driver aggregates constraints across all clients to determine hardware reporting
170    /// rates.
171    ///
172    /// Calling `ConfigureWatch` while a `Watch` call is already pending takes effect immediately:
173    /// if the current hardware state already differs from the last-delivered snapshot on a newly
174    /// enabled field, the pending `Watch` resolves immediately; otherwise it remains pending under
175    /// the updated mask.
176    ///
177    /// If `ConfigureWatch` returns an error, the connection's prior watch configuration remains
178    /// unchanged.
179    ///
180    /// Parameters:
181    /// + `options`: Requested watch options. Both `interest` and `wake_on` are optional.
182    ///
183    /// Returns:
184    /// + `effective_options`: The subset of requested options supported and enabled by the driver.
185    ///
186    /// Errors:
187    /// - `NOT_SUPPORTED`: Non-empty options were requested, but none of the requested
188    ///   interest/wake fields are supported by the driver.
189    pub fn r#configure_watch(
190        &self,
191        mut options: &WatchOptions,
192        ___deadline: zx::MonotonicInstant,
193    ) -> Result<ChargerConfigureWatchResult, fidl::Error> {
194        let _response = self.client.send_query::<
195            ChargerConfigureWatchRequest,
196            fidl::encoding::FlexibleResultType<ChargerConfigureWatchResponse, Error>,
197            ChargerMarker,
198        >(
199            (options,),
200            0x739a314e3494d695,
201            fidl::encoding::DynamicFlags::FLEXIBLE,
202            ___deadline,
203        )?
204        .into_result::<ChargerMarker>("configure_watch")?;
205        Ok(_response.map(|x| x.effective_options))
206    }
207
208    /// Watches for changes in charger state using a hanging-get pattern.
209    ///
210    /// The first call returns the full current hardware state immediately. Subsequent calls block
211    /// until a state change matches the masks in [`ConfigureWatch`]. Each return contains a
212    /// complete telemetry snapshot of all current charger fields, not a sparse delta.
213    ///
214    /// At most one `Watch` call may be outstanding per connection; concurrent calls fail with
215    /// `ALREADY_WATCHING`.
216    ///
217    /// Parameters:
218    /// + `lease`: An optional power lease token used to coordinate handoff between client and
219    ///   server, preventing the system from suspending before critical charger events are handled.
220    ///   If omitted, or if the driver does not support any `wake_on` fields, no lease coordination
221    ///   is performed and any provided token is dropped without returning a `wake_lease`.
222    ///
223    /// Returns:
224    /// + `status`: Complete current telemetry snapshot of the charger.
225    /// + `wake_lease`: An optional lease token provided if the change triggered a `wake_on`
226    ///   condition.
227    ///   Omitted if the change did not trigger a wake condition or if suspend coordination is
228    ///   inactive.
229    ///
230    /// Errors:
231    /// - `ALREADY_WATCHING`: A `Watch` call is already pending on this connection.
232    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
233    /// - `INTERNAL`: Internal driver error.
234    pub fn r#watch(
235        &self,
236        mut lease: Option<fidl::EventPair>,
237        ___deadline: zx::MonotonicInstant,
238    ) -> Result<ChargerWatchResult, fidl::Error> {
239        let _response = self.client.send_query::<
240            ChargerWatchRequest,
241            fidl::encoding::FlexibleResultType<ChargerWatchResponse, Error>,
242            ChargerMarker,
243        >(
244            (lease,),
245            0x5a52d95d33d7c66e,
246            fidl::encoding::DynamicFlags::FLEXIBLE,
247            ___deadline,
248        )?
249        .into_result::<ChargerMarker>("watch")?;
250        Ok(_response.map(|x| (x.status, x.wake_lease)))
251    }
252}
253
254#[cfg(target_os = "fuchsia")]
255impl From<ChargerSynchronousProxy> for zx::NullableHandle {
256    fn from(value: ChargerSynchronousProxy) -> Self {
257        value.into_channel().into()
258    }
259}
260
261#[cfg(target_os = "fuchsia")]
262impl From<fidl::Channel> for ChargerSynchronousProxy {
263    fn from(value: fidl::Channel) -> Self {
264        Self::new(value)
265    }
266}
267
268#[cfg(target_os = "fuchsia")]
269impl fidl::endpoints::FromClient for ChargerSynchronousProxy {
270    type Protocol = ChargerMarker;
271
272    fn from_client(value: fidl::endpoints::ClientEnd<ChargerMarker>) -> Self {
273        Self::new(value.into_channel())
274    }
275}
276
277#[derive(Debug, Clone)]
278pub struct ChargerProxy {
279    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
280}
281
282impl fidl::endpoints::Proxy for ChargerProxy {
283    type Protocol = ChargerMarker;
284
285    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
286        Self::new(inner)
287    }
288
289    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
290        self.client.into_channel().map_err(|client| Self { client })
291    }
292
293    fn as_channel(&self) -> &::fidl::AsyncChannel {
294        self.client.as_channel()
295    }
296}
297
298impl ChargerProxy {
299    /// Create a new Proxy for fuchsia.hardware.power.charger/Charger.
300    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
301        let protocol_name = <ChargerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
302        Self { client: fidl::client::Client::new(channel, protocol_name) }
303    }
304
305    /// Get a Stream of events from the remote end of the protocol.
306    ///
307    /// # Panics
308    ///
309    /// Panics if the event stream was already taken.
310    pub fn take_event_stream(&self) -> ChargerEventStream {
311        ChargerEventStream { event_receiver: self.client.take_event_receiver() }
312    }
313
314    /// Retrieves the static specification of the charger.
315    ///
316    /// Returns:
317    /// + `spec`: Static hardware characteristics and driver capabilities of the charger.
318    ///
319    /// Errors:
320    /// - `NOT_SUPPORTED`: Hardware does not supply a static specification.
321    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
322    /// - `INTERNAL`: Internal driver error.
323    pub fn r#get_spec(
324        &self,
325    ) -> fidl::client::QueryResponseFut<
326        ChargerGetSpecResult,
327        fidl::encoding::DefaultFuchsiaResourceDialect,
328    > {
329        ChargerProxyInterface::r#get_spec(self)
330    }
331
332    /// Retrieves an instantaneous snapshot of the charger status.
333    ///
334    /// Returns:
335    /// + `status`: Complete current telemetry snapshot of the charging regulator and its inputs.
336    ///
337    /// Errors:
338    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
339    /// - `INTERNAL`: Internal driver error.
340    pub fn r#get_status(
341        &self,
342    ) -> fidl::client::QueryResponseFut<
343        ChargerGetStatusResult,
344        fidl::encoding::DefaultFuchsiaResourceDialect,
345    > {
346        ChargerProxyInterface::r#get_status(self)
347    }
348
349    /// Configures the fields of interest and wake triggers for this client connection.
350    ///
351    /// The driver filters the requested masks against hardware capabilities and returns the
352    /// effective configuration in `effective_options`.
353    ///
354    /// - **Partially supported options**: If some requested fields are supported and others are not
355    ///   (e.g., requesting passive fields like `input_voltage_uv` or `input_current_ua` that do not
356    ///   support active interrupt notifications), the driver enables the supported fields and
357    ///   returns the active subset in `effective_options`. The call succeeds (`Ok`).
358    /// - **Fully unsupported options**: If non-empty masks were specified but NONE of the requested
359    ///   fields are supported, the driver returns `NOT_SUPPORTED`.
360    ///
361    /// If `ConfigureWatch` is never called, `Watch` defaults to returning on ANY supported field
362    /// change. The driver aggregates constraints across all clients to determine hardware reporting
363    /// rates.
364    ///
365    /// Calling `ConfigureWatch` while a `Watch` call is already pending takes effect immediately:
366    /// if the current hardware state already differs from the last-delivered snapshot on a newly
367    /// enabled field, the pending `Watch` resolves immediately; otherwise it remains pending under
368    /// the updated mask.
369    ///
370    /// If `ConfigureWatch` returns an error, the connection's prior watch configuration remains
371    /// unchanged.
372    ///
373    /// Parameters:
374    /// + `options`: Requested watch options. Both `interest` and `wake_on` are optional.
375    ///
376    /// Returns:
377    /// + `effective_options`: The subset of requested options supported and enabled by the driver.
378    ///
379    /// Errors:
380    /// - `NOT_SUPPORTED`: Non-empty options were requested, but none of the requested
381    ///   interest/wake fields are supported by the driver.
382    pub fn r#configure_watch(
383        &self,
384        mut options: &WatchOptions,
385    ) -> fidl::client::QueryResponseFut<
386        ChargerConfigureWatchResult,
387        fidl::encoding::DefaultFuchsiaResourceDialect,
388    > {
389        ChargerProxyInterface::r#configure_watch(self, options)
390    }
391
392    /// Watches for changes in charger state using a hanging-get pattern.
393    ///
394    /// The first call returns the full current hardware state immediately. Subsequent calls block
395    /// until a state change matches the masks in [`ConfigureWatch`]. Each return contains a
396    /// complete telemetry snapshot of all current charger fields, not a sparse delta.
397    ///
398    /// At most one `Watch` call may be outstanding per connection; concurrent calls fail with
399    /// `ALREADY_WATCHING`.
400    ///
401    /// Parameters:
402    /// + `lease`: An optional power lease token used to coordinate handoff between client and
403    ///   server, preventing the system from suspending before critical charger events are handled.
404    ///   If omitted, or if the driver does not support any `wake_on` fields, no lease coordination
405    ///   is performed and any provided token is dropped without returning a `wake_lease`.
406    ///
407    /// Returns:
408    /// + `status`: Complete current telemetry snapshot of the charger.
409    /// + `wake_lease`: An optional lease token provided if the change triggered a `wake_on`
410    ///   condition.
411    ///   Omitted if the change did not trigger a wake condition or if suspend coordination is
412    ///   inactive.
413    ///
414    /// Errors:
415    /// - `ALREADY_WATCHING`: A `Watch` call is already pending on this connection.
416    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
417    /// - `INTERNAL`: Internal driver error.
418    pub fn r#watch(
419        &self,
420        mut lease: Option<fidl::EventPair>,
421    ) -> fidl::client::QueryResponseFut<
422        ChargerWatchResult,
423        fidl::encoding::DefaultFuchsiaResourceDialect,
424    > {
425        ChargerProxyInterface::r#watch(self, lease)
426    }
427}
428
429impl ChargerProxyInterface for ChargerProxy {
430    type GetSpecResponseFut = fidl::client::QueryResponseFut<
431        ChargerGetSpecResult,
432        fidl::encoding::DefaultFuchsiaResourceDialect,
433    >;
434    fn r#get_spec(&self) -> Self::GetSpecResponseFut {
435        fn _decode(
436            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
437        ) -> Result<ChargerGetSpecResult, fidl::Error> {
438            let _response = fidl::client::decode_transaction_body::<
439                fidl::encoding::FlexibleResultType<ChargerGetSpecResponse, Error>,
440                fidl::encoding::DefaultFuchsiaResourceDialect,
441                0x4f1a5fc6df415db3,
442            >(_buf?)?
443            .into_result::<ChargerMarker>("get_spec")?;
444            Ok(_response.map(|x| x.spec))
445        }
446        self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ChargerGetSpecResult>(
447            (),
448            0x4f1a5fc6df415db3,
449            fidl::encoding::DynamicFlags::FLEXIBLE,
450            _decode,
451        )
452    }
453
454    type GetStatusResponseFut = fidl::client::QueryResponseFut<
455        ChargerGetStatusResult,
456        fidl::encoding::DefaultFuchsiaResourceDialect,
457    >;
458    fn r#get_status(&self) -> Self::GetStatusResponseFut {
459        fn _decode(
460            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
461        ) -> Result<ChargerGetStatusResult, fidl::Error> {
462            let _response = fidl::client::decode_transaction_body::<
463                fidl::encoding::FlexibleResultType<ChargerGetStatusResponse, Error>,
464                fidl::encoding::DefaultFuchsiaResourceDialect,
465                0x3c67651b7ec14d5e,
466            >(_buf?)?
467            .into_result::<ChargerMarker>("get_status")?;
468            Ok(_response.map(|x| x.status))
469        }
470        self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, ChargerGetStatusResult>(
471            (),
472            0x3c67651b7ec14d5e,
473            fidl::encoding::DynamicFlags::FLEXIBLE,
474            _decode,
475        )
476    }
477
478    type ConfigureWatchResponseFut = fidl::client::QueryResponseFut<
479        ChargerConfigureWatchResult,
480        fidl::encoding::DefaultFuchsiaResourceDialect,
481    >;
482    fn r#configure_watch(&self, mut options: &WatchOptions) -> Self::ConfigureWatchResponseFut {
483        fn _decode(
484            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
485        ) -> Result<ChargerConfigureWatchResult, fidl::Error> {
486            let _response = fidl::client::decode_transaction_body::<
487                fidl::encoding::FlexibleResultType<ChargerConfigureWatchResponse, Error>,
488                fidl::encoding::DefaultFuchsiaResourceDialect,
489                0x739a314e3494d695,
490            >(_buf?)?
491            .into_result::<ChargerMarker>("configure_watch")?;
492            Ok(_response.map(|x| x.effective_options))
493        }
494        self.client
495            .send_query_and_decode::<ChargerConfigureWatchRequest, ChargerConfigureWatchResult>(
496                (options,),
497                0x739a314e3494d695,
498                fidl::encoding::DynamicFlags::FLEXIBLE,
499                _decode,
500            )
501    }
502
503    type WatchResponseFut = fidl::client::QueryResponseFut<
504        ChargerWatchResult,
505        fidl::encoding::DefaultFuchsiaResourceDialect,
506    >;
507    fn r#watch(&self, mut lease: Option<fidl::EventPair>) -> Self::WatchResponseFut {
508        fn _decode(
509            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
510        ) -> Result<ChargerWatchResult, fidl::Error> {
511            let _response = fidl::client::decode_transaction_body::<
512                fidl::encoding::FlexibleResultType<ChargerWatchResponse, Error>,
513                fidl::encoding::DefaultFuchsiaResourceDialect,
514                0x5a52d95d33d7c66e,
515            >(_buf?)?
516            .into_result::<ChargerMarker>("watch")?;
517            Ok(_response.map(|x| (x.status, x.wake_lease)))
518        }
519        self.client.send_query_and_decode::<ChargerWatchRequest, ChargerWatchResult>(
520            (lease,),
521            0x5a52d95d33d7c66e,
522            fidl::encoding::DynamicFlags::FLEXIBLE,
523            _decode,
524        )
525    }
526}
527
528pub struct ChargerEventStream {
529    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
530}
531
532impl std::marker::Unpin for ChargerEventStream {}
533
534impl futures::stream::FusedStream for ChargerEventStream {
535    fn is_terminated(&self) -> bool {
536        self.event_receiver.is_terminated()
537    }
538}
539
540impl futures::Stream for ChargerEventStream {
541    type Item = Result<ChargerEvent, fidl::Error>;
542
543    fn poll_next(
544        mut self: std::pin::Pin<&mut Self>,
545        cx: &mut std::task::Context<'_>,
546    ) -> std::task::Poll<Option<Self::Item>> {
547        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
548            &mut self.event_receiver,
549            cx
550        )?) {
551            Some(buf) => std::task::Poll::Ready(Some(ChargerEvent::decode(buf))),
552            None => std::task::Poll::Ready(None),
553        }
554    }
555}
556
557#[derive(Debug)]
558pub enum ChargerEvent {
559    #[non_exhaustive]
560    _UnknownEvent {
561        /// Ordinal of the event that was sent.
562        ordinal: u64,
563    },
564}
565
566impl ChargerEvent {
567    /// Decodes a message buffer as a [`ChargerEvent`].
568    fn decode(
569        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
570    ) -> Result<ChargerEvent, fidl::Error> {
571        let (bytes, _handles) = buf.split_mut();
572        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
573        debug_assert_eq!(tx_header.tx_id, 0);
574        match tx_header.ordinal {
575            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
576                Ok(ChargerEvent::_UnknownEvent { ordinal: tx_header.ordinal })
577            }
578            _ => Err(fidl::Error::UnknownOrdinal {
579                ordinal: tx_header.ordinal,
580                protocol_name: <ChargerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
581            }),
582        }
583    }
584}
585
586/// A Stream of incoming requests for fuchsia.hardware.power.charger/Charger.
587pub struct ChargerRequestStream {
588    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
589    is_terminated: bool,
590}
591
592impl std::marker::Unpin for ChargerRequestStream {}
593
594impl futures::stream::FusedStream for ChargerRequestStream {
595    fn is_terminated(&self) -> bool {
596        self.is_terminated
597    }
598}
599
600impl fidl::endpoints::RequestStream for ChargerRequestStream {
601    type Protocol = ChargerMarker;
602    type ControlHandle = ChargerControlHandle;
603
604    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
605        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
606    }
607
608    fn control_handle(&self) -> Self::ControlHandle {
609        ChargerControlHandle { inner: self.inner.clone() }
610    }
611
612    fn into_inner(
613        self,
614    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
615    {
616        (self.inner, self.is_terminated)
617    }
618
619    fn from_inner(
620        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
621        is_terminated: bool,
622    ) -> Self {
623        Self { inner, is_terminated }
624    }
625}
626
627impl futures::Stream for ChargerRequestStream {
628    type Item = Result<ChargerRequest, fidl::Error>;
629
630    fn poll_next(
631        mut self: std::pin::Pin<&mut Self>,
632        cx: &mut std::task::Context<'_>,
633    ) -> std::task::Poll<Option<Self::Item>> {
634        let this = &mut *self;
635        if this.inner.check_shutdown(cx) {
636            this.is_terminated = true;
637            return std::task::Poll::Ready(None);
638        }
639        if this.is_terminated {
640            panic!("polled ChargerRequestStream after completion");
641        }
642        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
643            |bytes, handles| {
644                match this.inner.channel().read_etc(cx, bytes, handles) {
645                    std::task::Poll::Ready(Ok(())) => {}
646                    std::task::Poll::Pending => return std::task::Poll::Pending,
647                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
648                        this.is_terminated = true;
649                        return std::task::Poll::Ready(None);
650                    }
651                    std::task::Poll::Ready(Err(e)) => {
652                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
653                            e.into(),
654                        ))));
655                    }
656                }
657
658                // A message has been received from the channel
659                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
660
661                std::task::Poll::Ready(Some(match header.ordinal {
662                    0x4f1a5fc6df415db3 => {
663                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
664                        let mut req = fidl::new_empty!(
665                            fidl::encoding::EmptyPayload,
666                            fidl::encoding::DefaultFuchsiaResourceDialect
667                        );
668                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
669                        let control_handle = ChargerControlHandle { inner: this.inner.clone() };
670                        Ok(ChargerRequest::GetSpec {
671                            responder: ChargerGetSpecResponder {
672                                control_handle: std::mem::ManuallyDrop::new(control_handle),
673                                tx_id: header.tx_id,
674                            },
675                        })
676                    }
677                    0x3c67651b7ec14d5e => {
678                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
679                        let mut req = fidl::new_empty!(
680                            fidl::encoding::EmptyPayload,
681                            fidl::encoding::DefaultFuchsiaResourceDialect
682                        );
683                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
684                        let control_handle = ChargerControlHandle { inner: this.inner.clone() };
685                        Ok(ChargerRequest::GetStatus {
686                            responder: ChargerGetStatusResponder {
687                                control_handle: std::mem::ManuallyDrop::new(control_handle),
688                                tx_id: header.tx_id,
689                            },
690                        })
691                    }
692                    0x739a314e3494d695 => {
693                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
694                        let mut req = fidl::new_empty!(
695                            ChargerConfigureWatchRequest,
696                            fidl::encoding::DefaultFuchsiaResourceDialect
697                        );
698                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ChargerConfigureWatchRequest>(&header, _body_bytes, handles, &mut req)?;
699                        let control_handle = ChargerControlHandle { inner: this.inner.clone() };
700                        Ok(ChargerRequest::ConfigureWatch {
701                            options: req.options,
702
703                            responder: ChargerConfigureWatchResponder {
704                                control_handle: std::mem::ManuallyDrop::new(control_handle),
705                                tx_id: header.tx_id,
706                            },
707                        })
708                    }
709                    0x5a52d95d33d7c66e => {
710                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
711                        let mut req = fidl::new_empty!(
712                            ChargerWatchRequest,
713                            fidl::encoding::DefaultFuchsiaResourceDialect
714                        );
715                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ChargerWatchRequest>(&header, _body_bytes, handles, &mut req)?;
716                        let control_handle = ChargerControlHandle { inner: this.inner.clone() };
717                        Ok(ChargerRequest::Watch {
718                            lease: req.lease,
719
720                            responder: ChargerWatchResponder {
721                                control_handle: std::mem::ManuallyDrop::new(control_handle),
722                                tx_id: header.tx_id,
723                            },
724                        })
725                    }
726                    _ if header.tx_id == 0
727                        && header
728                            .dynamic_flags()
729                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
730                    {
731                        Ok(ChargerRequest::_UnknownMethod {
732                            ordinal: header.ordinal,
733                            control_handle: ChargerControlHandle { inner: this.inner.clone() },
734                            method_type: fidl::MethodType::OneWay,
735                        })
736                    }
737                    _ if header
738                        .dynamic_flags()
739                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
740                    {
741                        this.inner.send_framework_err(
742                            fidl::encoding::FrameworkErr::UnknownMethod,
743                            header.tx_id,
744                            header.ordinal,
745                            header.dynamic_flags(),
746                            (bytes, handles),
747                        )?;
748                        Ok(ChargerRequest::_UnknownMethod {
749                            ordinal: header.ordinal,
750                            control_handle: ChargerControlHandle { inner: this.inner.clone() },
751                            method_type: fidl::MethodType::TwoWay,
752                        })
753                    }
754                    _ => Err(fidl::Error::UnknownOrdinal {
755                        ordinal: header.ordinal,
756                        protocol_name:
757                            <ChargerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
758                    }),
759                }))
760            },
761        )
762    }
763}
764
765/// Diagnostic and telemetry interface for charging hardware.
766///
767/// This is a read-only protocol that supports multiple concurrent clients.
768#[derive(Debug)]
769pub enum ChargerRequest {
770    /// Retrieves the static specification of the charger.
771    ///
772    /// Returns:
773    /// + `spec`: Static hardware characteristics and driver capabilities of the charger.
774    ///
775    /// Errors:
776    /// - `NOT_SUPPORTED`: Hardware does not supply a static specification.
777    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
778    /// - `INTERNAL`: Internal driver error.
779    GetSpec { responder: ChargerGetSpecResponder },
780    /// Retrieves an instantaneous snapshot of the charger status.
781    ///
782    /// Returns:
783    /// + `status`: Complete current telemetry snapshot of the charging regulator and its inputs.
784    ///
785    /// Errors:
786    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
787    /// - `INTERNAL`: Internal driver error.
788    GetStatus { responder: ChargerGetStatusResponder },
789    /// Configures the fields of interest and wake triggers for this client connection.
790    ///
791    /// The driver filters the requested masks against hardware capabilities and returns the
792    /// effective configuration in `effective_options`.
793    ///
794    /// - **Partially supported options**: If some requested fields are supported and others are not
795    ///   (e.g., requesting passive fields like `input_voltage_uv` or `input_current_ua` that do not
796    ///   support active interrupt notifications), the driver enables the supported fields and
797    ///   returns the active subset in `effective_options`. The call succeeds (`Ok`).
798    /// - **Fully unsupported options**: If non-empty masks were specified but NONE of the requested
799    ///   fields are supported, the driver returns `NOT_SUPPORTED`.
800    ///
801    /// If `ConfigureWatch` is never called, `Watch` defaults to returning on ANY supported field
802    /// change. The driver aggregates constraints across all clients to determine hardware reporting
803    /// rates.
804    ///
805    /// Calling `ConfigureWatch` while a `Watch` call is already pending takes effect immediately:
806    /// if the current hardware state already differs from the last-delivered snapshot on a newly
807    /// enabled field, the pending `Watch` resolves immediately; otherwise it remains pending under
808    /// the updated mask.
809    ///
810    /// If `ConfigureWatch` returns an error, the connection's prior watch configuration remains
811    /// unchanged.
812    ///
813    /// Parameters:
814    /// + `options`: Requested watch options. Both `interest` and `wake_on` are optional.
815    ///
816    /// Returns:
817    /// + `effective_options`: The subset of requested options supported and enabled by the driver.
818    ///
819    /// Errors:
820    /// - `NOT_SUPPORTED`: Non-empty options were requested, but none of the requested
821    ///   interest/wake fields are supported by the driver.
822    ConfigureWatch { options: WatchOptions, responder: ChargerConfigureWatchResponder },
823    /// Watches for changes in charger state using a hanging-get pattern.
824    ///
825    /// The first call returns the full current hardware state immediately. Subsequent calls block
826    /// until a state change matches the masks in [`ConfigureWatch`]. Each return contains a
827    /// complete telemetry snapshot of all current charger fields, not a sparse delta.
828    ///
829    /// At most one `Watch` call may be outstanding per connection; concurrent calls fail with
830    /// `ALREADY_WATCHING`.
831    ///
832    /// Parameters:
833    /// + `lease`: An optional power lease token used to coordinate handoff between client and
834    ///   server, preventing the system from suspending before critical charger events are handled.
835    ///   If omitted, or if the driver does not support any `wake_on` fields, no lease coordination
836    ///   is performed and any provided token is dropped without returning a `wake_lease`.
837    ///
838    /// Returns:
839    /// + `status`: Complete current telemetry snapshot of the charger.
840    /// + `wake_lease`: An optional lease token provided if the change triggered a `wake_on`
841    ///   condition.
842    ///   Omitted if the change did not trigger a wake condition or if suspend coordination is
843    ///   inactive.
844    ///
845    /// Errors:
846    /// - `ALREADY_WATCHING`: A `Watch` call is already pending on this connection.
847    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
848    /// - `INTERNAL`: Internal driver error.
849    Watch { lease: Option<fidl::EventPair>, responder: ChargerWatchResponder },
850    /// An interaction was received which does not match any known method.
851    #[non_exhaustive]
852    _UnknownMethod {
853        /// Ordinal of the method that was called.
854        ordinal: u64,
855        control_handle: ChargerControlHandle,
856        method_type: fidl::MethodType,
857    },
858}
859
860impl ChargerRequest {
861    #[allow(irrefutable_let_patterns)]
862    pub fn into_get_spec(self) -> Option<(ChargerGetSpecResponder)> {
863        if let ChargerRequest::GetSpec { responder } = self { Some((responder)) } else { None }
864    }
865
866    #[allow(irrefutable_let_patterns)]
867    pub fn into_get_status(self) -> Option<(ChargerGetStatusResponder)> {
868        if let ChargerRequest::GetStatus { responder } = self { Some((responder)) } else { None }
869    }
870
871    #[allow(irrefutable_let_patterns)]
872    pub fn into_configure_watch(self) -> Option<(WatchOptions, ChargerConfigureWatchResponder)> {
873        if let ChargerRequest::ConfigureWatch { options, responder } = self {
874            Some((options, responder))
875        } else {
876            None
877        }
878    }
879
880    #[allow(irrefutable_let_patterns)]
881    pub fn into_watch(self) -> Option<(Option<fidl::EventPair>, ChargerWatchResponder)> {
882        if let ChargerRequest::Watch { lease, responder } = self {
883            Some((lease, responder))
884        } else {
885            None
886        }
887    }
888
889    /// Name of the method defined in FIDL
890    pub fn method_name(&self) -> &'static str {
891        match *self {
892            ChargerRequest::GetSpec { .. } => "get_spec",
893            ChargerRequest::GetStatus { .. } => "get_status",
894            ChargerRequest::ConfigureWatch { .. } => "configure_watch",
895            ChargerRequest::Watch { .. } => "watch",
896            ChargerRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
897                "unknown one-way method"
898            }
899            ChargerRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
900                "unknown two-way method"
901            }
902        }
903    }
904}
905
906#[derive(Debug, Clone)]
907pub struct ChargerControlHandle {
908    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
909}
910
911impl ChargerControlHandle {
912    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
913        self.inner.shutdown_with_epitaph(status.into())
914    }
915}
916
917impl fidl::endpoints::ControlHandle for ChargerControlHandle {
918    fn shutdown(&self) {
919        self.inner.shutdown()
920    }
921
922    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
923        self.inner.shutdown_with_epitaph(status)
924    }
925
926    fn is_closed(&self) -> bool {
927        self.inner.channel().is_closed()
928    }
929    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
930        self.inner.channel().on_closed()
931    }
932
933    #[cfg(target_os = "fuchsia")]
934    fn signal_peer(
935        &self,
936        clear_mask: zx::Signals,
937        set_mask: zx::Signals,
938    ) -> Result<(), zx_status::Status> {
939        use fidl::Peered;
940        self.inner.channel().signal_peer(clear_mask, set_mask)
941    }
942}
943
944impl ChargerControlHandle {}
945
946#[must_use = "FIDL methods require a response to be sent"]
947#[derive(Debug)]
948pub struct ChargerGetSpecResponder {
949    control_handle: std::mem::ManuallyDrop<ChargerControlHandle>,
950    tx_id: u32,
951}
952
953/// Set the the channel to be shutdown (see [`ChargerControlHandle::shutdown`])
954/// if the responder is dropped without sending a response, so that the client
955/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
956impl std::ops::Drop for ChargerGetSpecResponder {
957    fn drop(&mut self) {
958        self.control_handle.shutdown();
959        // Safety: drops once, never accessed again
960        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
961    }
962}
963
964impl fidl::endpoints::Responder for ChargerGetSpecResponder {
965    type ControlHandle = ChargerControlHandle;
966
967    fn control_handle(&self) -> &ChargerControlHandle {
968        &self.control_handle
969    }
970
971    fn drop_without_shutdown(mut self) {
972        // Safety: drops once, never accessed again due to mem::forget
973        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
974        // Prevent Drop from running (which would shut down the channel)
975        std::mem::forget(self);
976    }
977}
978
979impl ChargerGetSpecResponder {
980    /// Sends a response to the FIDL transaction.
981    ///
982    /// Sets the channel to shutdown if an error occurs.
983    pub fn send(self, mut result: Result<&Spec, Error>) -> Result<(), fidl::Error> {
984        let _result = self.send_raw(result);
985        if _result.is_err() {
986            self.control_handle.shutdown();
987        }
988        self.drop_without_shutdown();
989        _result
990    }
991
992    /// Similar to "send" but does not shutdown the channel if an error occurs.
993    pub fn send_no_shutdown_on_err(
994        self,
995        mut result: Result<&Spec, Error>,
996    ) -> Result<(), fidl::Error> {
997        let _result = self.send_raw(result);
998        self.drop_without_shutdown();
999        _result
1000    }
1001
1002    fn send_raw(&self, mut result: Result<&Spec, Error>) -> Result<(), fidl::Error> {
1003        self.control_handle
1004            .inner
1005            .send::<fidl::encoding::FlexibleResultType<ChargerGetSpecResponse, Error>>(
1006                fidl::encoding::FlexibleResult::new(result.map(|spec| (spec,))),
1007                self.tx_id,
1008                0x4f1a5fc6df415db3,
1009                fidl::encoding::DynamicFlags::FLEXIBLE,
1010            )
1011    }
1012}
1013
1014#[must_use = "FIDL methods require a response to be sent"]
1015#[derive(Debug)]
1016pub struct ChargerGetStatusResponder {
1017    control_handle: std::mem::ManuallyDrop<ChargerControlHandle>,
1018    tx_id: u32,
1019}
1020
1021/// Set the the channel to be shutdown (see [`ChargerControlHandle::shutdown`])
1022/// if the responder is dropped without sending a response, so that the client
1023/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1024impl std::ops::Drop for ChargerGetStatusResponder {
1025    fn drop(&mut self) {
1026        self.control_handle.shutdown();
1027        // Safety: drops once, never accessed again
1028        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1029    }
1030}
1031
1032impl fidl::endpoints::Responder for ChargerGetStatusResponder {
1033    type ControlHandle = ChargerControlHandle;
1034
1035    fn control_handle(&self) -> &ChargerControlHandle {
1036        &self.control_handle
1037    }
1038
1039    fn drop_without_shutdown(mut self) {
1040        // Safety: drops once, never accessed again due to mem::forget
1041        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1042        // Prevent Drop from running (which would shut down the channel)
1043        std::mem::forget(self);
1044    }
1045}
1046
1047impl ChargerGetStatusResponder {
1048    /// Sends a response to the FIDL transaction.
1049    ///
1050    /// Sets the channel to shutdown if an error occurs.
1051    pub fn send(self, mut result: Result<&Status, Error>) -> Result<(), fidl::Error> {
1052        let _result = self.send_raw(result);
1053        if _result.is_err() {
1054            self.control_handle.shutdown();
1055        }
1056        self.drop_without_shutdown();
1057        _result
1058    }
1059
1060    /// Similar to "send" but does not shutdown the channel if an error occurs.
1061    pub fn send_no_shutdown_on_err(
1062        self,
1063        mut result: Result<&Status, Error>,
1064    ) -> Result<(), fidl::Error> {
1065        let _result = self.send_raw(result);
1066        self.drop_without_shutdown();
1067        _result
1068    }
1069
1070    fn send_raw(&self, mut result: Result<&Status, Error>) -> Result<(), fidl::Error> {
1071        self.control_handle
1072            .inner
1073            .send::<fidl::encoding::FlexibleResultType<ChargerGetStatusResponse, Error>>(
1074                fidl::encoding::FlexibleResult::new(result.map(|status| (status,))),
1075                self.tx_id,
1076                0x3c67651b7ec14d5e,
1077                fidl::encoding::DynamicFlags::FLEXIBLE,
1078            )
1079    }
1080}
1081
1082#[must_use = "FIDL methods require a response to be sent"]
1083#[derive(Debug)]
1084pub struct ChargerConfigureWatchResponder {
1085    control_handle: std::mem::ManuallyDrop<ChargerControlHandle>,
1086    tx_id: u32,
1087}
1088
1089/// Set the the channel to be shutdown (see [`ChargerControlHandle::shutdown`])
1090/// if the responder is dropped without sending a response, so that the client
1091/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1092impl std::ops::Drop for ChargerConfigureWatchResponder {
1093    fn drop(&mut self) {
1094        self.control_handle.shutdown();
1095        // Safety: drops once, never accessed again
1096        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1097    }
1098}
1099
1100impl fidl::endpoints::Responder for ChargerConfigureWatchResponder {
1101    type ControlHandle = ChargerControlHandle;
1102
1103    fn control_handle(&self) -> &ChargerControlHandle {
1104        &self.control_handle
1105    }
1106
1107    fn drop_without_shutdown(mut self) {
1108        // Safety: drops once, never accessed again due to mem::forget
1109        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1110        // Prevent Drop from running (which would shut down the channel)
1111        std::mem::forget(self);
1112    }
1113}
1114
1115impl ChargerConfigureWatchResponder {
1116    /// Sends a response to the FIDL transaction.
1117    ///
1118    /// Sets the channel to shutdown if an error occurs.
1119    pub fn send(self, mut result: Result<&WatchOptions, Error>) -> Result<(), fidl::Error> {
1120        let _result = self.send_raw(result);
1121        if _result.is_err() {
1122            self.control_handle.shutdown();
1123        }
1124        self.drop_without_shutdown();
1125        _result
1126    }
1127
1128    /// Similar to "send" but does not shutdown the channel if an error occurs.
1129    pub fn send_no_shutdown_on_err(
1130        self,
1131        mut result: Result<&WatchOptions, Error>,
1132    ) -> Result<(), fidl::Error> {
1133        let _result = self.send_raw(result);
1134        self.drop_without_shutdown();
1135        _result
1136    }
1137
1138    fn send_raw(&self, mut result: Result<&WatchOptions, Error>) -> Result<(), fidl::Error> {
1139        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1140            ChargerConfigureWatchResponse,
1141            Error,
1142        >>(
1143            fidl::encoding::FlexibleResult::new(
1144                result.map(|effective_options| (effective_options,)),
1145            ),
1146            self.tx_id,
1147            0x739a314e3494d695,
1148            fidl::encoding::DynamicFlags::FLEXIBLE,
1149        )
1150    }
1151}
1152
1153#[must_use = "FIDL methods require a response to be sent"]
1154#[derive(Debug)]
1155pub struct ChargerWatchResponder {
1156    control_handle: std::mem::ManuallyDrop<ChargerControlHandle>,
1157    tx_id: u32,
1158}
1159
1160/// Set the the channel to be shutdown (see [`ChargerControlHandle::shutdown`])
1161/// if the responder is dropped without sending a response, so that the client
1162/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1163impl std::ops::Drop for ChargerWatchResponder {
1164    fn drop(&mut self) {
1165        self.control_handle.shutdown();
1166        // Safety: drops once, never accessed again
1167        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1168    }
1169}
1170
1171impl fidl::endpoints::Responder for ChargerWatchResponder {
1172    type ControlHandle = ChargerControlHandle;
1173
1174    fn control_handle(&self) -> &ChargerControlHandle {
1175        &self.control_handle
1176    }
1177
1178    fn drop_without_shutdown(mut self) {
1179        // Safety: drops once, never accessed again due to mem::forget
1180        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1181        // Prevent Drop from running (which would shut down the channel)
1182        std::mem::forget(self);
1183    }
1184}
1185
1186impl ChargerWatchResponder {
1187    /// Sends a response to the FIDL transaction.
1188    ///
1189    /// Sets the channel to shutdown if an error occurs.
1190    pub fn send(
1191        self,
1192        mut result: Result<(&Status, Option<fidl::EventPair>), Error>,
1193    ) -> Result<(), fidl::Error> {
1194        let _result = self.send_raw(result);
1195        if _result.is_err() {
1196            self.control_handle.shutdown();
1197        }
1198        self.drop_without_shutdown();
1199        _result
1200    }
1201
1202    /// Similar to "send" but does not shutdown the channel if an error occurs.
1203    pub fn send_no_shutdown_on_err(
1204        self,
1205        mut result: Result<(&Status, Option<fidl::EventPair>), Error>,
1206    ) -> Result<(), fidl::Error> {
1207        let _result = self.send_raw(result);
1208        self.drop_without_shutdown();
1209        _result
1210    }
1211
1212    fn send_raw(
1213        &self,
1214        mut result: Result<(&Status, Option<fidl::EventPair>), Error>,
1215    ) -> Result<(), fidl::Error> {
1216        self.control_handle
1217            .inner
1218            .send::<fidl::encoding::FlexibleResultType<ChargerWatchResponse, Error>>(
1219                fidl::encoding::FlexibleResult::new(result),
1220                self.tx_id,
1221                0x5a52d95d33d7c66e,
1222                fidl::encoding::DynamicFlags::FLEXIBLE,
1223            )
1224    }
1225}
1226
1227#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1228pub struct ControllerMarker;
1229
1230impl fidl::endpoints::ProtocolMarker for ControllerMarker {
1231    type Proxy = ControllerProxy;
1232    type RequestStream = ControllerRequestStream;
1233    #[cfg(target_os = "fuchsia")]
1234    type SynchronousProxy = ControllerSynchronousProxy;
1235
1236    const DEBUG_NAME: &'static str = "fuchsia.hardware.power.charger.Controller";
1237}
1238impl fidl::endpoints::DiscoverableProtocolMarker for ControllerMarker {}
1239pub type ControllerSetControlResult = Result<(), Error>;
1240pub type ControllerClearControlResult = Result<(), Error>;
1241
1242pub trait ControllerProxyInterface: Send + Sync {
1243    type SetControlResponseFut: std::future::Future<Output = Result<ControllerSetControlResult, fidl::Error>>
1244        + Send;
1245    fn r#set_control(&self, options: &ControlOptions) -> Self::SetControlResponseFut;
1246    type ClearControlResponseFut: std::future::Future<Output = Result<ControllerClearControlResult, fidl::Error>>
1247        + Send;
1248    fn r#clear_control(&self, options: &ControlOptions) -> Self::ClearControlResponseFut;
1249}
1250#[derive(Debug)]
1251#[cfg(target_os = "fuchsia")]
1252pub struct ControllerSynchronousProxy {
1253    client: fidl::client::sync::Client,
1254}
1255
1256#[cfg(target_os = "fuchsia")]
1257impl fidl::endpoints::SynchronousProxy for ControllerSynchronousProxy {
1258    type Proxy = ControllerProxy;
1259    type Protocol = ControllerMarker;
1260
1261    fn from_channel(inner: fidl::Channel) -> Self {
1262        Self::new(inner)
1263    }
1264
1265    fn into_channel(self) -> fidl::Channel {
1266        self.client.into_channel()
1267    }
1268
1269    fn as_channel(&self) -> &fidl::Channel {
1270        self.client.as_channel()
1271    }
1272}
1273
1274#[cfg(target_os = "fuchsia")]
1275impl ControllerSynchronousProxy {
1276    pub fn new(channel: fidl::Channel) -> Self {
1277        Self { client: fidl::client::sync::Client::new(channel) }
1278    }
1279
1280    pub fn into_channel(self) -> fidl::Channel {
1281        self.client.into_channel()
1282    }
1283
1284    /// Waits until an event arrives and returns it. It is safe for other
1285    /// threads to make concurrent requests while waiting for an event.
1286    pub fn wait_for_event(
1287        &self,
1288        deadline: zx::MonotonicInstant,
1289    ) -> Result<ControllerEvent, fidl::Error> {
1290        ControllerEvent::decode(self.client.wait_for_event::<ControllerMarker>(deadline)?)
1291    }
1292
1293    /// Applies operational and electrical constraints to the charger converter.
1294    ///
1295    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
1296    /// hardware and session state untouched. The response is returned only after all corresponding
1297    /// hardware register writes have completed and been acknowledged by the charger IC.
1298    ///
1299    /// Parameters:
1300    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
1301    ///   set on this connection for those fields; omitted fields leave this connection's prior
1302    ///   constraints for those fields unchanged.
1303    ///
1304    /// Errors:
1305    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
1306    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
1307    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
1308    ///   requested `operating_mode` conflicts with the active power path state (for example,
1309    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
1310    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
1311    /// - `INTERNAL`: Internal driver error.
1312    pub fn r#set_control(
1313        &self,
1314        mut options: &ControlOptions,
1315        ___deadline: zx::MonotonicInstant,
1316    ) -> Result<ControllerSetControlResult, fidl::Error> {
1317        let _response = self.client.send_query::<
1318            ControllerSetControlRequest,
1319            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
1320            ControllerMarker,
1321        >(
1322            (options,),
1323            0x363a64b0c8d45594,
1324            fidl::encoding::DynamicFlags::FLEXIBLE,
1325            ___deadline,
1326        )?
1327        .into_result::<ControllerMarker>("set_control")?;
1328        Ok(_response.map(|x| x))
1329    }
1330
1331    /// Withdraws constraints applied through this connection for the fields present in `options`.
1332    ///
1333    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
1334    /// field values themselves are ignored.
1335    ///
1336    /// - If `options` is empty (no fields set), **all** constraints applied through this
1337    ///   connection are withdrawn.
1338    /// - If one or more fields are set in `options`, only the constraints corresponding to those
1339    ///   fields are withdrawn, leaving any other fields untouched.
1340    ///
1341    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
1342    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
1343    /// Succeeds without effect for any targeted field that is not currently constrained.
1344    ///
1345    /// Parameters:
1346    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
1347    ///   empty table to withdraw all constraints on this connection.
1348    ///
1349    /// Errors:
1350    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
1351    ///   retain their constraint, so the call can be retried.
1352    /// - `INTERNAL`: Internal driver error.
1353    pub fn r#clear_control(
1354        &self,
1355        mut options: &ControlOptions,
1356        ___deadline: zx::MonotonicInstant,
1357    ) -> Result<ControllerClearControlResult, fidl::Error> {
1358        let _response = self.client.send_query::<
1359            ControllerClearControlRequest,
1360            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
1361            ControllerMarker,
1362        >(
1363            (options,),
1364            0x2b2a45d9fa0cd3c1,
1365            fidl::encoding::DynamicFlags::FLEXIBLE,
1366            ___deadline,
1367        )?
1368        .into_result::<ControllerMarker>("clear_control")?;
1369        Ok(_response.map(|x| x))
1370    }
1371}
1372
1373#[cfg(target_os = "fuchsia")]
1374impl From<ControllerSynchronousProxy> for zx::NullableHandle {
1375    fn from(value: ControllerSynchronousProxy) -> Self {
1376        value.into_channel().into()
1377    }
1378}
1379
1380#[cfg(target_os = "fuchsia")]
1381impl From<fidl::Channel> for ControllerSynchronousProxy {
1382    fn from(value: fidl::Channel) -> Self {
1383        Self::new(value)
1384    }
1385}
1386
1387#[cfg(target_os = "fuchsia")]
1388impl fidl::endpoints::FromClient for ControllerSynchronousProxy {
1389    type Protocol = ControllerMarker;
1390
1391    fn from_client(value: fidl::endpoints::ClientEnd<ControllerMarker>) -> Self {
1392        Self::new(value.into_channel())
1393    }
1394}
1395
1396#[derive(Debug, Clone)]
1397pub struct ControllerProxy {
1398    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
1399}
1400
1401impl fidl::endpoints::Proxy for ControllerProxy {
1402    type Protocol = ControllerMarker;
1403
1404    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
1405        Self::new(inner)
1406    }
1407
1408    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
1409        self.client.into_channel().map_err(|client| Self { client })
1410    }
1411
1412    fn as_channel(&self) -> &::fidl::AsyncChannel {
1413        self.client.as_channel()
1414    }
1415}
1416
1417impl ControllerProxy {
1418    /// Create a new Proxy for fuchsia.hardware.power.charger/Controller.
1419    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
1420        let protocol_name = <ControllerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1421        Self { client: fidl::client::Client::new(channel, protocol_name) }
1422    }
1423
1424    /// Get a Stream of events from the remote end of the protocol.
1425    ///
1426    /// # Panics
1427    ///
1428    /// Panics if the event stream was already taken.
1429    pub fn take_event_stream(&self) -> ControllerEventStream {
1430        ControllerEventStream { event_receiver: self.client.take_event_receiver() }
1431    }
1432
1433    /// Applies operational and electrical constraints to the charger converter.
1434    ///
1435    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
1436    /// hardware and session state untouched. The response is returned only after all corresponding
1437    /// hardware register writes have completed and been acknowledged by the charger IC.
1438    ///
1439    /// Parameters:
1440    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
1441    ///   set on this connection for those fields; omitted fields leave this connection's prior
1442    ///   constraints for those fields unchanged.
1443    ///
1444    /// Errors:
1445    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
1446    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
1447    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
1448    ///   requested `operating_mode` conflicts with the active power path state (for example,
1449    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
1450    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
1451    /// - `INTERNAL`: Internal driver error.
1452    pub fn r#set_control(
1453        &self,
1454        mut options: &ControlOptions,
1455    ) -> fidl::client::QueryResponseFut<
1456        ControllerSetControlResult,
1457        fidl::encoding::DefaultFuchsiaResourceDialect,
1458    > {
1459        ControllerProxyInterface::r#set_control(self, options)
1460    }
1461
1462    /// Withdraws constraints applied through this connection for the fields present in `options`.
1463    ///
1464    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
1465    /// field values themselves are ignored.
1466    ///
1467    /// - If `options` is empty (no fields set), **all** constraints applied through this
1468    ///   connection are withdrawn.
1469    /// - If one or more fields are set in `options`, only the constraints corresponding to those
1470    ///   fields are withdrawn, leaving any other fields untouched.
1471    ///
1472    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
1473    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
1474    /// Succeeds without effect for any targeted field that is not currently constrained.
1475    ///
1476    /// Parameters:
1477    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
1478    ///   empty table to withdraw all constraints on this connection.
1479    ///
1480    /// Errors:
1481    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
1482    ///   retain their constraint, so the call can be retried.
1483    /// - `INTERNAL`: Internal driver error.
1484    pub fn r#clear_control(
1485        &self,
1486        mut options: &ControlOptions,
1487    ) -> fidl::client::QueryResponseFut<
1488        ControllerClearControlResult,
1489        fidl::encoding::DefaultFuchsiaResourceDialect,
1490    > {
1491        ControllerProxyInterface::r#clear_control(self, options)
1492    }
1493}
1494
1495impl ControllerProxyInterface for ControllerProxy {
1496    type SetControlResponseFut = fidl::client::QueryResponseFut<
1497        ControllerSetControlResult,
1498        fidl::encoding::DefaultFuchsiaResourceDialect,
1499    >;
1500    fn r#set_control(&self, mut options: &ControlOptions) -> Self::SetControlResponseFut {
1501        fn _decode(
1502            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1503        ) -> Result<ControllerSetControlResult, fidl::Error> {
1504            let _response = fidl::client::decode_transaction_body::<
1505                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
1506                fidl::encoding::DefaultFuchsiaResourceDialect,
1507                0x363a64b0c8d45594,
1508            >(_buf?)?
1509            .into_result::<ControllerMarker>("set_control")?;
1510            Ok(_response.map(|x| x))
1511        }
1512        self.client
1513            .send_query_and_decode::<ControllerSetControlRequest, ControllerSetControlResult>(
1514                (options,),
1515                0x363a64b0c8d45594,
1516                fidl::encoding::DynamicFlags::FLEXIBLE,
1517                _decode,
1518            )
1519    }
1520
1521    type ClearControlResponseFut = fidl::client::QueryResponseFut<
1522        ControllerClearControlResult,
1523        fidl::encoding::DefaultFuchsiaResourceDialect,
1524    >;
1525    fn r#clear_control(&self, mut options: &ControlOptions) -> Self::ClearControlResponseFut {
1526        fn _decode(
1527            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1528        ) -> Result<ControllerClearControlResult, fidl::Error> {
1529            let _response = fidl::client::decode_transaction_body::<
1530                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
1531                fidl::encoding::DefaultFuchsiaResourceDialect,
1532                0x2b2a45d9fa0cd3c1,
1533            >(_buf?)?
1534            .into_result::<ControllerMarker>("clear_control")?;
1535            Ok(_response.map(|x| x))
1536        }
1537        self.client
1538            .send_query_and_decode::<ControllerClearControlRequest, ControllerClearControlResult>(
1539                (options,),
1540                0x2b2a45d9fa0cd3c1,
1541                fidl::encoding::DynamicFlags::FLEXIBLE,
1542                _decode,
1543            )
1544    }
1545}
1546
1547pub struct ControllerEventStream {
1548    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
1549}
1550
1551impl std::marker::Unpin for ControllerEventStream {}
1552
1553impl futures::stream::FusedStream for ControllerEventStream {
1554    fn is_terminated(&self) -> bool {
1555        self.event_receiver.is_terminated()
1556    }
1557}
1558
1559impl futures::Stream for ControllerEventStream {
1560    type Item = Result<ControllerEvent, fidl::Error>;
1561
1562    fn poll_next(
1563        mut self: std::pin::Pin<&mut Self>,
1564        cx: &mut std::task::Context<'_>,
1565    ) -> std::task::Poll<Option<Self::Item>> {
1566        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
1567            &mut self.event_receiver,
1568            cx
1569        )?) {
1570            Some(buf) => std::task::Poll::Ready(Some(ControllerEvent::decode(buf))),
1571            None => std::task::Poll::Ready(None),
1572        }
1573    }
1574}
1575
1576#[derive(Debug)]
1577pub enum ControllerEvent {
1578    #[non_exhaustive]
1579    _UnknownEvent {
1580        /// Ordinal of the event that was sent.
1581        ordinal: u64,
1582    },
1583}
1584
1585impl ControllerEvent {
1586    /// Decodes a message buffer as a [`ControllerEvent`].
1587    fn decode(
1588        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
1589    ) -> Result<ControllerEvent, fidl::Error> {
1590        let (bytes, _handles) = buf.split_mut();
1591        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1592        debug_assert_eq!(tx_header.tx_id, 0);
1593        match tx_header.ordinal {
1594            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
1595                Ok(ControllerEvent::_UnknownEvent { ordinal: tx_header.ordinal })
1596            }
1597            _ => Err(fidl::Error::UnknownOrdinal {
1598                ordinal: tx_header.ordinal,
1599                protocol_name: <ControllerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1600            }),
1601        }
1602    }
1603}
1604
1605/// A Stream of incoming requests for fuchsia.hardware.power.charger/Controller.
1606pub struct ControllerRequestStream {
1607    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1608    is_terminated: bool,
1609}
1610
1611impl std::marker::Unpin for ControllerRequestStream {}
1612
1613impl futures::stream::FusedStream for ControllerRequestStream {
1614    fn is_terminated(&self) -> bool {
1615        self.is_terminated
1616    }
1617}
1618
1619impl fidl::endpoints::RequestStream for ControllerRequestStream {
1620    type Protocol = ControllerMarker;
1621    type ControlHandle = ControllerControlHandle;
1622
1623    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
1624        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
1625    }
1626
1627    fn control_handle(&self) -> Self::ControlHandle {
1628        ControllerControlHandle { inner: self.inner.clone() }
1629    }
1630
1631    fn into_inner(
1632        self,
1633    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
1634    {
1635        (self.inner, self.is_terminated)
1636    }
1637
1638    fn from_inner(
1639        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1640        is_terminated: bool,
1641    ) -> Self {
1642        Self { inner, is_terminated }
1643    }
1644}
1645
1646impl futures::Stream for ControllerRequestStream {
1647    type Item = Result<ControllerRequest, fidl::Error>;
1648
1649    fn poll_next(
1650        mut self: std::pin::Pin<&mut Self>,
1651        cx: &mut std::task::Context<'_>,
1652    ) -> std::task::Poll<Option<Self::Item>> {
1653        let this = &mut *self;
1654        if this.inner.check_shutdown(cx) {
1655            this.is_terminated = true;
1656            return std::task::Poll::Ready(None);
1657        }
1658        if this.is_terminated {
1659            panic!("polled ControllerRequestStream after completion");
1660        }
1661        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
1662            |bytes, handles| {
1663                match this.inner.channel().read_etc(cx, bytes, handles) {
1664                    std::task::Poll::Ready(Ok(())) => {}
1665                    std::task::Poll::Pending => return std::task::Poll::Pending,
1666                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
1667                        this.is_terminated = true;
1668                        return std::task::Poll::Ready(None);
1669                    }
1670                    std::task::Poll::Ready(Err(e)) => {
1671                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
1672                            e.into(),
1673                        ))));
1674                    }
1675                }
1676
1677                // A message has been received from the channel
1678                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1679
1680                std::task::Poll::Ready(Some(match header.ordinal {
1681                    0x363a64b0c8d45594 => {
1682                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1683                        let mut req = fidl::new_empty!(
1684                            ControllerSetControlRequest,
1685                            fidl::encoding::DefaultFuchsiaResourceDialect
1686                        );
1687                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ControllerSetControlRequest>(&header, _body_bytes, handles, &mut req)?;
1688                        let control_handle = ControllerControlHandle { inner: this.inner.clone() };
1689                        Ok(ControllerRequest::SetControl {
1690                            options: req.options,
1691
1692                            responder: ControllerSetControlResponder {
1693                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1694                                tx_id: header.tx_id,
1695                            },
1696                        })
1697                    }
1698                    0x2b2a45d9fa0cd3c1 => {
1699                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1700                        let mut req = fidl::new_empty!(
1701                            ControllerClearControlRequest,
1702                            fidl::encoding::DefaultFuchsiaResourceDialect
1703                        );
1704                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ControllerClearControlRequest>(&header, _body_bytes, handles, &mut req)?;
1705                        let control_handle = ControllerControlHandle { inner: this.inner.clone() };
1706                        Ok(ControllerRequest::ClearControl {
1707                            options: req.options,
1708
1709                            responder: ControllerClearControlResponder {
1710                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1711                                tx_id: header.tx_id,
1712                            },
1713                        })
1714                    }
1715                    _ if header.tx_id == 0
1716                        && header
1717                            .dynamic_flags()
1718                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
1719                    {
1720                        Ok(ControllerRequest::_UnknownMethod {
1721                            ordinal: header.ordinal,
1722                            control_handle: ControllerControlHandle { inner: this.inner.clone() },
1723                            method_type: fidl::MethodType::OneWay,
1724                        })
1725                    }
1726                    _ if header
1727                        .dynamic_flags()
1728                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
1729                    {
1730                        this.inner.send_framework_err(
1731                            fidl::encoding::FrameworkErr::UnknownMethod,
1732                            header.tx_id,
1733                            header.ordinal,
1734                            header.dynamic_flags(),
1735                            (bytes, handles),
1736                        )?;
1737                        Ok(ControllerRequest::_UnknownMethod {
1738                            ordinal: header.ordinal,
1739                            control_handle: ControllerControlHandle { inner: this.inner.clone() },
1740                            method_type: fidl::MethodType::TwoWay,
1741                        })
1742                    }
1743                    _ => Err(fidl::Error::UnknownOrdinal {
1744                        ordinal: header.ordinal,
1745                        protocol_name:
1746                            <ControllerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1747                    }),
1748                }))
1749            },
1750        )
1751    }
1752}
1753
1754/// Control interface for mutating charger hardware state.
1755///
1756/// # Single-Client Exclusivity (Hardware Driver) vs. Policy Arbitrator
1757/// On a hardware charger driver, this protocol mutates shared hardware state and admits a single
1758/// active client: while one client is connected, a second connection attempt is closed immediately
1759/// with a `ZX_ERR_ALREADY_BOUND` epitaph before any request is served. When served by a userspace
1760/// policy arbitrator (such as `battery-manager`), multiple policy clients may connect concurrently;
1761/// each connection owns an independent vote that is aggregated using minimum selection on limit
1762/// fields and `Discharging > Passthrough > Charging` precedence on `operating_mode`.
1763///
1764/// # Connection-Scoped Lifetime (Revert on Close)
1765/// The `Controller` channel encodes the lifetime of the constraints applied through it. When the
1766/// client closes the channel (or disconnects unexpectedly), all constraints set during that
1767/// session are withdrawn (equivalent to calling `ClearControl` with an empty `ControlOptions`).
1768///
1769/// # Debug Overrides
1770/// Fields overridden through [`Debug`] take precedence over this protocol. A request that sets an
1771/// overridden field is validated and accepted as usual, but the new constraint (like `ClearControl`
1772/// or revert on close) reaches the hardware only once the override is cleared. See [`Debug`].
1773#[derive(Debug)]
1774pub enum ControllerRequest {
1775    /// Applies operational and electrical constraints to the charger converter.
1776    ///
1777    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
1778    /// hardware and session state untouched. The response is returned only after all corresponding
1779    /// hardware register writes have completed and been acknowledged by the charger IC.
1780    ///
1781    /// Parameters:
1782    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
1783    ///   set on this connection for those fields; omitted fields leave this connection's prior
1784    ///   constraints for those fields unchanged.
1785    ///
1786    /// Errors:
1787    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
1788    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
1789    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
1790    ///   requested `operating_mode` conflicts with the active power path state (for example,
1791    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
1792    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
1793    /// - `INTERNAL`: Internal driver error.
1794    SetControl { options: ControlOptions, responder: ControllerSetControlResponder },
1795    /// Withdraws constraints applied through this connection for the fields present in `options`.
1796    ///
1797    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
1798    /// field values themselves are ignored.
1799    ///
1800    /// - If `options` is empty (no fields set), **all** constraints applied through this
1801    ///   connection are withdrawn.
1802    /// - If one or more fields are set in `options`, only the constraints corresponding to those
1803    ///   fields are withdrawn, leaving any other fields untouched.
1804    ///
1805    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
1806    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
1807    /// Succeeds without effect for any targeted field that is not currently constrained.
1808    ///
1809    /// Parameters:
1810    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
1811    ///   empty table to withdraw all constraints on this connection.
1812    ///
1813    /// Errors:
1814    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
1815    ///   retain their constraint, so the call can be retried.
1816    /// - `INTERNAL`: Internal driver error.
1817    ClearControl { options: ControlOptions, responder: ControllerClearControlResponder },
1818    /// An interaction was received which does not match any known method.
1819    #[non_exhaustive]
1820    _UnknownMethod {
1821        /// Ordinal of the method that was called.
1822        ordinal: u64,
1823        control_handle: ControllerControlHandle,
1824        method_type: fidl::MethodType,
1825    },
1826}
1827
1828impl ControllerRequest {
1829    #[allow(irrefutable_let_patterns)]
1830    pub fn into_set_control(self) -> Option<(ControlOptions, ControllerSetControlResponder)> {
1831        if let ControllerRequest::SetControl { options, responder } = self {
1832            Some((options, responder))
1833        } else {
1834            None
1835        }
1836    }
1837
1838    #[allow(irrefutable_let_patterns)]
1839    pub fn into_clear_control(self) -> Option<(ControlOptions, ControllerClearControlResponder)> {
1840        if let ControllerRequest::ClearControl { options, responder } = self {
1841            Some((options, responder))
1842        } else {
1843            None
1844        }
1845    }
1846
1847    /// Name of the method defined in FIDL
1848    pub fn method_name(&self) -> &'static str {
1849        match *self {
1850            ControllerRequest::SetControl { .. } => "set_control",
1851            ControllerRequest::ClearControl { .. } => "clear_control",
1852            ControllerRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
1853                "unknown one-way method"
1854            }
1855            ControllerRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
1856                "unknown two-way method"
1857            }
1858        }
1859    }
1860}
1861
1862#[derive(Debug, Clone)]
1863pub struct ControllerControlHandle {
1864    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1865}
1866
1867impl ControllerControlHandle {
1868    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
1869        self.inner.shutdown_with_epitaph(status.into())
1870    }
1871}
1872
1873impl fidl::endpoints::ControlHandle for ControllerControlHandle {
1874    fn shutdown(&self) {
1875        self.inner.shutdown()
1876    }
1877
1878    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
1879        self.inner.shutdown_with_epitaph(status)
1880    }
1881
1882    fn is_closed(&self) -> bool {
1883        self.inner.channel().is_closed()
1884    }
1885    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1886        self.inner.channel().on_closed()
1887    }
1888
1889    #[cfg(target_os = "fuchsia")]
1890    fn signal_peer(
1891        &self,
1892        clear_mask: zx::Signals,
1893        set_mask: zx::Signals,
1894    ) -> Result<(), zx_status::Status> {
1895        use fidl::Peered;
1896        self.inner.channel().signal_peer(clear_mask, set_mask)
1897    }
1898}
1899
1900impl ControllerControlHandle {}
1901
1902#[must_use = "FIDL methods require a response to be sent"]
1903#[derive(Debug)]
1904pub struct ControllerSetControlResponder {
1905    control_handle: std::mem::ManuallyDrop<ControllerControlHandle>,
1906    tx_id: u32,
1907}
1908
1909/// Set the the channel to be shutdown (see [`ControllerControlHandle::shutdown`])
1910/// if the responder is dropped without sending a response, so that the client
1911/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1912impl std::ops::Drop for ControllerSetControlResponder {
1913    fn drop(&mut self) {
1914        self.control_handle.shutdown();
1915        // Safety: drops once, never accessed again
1916        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1917    }
1918}
1919
1920impl fidl::endpoints::Responder for ControllerSetControlResponder {
1921    type ControlHandle = ControllerControlHandle;
1922
1923    fn control_handle(&self) -> &ControllerControlHandle {
1924        &self.control_handle
1925    }
1926
1927    fn drop_without_shutdown(mut self) {
1928        // Safety: drops once, never accessed again due to mem::forget
1929        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1930        // Prevent Drop from running (which would shut down the channel)
1931        std::mem::forget(self);
1932    }
1933}
1934
1935impl ControllerSetControlResponder {
1936    /// Sends a response to the FIDL transaction.
1937    ///
1938    /// Sets the channel to shutdown if an error occurs.
1939    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1940        let _result = self.send_raw(result);
1941        if _result.is_err() {
1942            self.control_handle.shutdown();
1943        }
1944        self.drop_without_shutdown();
1945        _result
1946    }
1947
1948    /// Similar to "send" but does not shutdown the channel if an error occurs.
1949    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1950        let _result = self.send_raw(result);
1951        self.drop_without_shutdown();
1952        _result
1953    }
1954
1955    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1956        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1957            fidl::encoding::EmptyStruct,
1958            Error,
1959        >>(
1960            fidl::encoding::FlexibleResult::new(result),
1961            self.tx_id,
1962            0x363a64b0c8d45594,
1963            fidl::encoding::DynamicFlags::FLEXIBLE,
1964        )
1965    }
1966}
1967
1968#[must_use = "FIDL methods require a response to be sent"]
1969#[derive(Debug)]
1970pub struct ControllerClearControlResponder {
1971    control_handle: std::mem::ManuallyDrop<ControllerControlHandle>,
1972    tx_id: u32,
1973}
1974
1975/// Set the the channel to be shutdown (see [`ControllerControlHandle::shutdown`])
1976/// if the responder is dropped without sending a response, so that the client
1977/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1978impl std::ops::Drop for ControllerClearControlResponder {
1979    fn drop(&mut self) {
1980        self.control_handle.shutdown();
1981        // Safety: drops once, never accessed again
1982        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1983    }
1984}
1985
1986impl fidl::endpoints::Responder for ControllerClearControlResponder {
1987    type ControlHandle = ControllerControlHandle;
1988
1989    fn control_handle(&self) -> &ControllerControlHandle {
1990        &self.control_handle
1991    }
1992
1993    fn drop_without_shutdown(mut self) {
1994        // Safety: drops once, never accessed again due to mem::forget
1995        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1996        // Prevent Drop from running (which would shut down the channel)
1997        std::mem::forget(self);
1998    }
1999}
2000
2001impl ControllerClearControlResponder {
2002    /// Sends a response to the FIDL transaction.
2003    ///
2004    /// Sets the channel to shutdown if an error occurs.
2005    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2006        let _result = self.send_raw(result);
2007        if _result.is_err() {
2008            self.control_handle.shutdown();
2009        }
2010        self.drop_without_shutdown();
2011        _result
2012    }
2013
2014    /// Similar to "send" but does not shutdown the channel if an error occurs.
2015    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2016        let _result = self.send_raw(result);
2017        self.drop_without_shutdown();
2018        _result
2019    }
2020
2021    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2022        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
2023            fidl::encoding::EmptyStruct,
2024            Error,
2025        >>(
2026            fidl::encoding::FlexibleResult::new(result),
2027            self.tx_id,
2028            0x2b2a45d9fa0cd3c1,
2029            fidl::encoding::DynamicFlags::FLEXIBLE,
2030        )
2031    }
2032}
2033
2034#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2035pub struct DebugMarker;
2036
2037impl fidl::endpoints::ProtocolMarker for DebugMarker {
2038    type Proxy = DebugProxy;
2039    type RequestStream = DebugRequestStream;
2040    #[cfg(target_os = "fuchsia")]
2041    type SynchronousProxy = DebugSynchronousProxy;
2042
2043    const DEBUG_NAME: &'static str = "(anonymous) Debug";
2044}
2045
2046pub trait DebugProxyInterface: Send + Sync {
2047    type SetControlResponseFut: std::future::Future<Output = Result<ControllerSetControlResult, fidl::Error>>
2048        + Send;
2049    fn r#set_control(&self, options: &ControlOptions) -> Self::SetControlResponseFut;
2050    type ClearControlResponseFut: std::future::Future<Output = Result<ControllerClearControlResult, fidl::Error>>
2051        + Send;
2052    fn r#clear_control(&self, options: &ControlOptions) -> Self::ClearControlResponseFut;
2053}
2054#[derive(Debug)]
2055#[cfg(target_os = "fuchsia")]
2056pub struct DebugSynchronousProxy {
2057    client: fidl::client::sync::Client,
2058}
2059
2060#[cfg(target_os = "fuchsia")]
2061impl fidl::endpoints::SynchronousProxy for DebugSynchronousProxy {
2062    type Proxy = DebugProxy;
2063    type Protocol = DebugMarker;
2064
2065    fn from_channel(inner: fidl::Channel) -> Self {
2066        Self::new(inner)
2067    }
2068
2069    fn into_channel(self) -> fidl::Channel {
2070        self.client.into_channel()
2071    }
2072
2073    fn as_channel(&self) -> &fidl::Channel {
2074        self.client.as_channel()
2075    }
2076}
2077
2078#[cfg(target_os = "fuchsia")]
2079impl DebugSynchronousProxy {
2080    pub fn new(channel: fidl::Channel) -> Self {
2081        Self { client: fidl::client::sync::Client::new(channel) }
2082    }
2083
2084    pub fn into_channel(self) -> fidl::Channel {
2085        self.client.into_channel()
2086    }
2087
2088    /// Waits until an event arrives and returns it. It is safe for other
2089    /// threads to make concurrent requests while waiting for an event.
2090    pub fn wait_for_event(
2091        &self,
2092        deadline: zx::MonotonicInstant,
2093    ) -> Result<DebugEvent, fidl::Error> {
2094        DebugEvent::decode(self.client.wait_for_event::<DebugMarker>(deadline)?)
2095    }
2096
2097    /// Applies operational and electrical constraints to the charger converter.
2098    ///
2099    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
2100    /// hardware and session state untouched. The response is returned only after all corresponding
2101    /// hardware register writes have completed and been acknowledged by the charger IC.
2102    ///
2103    /// Parameters:
2104    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
2105    ///   set on this connection for those fields; omitted fields leave this connection's prior
2106    ///   constraints for those fields unchanged.
2107    ///
2108    /// Errors:
2109    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
2110    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
2111    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
2112    ///   requested `operating_mode` conflicts with the active power path state (for example,
2113    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
2114    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
2115    /// - `INTERNAL`: Internal driver error.
2116    pub fn r#set_control(
2117        &self,
2118        mut options: &ControlOptions,
2119        ___deadline: zx::MonotonicInstant,
2120    ) -> Result<ControllerSetControlResult, fidl::Error> {
2121        let _response = self.client.send_query::<
2122            ControllerSetControlRequest,
2123            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2124            DebugMarker,
2125        >(
2126            (options,),
2127            0x363a64b0c8d45594,
2128            fidl::encoding::DynamicFlags::FLEXIBLE,
2129            ___deadline,
2130        )?
2131        .into_result::<DebugMarker>("set_control")?;
2132        Ok(_response.map(|x| x))
2133    }
2134
2135    /// Withdraws constraints applied through this connection for the fields present in `options`.
2136    ///
2137    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
2138    /// field values themselves are ignored.
2139    ///
2140    /// - If `options` is empty (no fields set), **all** constraints applied through this
2141    ///   connection are withdrawn.
2142    /// - If one or more fields are set in `options`, only the constraints corresponding to those
2143    ///   fields are withdrawn, leaving any other fields untouched.
2144    ///
2145    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
2146    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
2147    /// Succeeds without effect for any targeted field that is not currently constrained.
2148    ///
2149    /// Parameters:
2150    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
2151    ///   empty table to withdraw all constraints on this connection.
2152    ///
2153    /// Errors:
2154    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
2155    ///   retain their constraint, so the call can be retried.
2156    /// - `INTERNAL`: Internal driver error.
2157    pub fn r#clear_control(
2158        &self,
2159        mut options: &ControlOptions,
2160        ___deadline: zx::MonotonicInstant,
2161    ) -> Result<ControllerClearControlResult, fidl::Error> {
2162        let _response = self.client.send_query::<
2163            ControllerClearControlRequest,
2164            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2165            DebugMarker,
2166        >(
2167            (options,),
2168            0x2b2a45d9fa0cd3c1,
2169            fidl::encoding::DynamicFlags::FLEXIBLE,
2170            ___deadline,
2171        )?
2172        .into_result::<DebugMarker>("clear_control")?;
2173        Ok(_response.map(|x| x))
2174    }
2175}
2176
2177#[cfg(target_os = "fuchsia")]
2178impl From<DebugSynchronousProxy> for zx::NullableHandle {
2179    fn from(value: DebugSynchronousProxy) -> Self {
2180        value.into_channel().into()
2181    }
2182}
2183
2184#[cfg(target_os = "fuchsia")]
2185impl From<fidl::Channel> for DebugSynchronousProxy {
2186    fn from(value: fidl::Channel) -> Self {
2187        Self::new(value)
2188    }
2189}
2190
2191#[cfg(target_os = "fuchsia")]
2192impl fidl::endpoints::FromClient for DebugSynchronousProxy {
2193    type Protocol = DebugMarker;
2194
2195    fn from_client(value: fidl::endpoints::ClientEnd<DebugMarker>) -> Self {
2196        Self::new(value.into_channel())
2197    }
2198}
2199
2200#[derive(Debug, Clone)]
2201pub struct DebugProxy {
2202    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
2203}
2204
2205impl fidl::endpoints::Proxy for DebugProxy {
2206    type Protocol = DebugMarker;
2207
2208    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
2209        Self::new(inner)
2210    }
2211
2212    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
2213        self.client.into_channel().map_err(|client| Self { client })
2214    }
2215
2216    fn as_channel(&self) -> &::fidl::AsyncChannel {
2217        self.client.as_channel()
2218    }
2219}
2220
2221impl DebugProxy {
2222    /// Create a new Proxy for fuchsia.hardware.power.charger/Debug.
2223    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
2224        let protocol_name = <DebugMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
2225        Self { client: fidl::client::Client::new(channel, protocol_name) }
2226    }
2227
2228    /// Get a Stream of events from the remote end of the protocol.
2229    ///
2230    /// # Panics
2231    ///
2232    /// Panics if the event stream was already taken.
2233    pub fn take_event_stream(&self) -> DebugEventStream {
2234        DebugEventStream { event_receiver: self.client.take_event_receiver() }
2235    }
2236
2237    /// Applies operational and electrical constraints to the charger converter.
2238    ///
2239    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
2240    /// hardware and session state untouched. The response is returned only after all corresponding
2241    /// hardware register writes have completed and been acknowledged by the charger IC.
2242    ///
2243    /// Parameters:
2244    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
2245    ///   set on this connection for those fields; omitted fields leave this connection's prior
2246    ///   constraints for those fields unchanged.
2247    ///
2248    /// Errors:
2249    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
2250    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
2251    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
2252    ///   requested `operating_mode` conflicts with the active power path state (for example,
2253    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
2254    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
2255    /// - `INTERNAL`: Internal driver error.
2256    pub fn r#set_control(
2257        &self,
2258        mut options: &ControlOptions,
2259    ) -> fidl::client::QueryResponseFut<
2260        ControllerSetControlResult,
2261        fidl::encoding::DefaultFuchsiaResourceDialect,
2262    > {
2263        DebugProxyInterface::r#set_control(self, options)
2264    }
2265
2266    /// Withdraws constraints applied through this connection for the fields present in `options`.
2267    ///
2268    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
2269    /// field values themselves are ignored.
2270    ///
2271    /// - If `options` is empty (no fields set), **all** constraints applied through this
2272    ///   connection are withdrawn.
2273    /// - If one or more fields are set in `options`, only the constraints corresponding to those
2274    ///   fields are withdrawn, leaving any other fields untouched.
2275    ///
2276    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
2277    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
2278    /// Succeeds without effect for any targeted field that is not currently constrained.
2279    ///
2280    /// Parameters:
2281    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
2282    ///   empty table to withdraw all constraints on this connection.
2283    ///
2284    /// Errors:
2285    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
2286    ///   retain their constraint, so the call can be retried.
2287    /// - `INTERNAL`: Internal driver error.
2288    pub fn r#clear_control(
2289        &self,
2290        mut options: &ControlOptions,
2291    ) -> fidl::client::QueryResponseFut<
2292        ControllerClearControlResult,
2293        fidl::encoding::DefaultFuchsiaResourceDialect,
2294    > {
2295        DebugProxyInterface::r#clear_control(self, options)
2296    }
2297}
2298
2299impl DebugProxyInterface for DebugProxy {
2300    type SetControlResponseFut = fidl::client::QueryResponseFut<
2301        ControllerSetControlResult,
2302        fidl::encoding::DefaultFuchsiaResourceDialect,
2303    >;
2304    fn r#set_control(&self, mut options: &ControlOptions) -> Self::SetControlResponseFut {
2305        fn _decode(
2306            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2307        ) -> Result<ControllerSetControlResult, fidl::Error> {
2308            let _response = fidl::client::decode_transaction_body::<
2309                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2310                fidl::encoding::DefaultFuchsiaResourceDialect,
2311                0x363a64b0c8d45594,
2312            >(_buf?)?
2313            .into_result::<DebugMarker>("set_control")?;
2314            Ok(_response.map(|x| x))
2315        }
2316        self.client
2317            .send_query_and_decode::<ControllerSetControlRequest, ControllerSetControlResult>(
2318                (options,),
2319                0x363a64b0c8d45594,
2320                fidl::encoding::DynamicFlags::FLEXIBLE,
2321                _decode,
2322            )
2323    }
2324
2325    type ClearControlResponseFut = fidl::client::QueryResponseFut<
2326        ControllerClearControlResult,
2327        fidl::encoding::DefaultFuchsiaResourceDialect,
2328    >;
2329    fn r#clear_control(&self, mut options: &ControlOptions) -> Self::ClearControlResponseFut {
2330        fn _decode(
2331            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
2332        ) -> Result<ControllerClearControlResult, fidl::Error> {
2333            let _response = fidl::client::decode_transaction_body::<
2334                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, Error>,
2335                fidl::encoding::DefaultFuchsiaResourceDialect,
2336                0x2b2a45d9fa0cd3c1,
2337            >(_buf?)?
2338            .into_result::<DebugMarker>("clear_control")?;
2339            Ok(_response.map(|x| x))
2340        }
2341        self.client
2342            .send_query_and_decode::<ControllerClearControlRequest, ControllerClearControlResult>(
2343                (options,),
2344                0x2b2a45d9fa0cd3c1,
2345                fidl::encoding::DynamicFlags::FLEXIBLE,
2346                _decode,
2347            )
2348    }
2349}
2350
2351pub struct DebugEventStream {
2352    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
2353}
2354
2355impl std::marker::Unpin for DebugEventStream {}
2356
2357impl futures::stream::FusedStream for DebugEventStream {
2358    fn is_terminated(&self) -> bool {
2359        self.event_receiver.is_terminated()
2360    }
2361}
2362
2363impl futures::Stream for DebugEventStream {
2364    type Item = Result<DebugEvent, fidl::Error>;
2365
2366    fn poll_next(
2367        mut self: std::pin::Pin<&mut Self>,
2368        cx: &mut std::task::Context<'_>,
2369    ) -> std::task::Poll<Option<Self::Item>> {
2370        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
2371            &mut self.event_receiver,
2372            cx
2373        )?) {
2374            Some(buf) => std::task::Poll::Ready(Some(DebugEvent::decode(buf))),
2375            None => std::task::Poll::Ready(None),
2376        }
2377    }
2378}
2379
2380#[derive(Debug)]
2381pub enum DebugEvent {
2382    #[non_exhaustive]
2383    _UnknownEvent {
2384        /// Ordinal of the event that was sent.
2385        ordinal: u64,
2386    },
2387}
2388
2389impl DebugEvent {
2390    /// Decodes a message buffer as a [`DebugEvent`].
2391    fn decode(
2392        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
2393    ) -> Result<DebugEvent, fidl::Error> {
2394        let (bytes, _handles) = buf.split_mut();
2395        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2396        debug_assert_eq!(tx_header.tx_id, 0);
2397        match tx_header.ordinal {
2398            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
2399                Ok(DebugEvent::_UnknownEvent { ordinal: tx_header.ordinal })
2400            }
2401            _ => Err(fidl::Error::UnknownOrdinal {
2402                ordinal: tx_header.ordinal,
2403                protocol_name: <DebugMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2404            }),
2405        }
2406    }
2407}
2408
2409/// A Stream of incoming requests for fuchsia.hardware.power.charger/Debug.
2410pub struct DebugRequestStream {
2411    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2412    is_terminated: bool,
2413}
2414
2415impl std::marker::Unpin for DebugRequestStream {}
2416
2417impl futures::stream::FusedStream for DebugRequestStream {
2418    fn is_terminated(&self) -> bool {
2419        self.is_terminated
2420    }
2421}
2422
2423impl fidl::endpoints::RequestStream for DebugRequestStream {
2424    type Protocol = DebugMarker;
2425    type ControlHandle = DebugControlHandle;
2426
2427    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
2428        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
2429    }
2430
2431    fn control_handle(&self) -> Self::ControlHandle {
2432        DebugControlHandle { inner: self.inner.clone() }
2433    }
2434
2435    fn into_inner(
2436        self,
2437    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
2438    {
2439        (self.inner, self.is_terminated)
2440    }
2441
2442    fn from_inner(
2443        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2444        is_terminated: bool,
2445    ) -> Self {
2446        Self { inner, is_terminated }
2447    }
2448}
2449
2450impl futures::Stream for DebugRequestStream {
2451    type Item = Result<DebugRequest, fidl::Error>;
2452
2453    fn poll_next(
2454        mut self: std::pin::Pin<&mut Self>,
2455        cx: &mut std::task::Context<'_>,
2456    ) -> std::task::Poll<Option<Self::Item>> {
2457        let this = &mut *self;
2458        if this.inner.check_shutdown(cx) {
2459            this.is_terminated = true;
2460            return std::task::Poll::Ready(None);
2461        }
2462        if this.is_terminated {
2463            panic!("polled DebugRequestStream after completion");
2464        }
2465        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
2466            |bytes, handles| {
2467                match this.inner.channel().read_etc(cx, bytes, handles) {
2468                    std::task::Poll::Ready(Ok(())) => {}
2469                    std::task::Poll::Pending => return std::task::Poll::Pending,
2470                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
2471                        this.is_terminated = true;
2472                        return std::task::Poll::Ready(None);
2473                    }
2474                    std::task::Poll::Ready(Err(e)) => {
2475                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
2476                            e.into(),
2477                        ))));
2478                    }
2479                }
2480
2481                // A message has been received from the channel
2482                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
2483
2484                std::task::Poll::Ready(Some(match header.ordinal {
2485                    0x363a64b0c8d45594 => {
2486                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2487                        let mut req = fidl::new_empty!(
2488                            ControllerSetControlRequest,
2489                            fidl::encoding::DefaultFuchsiaResourceDialect
2490                        );
2491                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ControllerSetControlRequest>(&header, _body_bytes, handles, &mut req)?;
2492                        let control_handle = DebugControlHandle { inner: this.inner.clone() };
2493                        Ok(DebugRequest::SetControl {
2494                            options: req.options,
2495
2496                            responder: DebugSetControlResponder {
2497                                control_handle: std::mem::ManuallyDrop::new(control_handle),
2498                                tx_id: header.tx_id,
2499                            },
2500                        })
2501                    }
2502                    0x2b2a45d9fa0cd3c1 => {
2503                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
2504                        let mut req = fidl::new_empty!(
2505                            ControllerClearControlRequest,
2506                            fidl::encoding::DefaultFuchsiaResourceDialect
2507                        );
2508                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ControllerClearControlRequest>(&header, _body_bytes, handles, &mut req)?;
2509                        let control_handle = DebugControlHandle { inner: this.inner.clone() };
2510                        Ok(DebugRequest::ClearControl {
2511                            options: req.options,
2512
2513                            responder: DebugClearControlResponder {
2514                                control_handle: std::mem::ManuallyDrop::new(control_handle),
2515                                tx_id: header.tx_id,
2516                            },
2517                        })
2518                    }
2519                    _ if header.tx_id == 0
2520                        && header
2521                            .dynamic_flags()
2522                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
2523                    {
2524                        Ok(DebugRequest::_UnknownMethod {
2525                            ordinal: header.ordinal,
2526                            control_handle: DebugControlHandle { inner: this.inner.clone() },
2527                            method_type: fidl::MethodType::OneWay,
2528                        })
2529                    }
2530                    _ if header
2531                        .dynamic_flags()
2532                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
2533                    {
2534                        this.inner.send_framework_err(
2535                            fidl::encoding::FrameworkErr::UnknownMethod,
2536                            header.tx_id,
2537                            header.ordinal,
2538                            header.dynamic_flags(),
2539                            (bytes, handles),
2540                        )?;
2541                        Ok(DebugRequest::_UnknownMethod {
2542                            ordinal: header.ordinal,
2543                            control_handle: DebugControlHandle { inner: this.inner.clone() },
2544                            method_type: fidl::MethodType::TwoWay,
2545                        })
2546                    }
2547                    _ => Err(fidl::Error::UnknownOrdinal {
2548                        ordinal: header.ordinal,
2549                        protocol_name: <DebugMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
2550                    }),
2551                }))
2552            },
2553        )
2554    }
2555}
2556
2557/// Debug control interface for hardware battery chargers.
2558///
2559/// Composes [`Controller`] without its single-client exclusivity or revert-on-close lifetime, so
2560/// command-line diagnostic utilities (such as `batteryutil`) and integration tests can apply sticky
2561/// charger overrides while the production policy client stays connected to [`Controller`]. Only
2562/// reachable through [`DebugService`].
2563///
2564/// # Override Precedence
2565/// Each field set through `SetControl` becomes an override that takes precedence over
2566/// [`Controller`] regardless of request order: a [`Controller`] request that sets an overridden
2567/// field is validated and accepted, but takes effect only once the override is cleared, and a
2568/// [`Controller`] revert on close leaves overridden fields untouched. Fields that are not
2569/// overridden stay under [`Controller`] control.
2570///
2571/// # Sticky Lifetime (No Revert on Close)
2572/// Overrides are not tied to the connection that applied them: closing the channel leaves them in
2573/// effect, so a utility can apply an override and exit. They remain in effect until
2574/// `ClearControl` is called on a `Debug` connection.
2575///
2576/// # Multiple Connections
2577/// Any number of `Debug` connections may be open concurrently; connections are never rejected with
2578/// `ZX_ERR_ALREADY_BOUND`. All `Debug` connections share one set of `Debug` overrides: for each
2579/// field, the most recent `SetControl` wins, and `ClearControl` withdraws the targeted `Debug`
2580/// overrides.
2581#[derive(Debug)]
2582pub enum DebugRequest {
2583    /// Applies operational and electrical constraints to the charger converter.
2584    ///
2585    /// Validation is atomic: a request rejected with `NOT_SUPPORTED` or `INVALID_ARGS` leaves
2586    /// hardware and session state untouched. The response is returned only after all corresponding
2587    /// hardware register writes have completed and been acknowledged by the charger IC.
2588    ///
2589    /// Parameters:
2590    /// + `options`: The constraints to apply. Present fields overwrite the constraints previously
2591    ///   set on this connection for those fields; omitted fields leave this connection's prior
2592    ///   constraints for those fields unchanged.
2593    ///
2594    /// Errors:
2595    /// - `NOT_SUPPORTED`: One or more requested constraints are not adjustable on this
2596    ///   hardware/arbiter, or the requested `operating_mode` is absent from `Spec.supported_modes`.
2597    /// - `INVALID_ARGS`: A requested value is outside the range the hardware can program, or the
2598    ///   requested `operating_mode` conflicts with the active power path state (for example,
2599    ///   requesting `OperatingMode::OTG` while external input power is online on the same port).
2600    /// - `IO`: Communication failure with the charger hardware (e.g. SPMI transfer failure).
2601    /// - `INTERNAL`: Internal driver error.
2602    SetControl { options: ControlOptions, responder: DebugSetControlResponder },
2603    /// Withdraws constraints applied through this connection for the fields present in `options`.
2604    ///
2605    /// `options` acts as a field mask: only field presence (set vs. unset) is inspected, and the
2606    /// field values themselves are ignored.
2607    ///
2608    /// - If `options` is empty (no fields set), **all** constraints applied through this
2609    ///   connection are withdrawn.
2610    /// - If one or more fields are set in `options`, only the constraints corresponding to those
2611    ///   fields are withdrawn, leaving any other fields untouched.
2612    ///
2613    /// Each cleared field reverts to the next active constraint, if any, or otherwise to the
2614    /// autonomous hardware / board-configured default that [`Controller`] restores on close.
2615    /// Succeeds without effect for any targeted field that is not currently constrained.
2616    ///
2617    /// Parameters:
2618    /// + `options`: Mask of `ControlOptions` fields whose constraints should be withdrawn, or an
2619    ///   empty table to withdraw all constraints on this connection.
2620    ///
2621    /// Errors:
2622    /// - `IO`: Communication failure with the charger hardware. Fields that could not be reverted
2623    ///   retain their constraint, so the call can be retried.
2624    /// - `INTERNAL`: Internal driver error.
2625    ClearControl { options: ControlOptions, responder: DebugClearControlResponder },
2626    /// An interaction was received which does not match any known method.
2627    #[non_exhaustive]
2628    _UnknownMethod {
2629        /// Ordinal of the method that was called.
2630        ordinal: u64,
2631        control_handle: DebugControlHandle,
2632        method_type: fidl::MethodType,
2633    },
2634}
2635
2636impl DebugRequest {
2637    #[allow(irrefutable_let_patterns)]
2638    pub fn into_set_control(self) -> Option<(ControlOptions, DebugSetControlResponder)> {
2639        if let DebugRequest::SetControl { options, responder } = self {
2640            Some((options, responder))
2641        } else {
2642            None
2643        }
2644    }
2645
2646    #[allow(irrefutable_let_patterns)]
2647    pub fn into_clear_control(self) -> Option<(ControlOptions, DebugClearControlResponder)> {
2648        if let DebugRequest::ClearControl { options, responder } = self {
2649            Some((options, responder))
2650        } else {
2651            None
2652        }
2653    }
2654
2655    /// Name of the method defined in FIDL
2656    pub fn method_name(&self) -> &'static str {
2657        match *self {
2658            DebugRequest::SetControl { .. } => "set_control",
2659            DebugRequest::ClearControl { .. } => "clear_control",
2660            DebugRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
2661                "unknown one-way method"
2662            }
2663            DebugRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
2664                "unknown two-way method"
2665            }
2666        }
2667    }
2668}
2669
2670#[derive(Debug, Clone)]
2671pub struct DebugControlHandle {
2672    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
2673}
2674
2675impl DebugControlHandle {
2676    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
2677        self.inner.shutdown_with_epitaph(status.into())
2678    }
2679}
2680
2681impl fidl::endpoints::ControlHandle for DebugControlHandle {
2682    fn shutdown(&self) {
2683        self.inner.shutdown()
2684    }
2685
2686    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
2687        self.inner.shutdown_with_epitaph(status)
2688    }
2689
2690    fn is_closed(&self) -> bool {
2691        self.inner.channel().is_closed()
2692    }
2693    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
2694        self.inner.channel().on_closed()
2695    }
2696
2697    #[cfg(target_os = "fuchsia")]
2698    fn signal_peer(
2699        &self,
2700        clear_mask: zx::Signals,
2701        set_mask: zx::Signals,
2702    ) -> Result<(), zx_status::Status> {
2703        use fidl::Peered;
2704        self.inner.channel().signal_peer(clear_mask, set_mask)
2705    }
2706}
2707
2708impl DebugControlHandle {}
2709
2710#[must_use = "FIDL methods require a response to be sent"]
2711#[derive(Debug)]
2712pub struct DebugSetControlResponder {
2713    control_handle: std::mem::ManuallyDrop<DebugControlHandle>,
2714    tx_id: u32,
2715}
2716
2717/// Set the the channel to be shutdown (see [`DebugControlHandle::shutdown`])
2718/// if the responder is dropped without sending a response, so that the client
2719/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
2720impl std::ops::Drop for DebugSetControlResponder {
2721    fn drop(&mut self) {
2722        self.control_handle.shutdown();
2723        // Safety: drops once, never accessed again
2724        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2725    }
2726}
2727
2728impl fidl::endpoints::Responder for DebugSetControlResponder {
2729    type ControlHandle = DebugControlHandle;
2730
2731    fn control_handle(&self) -> &DebugControlHandle {
2732        &self.control_handle
2733    }
2734
2735    fn drop_without_shutdown(mut self) {
2736        // Safety: drops once, never accessed again due to mem::forget
2737        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2738        // Prevent Drop from running (which would shut down the channel)
2739        std::mem::forget(self);
2740    }
2741}
2742
2743impl DebugSetControlResponder {
2744    /// Sends a response to the FIDL transaction.
2745    ///
2746    /// Sets the channel to shutdown if an error occurs.
2747    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2748        let _result = self.send_raw(result);
2749        if _result.is_err() {
2750            self.control_handle.shutdown();
2751        }
2752        self.drop_without_shutdown();
2753        _result
2754    }
2755
2756    /// Similar to "send" but does not shutdown the channel if an error occurs.
2757    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2758        let _result = self.send_raw(result);
2759        self.drop_without_shutdown();
2760        _result
2761    }
2762
2763    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2764        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
2765            fidl::encoding::EmptyStruct,
2766            Error,
2767        >>(
2768            fidl::encoding::FlexibleResult::new(result),
2769            self.tx_id,
2770            0x363a64b0c8d45594,
2771            fidl::encoding::DynamicFlags::FLEXIBLE,
2772        )
2773    }
2774}
2775
2776#[must_use = "FIDL methods require a response to be sent"]
2777#[derive(Debug)]
2778pub struct DebugClearControlResponder {
2779    control_handle: std::mem::ManuallyDrop<DebugControlHandle>,
2780    tx_id: u32,
2781}
2782
2783/// Set the the channel to be shutdown (see [`DebugControlHandle::shutdown`])
2784/// if the responder is dropped without sending a response, so that the client
2785/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
2786impl std::ops::Drop for DebugClearControlResponder {
2787    fn drop(&mut self) {
2788        self.control_handle.shutdown();
2789        // Safety: drops once, never accessed again
2790        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2791    }
2792}
2793
2794impl fidl::endpoints::Responder for DebugClearControlResponder {
2795    type ControlHandle = DebugControlHandle;
2796
2797    fn control_handle(&self) -> &DebugControlHandle {
2798        &self.control_handle
2799    }
2800
2801    fn drop_without_shutdown(mut self) {
2802        // Safety: drops once, never accessed again due to mem::forget
2803        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
2804        // Prevent Drop from running (which would shut down the channel)
2805        std::mem::forget(self);
2806    }
2807}
2808
2809impl DebugClearControlResponder {
2810    /// Sends a response to the FIDL transaction.
2811    ///
2812    /// Sets the channel to shutdown if an error occurs.
2813    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2814        let _result = self.send_raw(result);
2815        if _result.is_err() {
2816            self.control_handle.shutdown();
2817        }
2818        self.drop_without_shutdown();
2819        _result
2820    }
2821
2822    /// Similar to "send" but does not shutdown the channel if an error occurs.
2823    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2824        let _result = self.send_raw(result);
2825        self.drop_without_shutdown();
2826        _result
2827    }
2828
2829    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
2830        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
2831            fidl::encoding::EmptyStruct,
2832            Error,
2833        >>(
2834            fidl::encoding::FlexibleResult::new(result),
2835            self.tx_id,
2836            0x2b2a45d9fa0cd3c1,
2837            fidl::encoding::DynamicFlags::FLEXIBLE,
2838        )
2839    }
2840}
2841
2842#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2843pub struct DebugServiceMarker;
2844
2845#[cfg(target_os = "fuchsia")]
2846impl fidl::endpoints::ServiceMarker for DebugServiceMarker {
2847    type Proxy = DebugServiceProxy;
2848    type Request = DebugServiceRequest;
2849    const SERVICE_NAME: &'static str = "fuchsia.hardware.power.charger.DebugService";
2850}
2851
2852/// A request for one of the member protocols of DebugService.
2853///
2854/// Debug service for command-line utilities and engineering/bringup consoles.
2855///
2856/// Restricted via component capability routing and product assembly; not exposed to production
2857/// drivers or system daemons, which use [`Service`] instead.
2858#[cfg(target_os = "fuchsia")]
2859pub enum DebugServiceRequest {
2860    Debug(DebugRequestStream),
2861}
2862
2863#[cfg(target_os = "fuchsia")]
2864impl fidl::endpoints::ServiceRequest for DebugServiceRequest {
2865    type Service = DebugServiceMarker;
2866
2867    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
2868        match name {
2869            "debug" => Self::Debug(
2870                <DebugRequestStream as fidl::endpoints::RequestStream>::from_channel(_channel),
2871            ),
2872            _ => panic!("no such member protocol name for service DebugService"),
2873        }
2874    }
2875
2876    fn member_names() -> &'static [&'static str] {
2877        &["debug"]
2878    }
2879}
2880/// Debug service for command-line utilities and engineering/bringup consoles.
2881///
2882/// Restricted via component capability routing and product assembly; not exposed to production
2883/// drivers or system daemons, which use [`Service`] instead.
2884#[cfg(target_os = "fuchsia")]
2885pub struct DebugServiceProxy(#[allow(dead_code)] Box<dyn fidl::endpoints::MemberOpener>);
2886
2887#[cfg(target_os = "fuchsia")]
2888impl fidl::endpoints::ServiceProxy for DebugServiceProxy {
2889    type Service = DebugServiceMarker;
2890
2891    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
2892        Self(opener)
2893    }
2894}
2895
2896#[cfg(target_os = "fuchsia")]
2897impl DebugServiceProxy {
2898    pub fn connect_to_debug(&self) -> Result<DebugProxy, fidl::Error> {
2899        let (proxy, server_end) = fidl::endpoints::create_proxy::<DebugMarker>();
2900        self.connect_channel_to_debug(server_end)?;
2901        Ok(proxy)
2902    }
2903
2904    /// Like `connect_to_debug`, but returns a sync proxy.
2905    /// See [`Self::connect_to_debug`] for more details.
2906    pub fn connect_to_debug_sync(&self) -> Result<DebugSynchronousProxy, fidl::Error> {
2907        let (proxy, server_end) = fidl::endpoints::create_sync_proxy::<DebugMarker>();
2908        self.connect_channel_to_debug(server_end)?;
2909        Ok(proxy)
2910    }
2911
2912    /// Like `connect_to_debug`, but accepts a server end.
2913    /// See [`Self::connect_to_debug`] for more details.
2914    pub fn connect_channel_to_debug(
2915        &self,
2916        server_end: fidl::endpoints::ServerEnd<DebugMarker>,
2917    ) -> Result<(), fidl::Error> {
2918        self.0.open_member("debug", server_end.into_channel())
2919    }
2920
2921    pub fn instance_name(&self) -> &str {
2922        self.0.instance_name()
2923    }
2924}
2925
2926#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2927pub struct ServiceMarker;
2928
2929#[cfg(target_os = "fuchsia")]
2930impl fidl::endpoints::ServiceMarker for ServiceMarker {
2931    type Proxy = ServiceProxy;
2932    type Request = ServiceRequest;
2933    const SERVICE_NAME: &'static str = "fuchsia.hardware.power.charger.Service";
2934}
2935
2936/// A request for one of the member protocols of Service.
2937///
2938#[cfg(target_os = "fuchsia")]
2939pub enum ServiceRequest {
2940    Charger(ChargerRequestStream),
2941    Controller(ControllerRequestStream),
2942}
2943
2944#[cfg(target_os = "fuchsia")]
2945impl fidl::endpoints::ServiceRequest for ServiceRequest {
2946    type Service = ServiceMarker;
2947
2948    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
2949        match name {
2950            "charger" => Self::Charger(
2951                <ChargerRequestStream as fidl::endpoints::RequestStream>::from_channel(_channel),
2952            ),
2953            "controller" => Self::Controller(
2954                <ControllerRequestStream as fidl::endpoints::RequestStream>::from_channel(_channel),
2955            ),
2956            _ => panic!("no such member protocol name for service Service"),
2957        }
2958    }
2959
2960    fn member_names() -> &'static [&'static str] {
2961        &["charger", "controller"]
2962    }
2963}
2964#[cfg(target_os = "fuchsia")]
2965pub struct ServiceProxy(#[allow(dead_code)] Box<dyn fidl::endpoints::MemberOpener>);
2966
2967#[cfg(target_os = "fuchsia")]
2968impl fidl::endpoints::ServiceProxy for ServiceProxy {
2969    type Service = ServiceMarker;
2970
2971    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
2972        Self(opener)
2973    }
2974}
2975
2976#[cfg(target_os = "fuchsia")]
2977impl ServiceProxy {
2978    pub fn connect_to_charger(&self) -> Result<ChargerProxy, fidl::Error> {
2979        let (proxy, server_end) = fidl::endpoints::create_proxy::<ChargerMarker>();
2980        self.connect_channel_to_charger(server_end)?;
2981        Ok(proxy)
2982    }
2983
2984    /// Like `connect_to_charger`, but returns a sync proxy.
2985    /// See [`Self::connect_to_charger`] for more details.
2986    pub fn connect_to_charger_sync(&self) -> Result<ChargerSynchronousProxy, fidl::Error> {
2987        let (proxy, server_end) = fidl::endpoints::create_sync_proxy::<ChargerMarker>();
2988        self.connect_channel_to_charger(server_end)?;
2989        Ok(proxy)
2990    }
2991
2992    /// Like `connect_to_charger`, but accepts a server end.
2993    /// See [`Self::connect_to_charger`] for more details.
2994    pub fn connect_channel_to_charger(
2995        &self,
2996        server_end: fidl::endpoints::ServerEnd<ChargerMarker>,
2997    ) -> Result<(), fidl::Error> {
2998        self.0.open_member("charger", server_end.into_channel())
2999    }
3000    pub fn connect_to_controller(&self) -> Result<ControllerProxy, fidl::Error> {
3001        let (proxy, server_end) = fidl::endpoints::create_proxy::<ControllerMarker>();
3002        self.connect_channel_to_controller(server_end)?;
3003        Ok(proxy)
3004    }
3005
3006    /// Like `connect_to_controller`, but returns a sync proxy.
3007    /// See [`Self::connect_to_controller`] for more details.
3008    pub fn connect_to_controller_sync(&self) -> Result<ControllerSynchronousProxy, fidl::Error> {
3009        let (proxy, server_end) = fidl::endpoints::create_sync_proxy::<ControllerMarker>();
3010        self.connect_channel_to_controller(server_end)?;
3011        Ok(proxy)
3012    }
3013
3014    /// Like `connect_to_controller`, but accepts a server end.
3015    /// See [`Self::connect_to_controller`] for more details.
3016    pub fn connect_channel_to_controller(
3017        &self,
3018        server_end: fidl::endpoints::ServerEnd<ControllerMarker>,
3019    ) -> Result<(), fidl::Error> {
3020        self.0.open_member("controller", server_end.into_channel())
3021    }
3022
3023    pub fn instance_name(&self) -> &str {
3024        self.0.instance_name()
3025    }
3026}
3027
3028mod internal {
3029    use super::*;
3030
3031    impl fidl::encoding::ResourceTypeMarker for ChargerWatchRequest {
3032        type Borrowed<'a> = &'a mut Self;
3033        fn take_or_borrow<'a>(
3034            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
3035        ) -> Self::Borrowed<'a> {
3036            value
3037        }
3038    }
3039
3040    unsafe impl fidl::encoding::TypeMarker for ChargerWatchRequest {
3041        type Owned = Self;
3042
3043        #[inline(always)]
3044        fn inline_align(_context: fidl::encoding::Context) -> usize {
3045            4
3046        }
3047
3048        #[inline(always)]
3049        fn inline_size(_context: fidl::encoding::Context) -> usize {
3050            4
3051        }
3052    }
3053
3054    unsafe impl
3055        fidl::encoding::Encode<ChargerWatchRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
3056        for &mut ChargerWatchRequest
3057    {
3058        #[inline]
3059        unsafe fn encode(
3060            self,
3061            encoder: &mut fidl::encoding::Encoder<
3062                '_,
3063                fidl::encoding::DefaultFuchsiaResourceDialect,
3064            >,
3065            offset: usize,
3066            _depth: fidl::encoding::Depth,
3067        ) -> fidl::Result<()> {
3068            encoder.debug_check_bounds::<ChargerWatchRequest>(offset);
3069            // Delegate to tuple encoding.
3070            fidl::encoding::Encode::<
3071                ChargerWatchRequest,
3072                fidl::encoding::DefaultFuchsiaResourceDialect,
3073            >::encode(
3074                (<fidl::encoding::Optional<
3075                    fidl::encoding::HandleType<
3076                        fidl::EventPair,
3077                        { fidl::ObjectType::EVENTPAIR.into_raw() },
3078                        16387,
3079                    >,
3080                > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
3081                    &mut self.lease
3082                ),),
3083                encoder,
3084                offset,
3085                _depth,
3086            )
3087        }
3088    }
3089    unsafe impl<
3090        T0: fidl::encoding::Encode<
3091                fidl::encoding::Optional<
3092                    fidl::encoding::HandleType<
3093                        fidl::EventPair,
3094                        { fidl::ObjectType::EVENTPAIR.into_raw() },
3095                        16387,
3096                    >,
3097                >,
3098                fidl::encoding::DefaultFuchsiaResourceDialect,
3099            >,
3100    > fidl::encoding::Encode<ChargerWatchRequest, fidl::encoding::DefaultFuchsiaResourceDialect>
3101        for (T0,)
3102    {
3103        #[inline]
3104        unsafe fn encode(
3105            self,
3106            encoder: &mut fidl::encoding::Encoder<
3107                '_,
3108                fidl::encoding::DefaultFuchsiaResourceDialect,
3109            >,
3110            offset: usize,
3111            depth: fidl::encoding::Depth,
3112        ) -> fidl::Result<()> {
3113            encoder.debug_check_bounds::<ChargerWatchRequest>(offset);
3114            // Zero out padding regions. There's no need to apply masks
3115            // because the unmasked parts will be overwritten by fields.
3116            // Write the fields.
3117            self.0.encode(encoder, offset + 0, depth)?;
3118            Ok(())
3119        }
3120    }
3121
3122    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
3123        for ChargerWatchRequest
3124    {
3125        #[inline(always)]
3126        fn new_empty() -> Self {
3127            Self {
3128                lease: fidl::new_empty!(
3129                    fidl::encoding::Optional<
3130                        fidl::encoding::HandleType<
3131                            fidl::EventPair,
3132                            { fidl::ObjectType::EVENTPAIR.into_raw() },
3133                            16387,
3134                        >,
3135                    >,
3136                    fidl::encoding::DefaultFuchsiaResourceDialect
3137                ),
3138            }
3139        }
3140
3141        #[inline]
3142        unsafe fn decode(
3143            &mut self,
3144            decoder: &mut fidl::encoding::Decoder<
3145                '_,
3146                fidl::encoding::DefaultFuchsiaResourceDialect,
3147            >,
3148            offset: usize,
3149            _depth: fidl::encoding::Depth,
3150        ) -> fidl::Result<()> {
3151            decoder.debug_check_bounds::<Self>(offset);
3152            // Verify that padding bytes are zero.
3153            fidl::decode!(
3154                fidl::encoding::Optional<
3155                    fidl::encoding::HandleType<
3156                        fidl::EventPair,
3157                        { fidl::ObjectType::EVENTPAIR.into_raw() },
3158                        16387,
3159                    >,
3160                >,
3161                fidl::encoding::DefaultFuchsiaResourceDialect,
3162                &mut self.lease,
3163                decoder,
3164                offset + 0,
3165                _depth
3166            )?;
3167            Ok(())
3168        }
3169    }
3170
3171    impl fidl::encoding::ResourceTypeMarker for ChargerWatchResponse {
3172        type Borrowed<'a> = &'a mut Self;
3173        fn take_or_borrow<'a>(
3174            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
3175        ) -> Self::Borrowed<'a> {
3176            value
3177        }
3178    }
3179
3180    unsafe impl fidl::encoding::TypeMarker for ChargerWatchResponse {
3181        type Owned = Self;
3182
3183        #[inline(always)]
3184        fn inline_align(_context: fidl::encoding::Context) -> usize {
3185            8
3186        }
3187
3188        #[inline(always)]
3189        fn inline_size(_context: fidl::encoding::Context) -> usize {
3190            24
3191        }
3192    }
3193
3194    unsafe impl
3195        fidl::encoding::Encode<ChargerWatchResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
3196        for &mut ChargerWatchResponse
3197    {
3198        #[inline]
3199        unsafe fn encode(
3200            self,
3201            encoder: &mut fidl::encoding::Encoder<
3202                '_,
3203                fidl::encoding::DefaultFuchsiaResourceDialect,
3204            >,
3205            offset: usize,
3206            _depth: fidl::encoding::Depth,
3207        ) -> fidl::Result<()> {
3208            encoder.debug_check_bounds::<ChargerWatchResponse>(offset);
3209            // Delegate to tuple encoding.
3210            fidl::encoding::Encode::<
3211                ChargerWatchResponse,
3212                fidl::encoding::DefaultFuchsiaResourceDialect,
3213            >::encode(
3214                (
3215                    <Status as fidl::encoding::ValueTypeMarker>::borrow(&self.status),
3216                    <fidl::encoding::Optional<
3217                        fidl::encoding::HandleType<
3218                            fidl::EventPair,
3219                            { fidl::ObjectType::EVENTPAIR.into_raw() },
3220                            16387,
3221                        >,
3222                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
3223                        &mut self.wake_lease
3224                    ),
3225                ),
3226                encoder,
3227                offset,
3228                _depth,
3229            )
3230        }
3231    }
3232    unsafe impl<
3233        T0: fidl::encoding::Encode<Status, fidl::encoding::DefaultFuchsiaResourceDialect>,
3234        T1: fidl::encoding::Encode<
3235                fidl::encoding::Optional<
3236                    fidl::encoding::HandleType<
3237                        fidl::EventPair,
3238                        { fidl::ObjectType::EVENTPAIR.into_raw() },
3239                        16387,
3240                    >,
3241                >,
3242                fidl::encoding::DefaultFuchsiaResourceDialect,
3243            >,
3244    >
3245        fidl::encoding::Encode<ChargerWatchResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
3246        for (T0, T1)
3247    {
3248        #[inline]
3249        unsafe fn encode(
3250            self,
3251            encoder: &mut fidl::encoding::Encoder<
3252                '_,
3253                fidl::encoding::DefaultFuchsiaResourceDialect,
3254            >,
3255            offset: usize,
3256            depth: fidl::encoding::Depth,
3257        ) -> fidl::Result<()> {
3258            encoder.debug_check_bounds::<ChargerWatchResponse>(offset);
3259            // Zero out padding regions. There's no need to apply masks
3260            // because the unmasked parts will be overwritten by fields.
3261            unsafe {
3262                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(16);
3263                (ptr as *mut u64).write_unaligned(0);
3264            }
3265            // Write the fields.
3266            self.0.encode(encoder, offset + 0, depth)?;
3267            self.1.encode(encoder, offset + 16, depth)?;
3268            Ok(())
3269        }
3270    }
3271
3272    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
3273        for ChargerWatchResponse
3274    {
3275        #[inline(always)]
3276        fn new_empty() -> Self {
3277            Self {
3278                status: fidl::new_empty!(Status, fidl::encoding::DefaultFuchsiaResourceDialect),
3279                wake_lease: fidl::new_empty!(
3280                    fidl::encoding::Optional<
3281                        fidl::encoding::HandleType<
3282                            fidl::EventPair,
3283                            { fidl::ObjectType::EVENTPAIR.into_raw() },
3284                            16387,
3285                        >,
3286                    >,
3287                    fidl::encoding::DefaultFuchsiaResourceDialect
3288                ),
3289            }
3290        }
3291
3292        #[inline]
3293        unsafe fn decode(
3294            &mut self,
3295            decoder: &mut fidl::encoding::Decoder<
3296                '_,
3297                fidl::encoding::DefaultFuchsiaResourceDialect,
3298            >,
3299            offset: usize,
3300            _depth: fidl::encoding::Depth,
3301        ) -> fidl::Result<()> {
3302            decoder.debug_check_bounds::<Self>(offset);
3303            // Verify that padding bytes are zero.
3304            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(16) };
3305            let padval = unsafe { (ptr as *const u64).read_unaligned() };
3306            let mask = 0xffffffff00000000u64;
3307            let maskedval = padval & mask;
3308            if maskedval != 0 {
3309                return Err(fidl::Error::NonZeroPadding {
3310                    padding_start: offset + 16 + ((mask as u64).trailing_zeros() / 8) as usize,
3311                });
3312            }
3313            fidl::decode!(
3314                Status,
3315                fidl::encoding::DefaultFuchsiaResourceDialect,
3316                &mut self.status,
3317                decoder,
3318                offset + 0,
3319                _depth
3320            )?;
3321            fidl::decode!(
3322                fidl::encoding::Optional<
3323                    fidl::encoding::HandleType<
3324                        fidl::EventPair,
3325                        { fidl::ObjectType::EVENTPAIR.into_raw() },
3326                        16387,
3327                    >,
3328                >,
3329                fidl::encoding::DefaultFuchsiaResourceDialect,
3330                &mut self.wake_lease,
3331                decoder,
3332                offset + 16,
3333                _depth
3334            )?;
3335            Ok(())
3336        }
3337    }
3338}