fidl_fuchsia_session_power/
fidl_fuchsia_session_power.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_session_power_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct HandoffTakeResponse {
16    /// A lease on the power element.
17    ///
18    /// This is secretly a `fuchsia.power.broker.LeaseControl` channel
19    /// but we'd like to avoid exposing that to `ffx`. When that protocol
20    /// is stabilized, we can replace the channel with that here.
21    ///
22    /// TODO(https://fxbug.dev/339474151): This may also become an
23    /// eventpair as the linked bug tracks migrating lease control channel
24    /// to eventpair.
25    pub lease: fidl::Handle,
26}
27
28impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for HandoffTakeResponse {}
29
30#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
31pub struct HandoffMarker;
32
33impl fidl::endpoints::ProtocolMarker for HandoffMarker {
34    type Proxy = HandoffProxy;
35    type RequestStream = HandoffRequestStream;
36    #[cfg(target_os = "fuchsia")]
37    type SynchronousProxy = HandoffSynchronousProxy;
38
39    const DEBUG_NAME: &'static str = "fuchsia.session.power.Handoff";
40}
41impl fidl::endpoints::DiscoverableProtocolMarker for HandoffMarker {}
42pub type HandoffTakeResult = Result<fidl::Handle, HandoffError>;
43
44pub trait HandoffProxyInterface: Send + Sync {
45    type TakeResponseFut: std::future::Future<Output = Result<HandoffTakeResult, fidl::Error>>
46        + Send;
47    fn r#take(&self) -> Self::TakeResponseFut;
48}
49#[derive(Debug)]
50#[cfg(target_os = "fuchsia")]
51pub struct HandoffSynchronousProxy {
52    client: fidl::client::sync::Client,
53}
54
55#[cfg(target_os = "fuchsia")]
56impl fidl::endpoints::SynchronousProxy for HandoffSynchronousProxy {
57    type Proxy = HandoffProxy;
58    type Protocol = HandoffMarker;
59
60    fn from_channel(inner: fidl::Channel) -> Self {
61        Self::new(inner)
62    }
63
64    fn into_channel(self) -> fidl::Channel {
65        self.client.into_channel()
66    }
67
68    fn as_channel(&self) -> &fidl::Channel {
69        self.client.as_channel()
70    }
71}
72
73#[cfg(target_os = "fuchsia")]
74impl HandoffSynchronousProxy {
75    pub fn new(channel: fidl::Channel) -> Self {
76        let protocol_name = <HandoffMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
77        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
78    }
79
80    pub fn into_channel(self) -> fidl::Channel {
81        self.client.into_channel()
82    }
83
84    /// Waits until an event arrives and returns it. It is safe for other
85    /// threads to make concurrent requests while waiting for an event.
86    pub fn wait_for_event(
87        &self,
88        deadline: zx::MonotonicInstant,
89    ) -> Result<HandoffEvent, fidl::Error> {
90        HandoffEvent::decode(self.client.wait_for_event(deadline)?)
91    }
92
93    /// Take the lease.
94    pub fn r#take(
95        &self,
96        ___deadline: zx::MonotonicInstant,
97    ) -> Result<HandoffTakeResult, fidl::Error> {
98        let _response = self.client.send_query::<
99            fidl::encoding::EmptyPayload,
100            fidl::encoding::FlexibleResultType<HandoffTakeResponse, HandoffError>,
101        >(
102            (),
103            0x7150089bdc73770b,
104            fidl::encoding::DynamicFlags::FLEXIBLE,
105            ___deadline,
106        )?
107        .into_result::<HandoffMarker>("take")?;
108        Ok(_response.map(|x| x.lease))
109    }
110}
111
112#[derive(Debug, Clone)]
113pub struct HandoffProxy {
114    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
115}
116
117impl fidl::endpoints::Proxy for HandoffProxy {
118    type Protocol = HandoffMarker;
119
120    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
121        Self::new(inner)
122    }
123
124    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
125        self.client.into_channel().map_err(|client| Self { client })
126    }
127
128    fn as_channel(&self) -> &::fidl::AsyncChannel {
129        self.client.as_channel()
130    }
131}
132
133impl HandoffProxy {
134    /// Create a new Proxy for fuchsia.session.power/Handoff.
135    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
136        let protocol_name = <HandoffMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
137        Self { client: fidl::client::Client::new(channel, protocol_name) }
138    }
139
140    /// Get a Stream of events from the remote end of the protocol.
141    ///
142    /// # Panics
143    ///
144    /// Panics if the event stream was already taken.
145    pub fn take_event_stream(&self) -> HandoffEventStream {
146        HandoffEventStream { event_receiver: self.client.take_event_receiver() }
147    }
148
149    /// Take the lease.
150    pub fn r#take(
151        &self,
152    ) -> fidl::client::QueryResponseFut<
153        HandoffTakeResult,
154        fidl::encoding::DefaultFuchsiaResourceDialect,
155    > {
156        HandoffProxyInterface::r#take(self)
157    }
158}
159
160impl HandoffProxyInterface for HandoffProxy {
161    type TakeResponseFut = fidl::client::QueryResponseFut<
162        HandoffTakeResult,
163        fidl::encoding::DefaultFuchsiaResourceDialect,
164    >;
165    fn r#take(&self) -> Self::TakeResponseFut {
166        fn _decode(
167            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
168        ) -> Result<HandoffTakeResult, fidl::Error> {
169            let _response = fidl::client::decode_transaction_body::<
170                fidl::encoding::FlexibleResultType<HandoffTakeResponse, HandoffError>,
171                fidl::encoding::DefaultFuchsiaResourceDialect,
172                0x7150089bdc73770b,
173            >(_buf?)?
174            .into_result::<HandoffMarker>("take")?;
175            Ok(_response.map(|x| x.lease))
176        }
177        self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, HandoffTakeResult>(
178            (),
179            0x7150089bdc73770b,
180            fidl::encoding::DynamicFlags::FLEXIBLE,
181            _decode,
182        )
183    }
184}
185
186pub struct HandoffEventStream {
187    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
188}
189
190impl std::marker::Unpin for HandoffEventStream {}
191
192impl futures::stream::FusedStream for HandoffEventStream {
193    fn is_terminated(&self) -> bool {
194        self.event_receiver.is_terminated()
195    }
196}
197
198impl futures::Stream for HandoffEventStream {
199    type Item = Result<HandoffEvent, fidl::Error>;
200
201    fn poll_next(
202        mut self: std::pin::Pin<&mut Self>,
203        cx: &mut std::task::Context<'_>,
204    ) -> std::task::Poll<Option<Self::Item>> {
205        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
206            &mut self.event_receiver,
207            cx
208        )?) {
209            Some(buf) => std::task::Poll::Ready(Some(HandoffEvent::decode(buf))),
210            None => std::task::Poll::Ready(None),
211        }
212    }
213}
214
215#[derive(Debug)]
216pub enum HandoffEvent {
217    #[non_exhaustive]
218    _UnknownEvent {
219        /// Ordinal of the event that was sent.
220        ordinal: u64,
221    },
222}
223
224impl HandoffEvent {
225    /// Decodes a message buffer as a [`HandoffEvent`].
226    fn decode(
227        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
228    ) -> Result<HandoffEvent, fidl::Error> {
229        let (bytes, _handles) = buf.split_mut();
230        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
231        debug_assert_eq!(tx_header.tx_id, 0);
232        match tx_header.ordinal {
233            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
234                Ok(HandoffEvent::_UnknownEvent { ordinal: tx_header.ordinal })
235            }
236            _ => Err(fidl::Error::UnknownOrdinal {
237                ordinal: tx_header.ordinal,
238                protocol_name: <HandoffMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
239            }),
240        }
241    }
242}
243
244/// A Stream of incoming requests for fuchsia.session.power/Handoff.
245pub struct HandoffRequestStream {
246    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
247    is_terminated: bool,
248}
249
250impl std::marker::Unpin for HandoffRequestStream {}
251
252impl futures::stream::FusedStream for HandoffRequestStream {
253    fn is_terminated(&self) -> bool {
254        self.is_terminated
255    }
256}
257
258impl fidl::endpoints::RequestStream for HandoffRequestStream {
259    type Protocol = HandoffMarker;
260    type ControlHandle = HandoffControlHandle;
261
262    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
263        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
264    }
265
266    fn control_handle(&self) -> Self::ControlHandle {
267        HandoffControlHandle { inner: self.inner.clone() }
268    }
269
270    fn into_inner(
271        self,
272    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
273    {
274        (self.inner, self.is_terminated)
275    }
276
277    fn from_inner(
278        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
279        is_terminated: bool,
280    ) -> Self {
281        Self { inner, is_terminated }
282    }
283}
284
285impl futures::Stream for HandoffRequestStream {
286    type Item = Result<HandoffRequest, fidl::Error>;
287
288    fn poll_next(
289        mut self: std::pin::Pin<&mut Self>,
290        cx: &mut std::task::Context<'_>,
291    ) -> std::task::Poll<Option<Self::Item>> {
292        let this = &mut *self;
293        if this.inner.check_shutdown(cx) {
294            this.is_terminated = true;
295            return std::task::Poll::Ready(None);
296        }
297        if this.is_terminated {
298            panic!("polled HandoffRequestStream after completion");
299        }
300        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
301            |bytes, handles| {
302                match this.inner.channel().read_etc(cx, bytes, handles) {
303                    std::task::Poll::Ready(Ok(())) => {}
304                    std::task::Poll::Pending => return std::task::Poll::Pending,
305                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
306                        this.is_terminated = true;
307                        return std::task::Poll::Ready(None);
308                    }
309                    std::task::Poll::Ready(Err(e)) => {
310                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
311                            e.into(),
312                        ))))
313                    }
314                }
315
316                // A message has been received from the channel
317                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
318
319                std::task::Poll::Ready(Some(match header.ordinal {
320                    0x7150089bdc73770b => {
321                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
322                        let mut req = fidl::new_empty!(
323                            fidl::encoding::EmptyPayload,
324                            fidl::encoding::DefaultFuchsiaResourceDialect
325                        );
326                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
327                        let control_handle = HandoffControlHandle { inner: this.inner.clone() };
328                        Ok(HandoffRequest::Take {
329                            responder: HandoffTakeResponder {
330                                control_handle: std::mem::ManuallyDrop::new(control_handle),
331                                tx_id: header.tx_id,
332                            },
333                        })
334                    }
335                    _ if header.tx_id == 0
336                        && header
337                            .dynamic_flags()
338                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
339                    {
340                        Ok(HandoffRequest::_UnknownMethod {
341                            ordinal: header.ordinal,
342                            control_handle: HandoffControlHandle { inner: this.inner.clone() },
343                            method_type: fidl::MethodType::OneWay,
344                        })
345                    }
346                    _ if header
347                        .dynamic_flags()
348                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
349                    {
350                        this.inner.send_framework_err(
351                            fidl::encoding::FrameworkErr::UnknownMethod,
352                            header.tx_id,
353                            header.ordinal,
354                            header.dynamic_flags(),
355                            (bytes, handles),
356                        )?;
357                        Ok(HandoffRequest::_UnknownMethod {
358                            ordinal: header.ordinal,
359                            control_handle: HandoffControlHandle { inner: this.inner.clone() },
360                            method_type: fidl::MethodType::TwoWay,
361                        })
362                    }
363                    _ => Err(fidl::Error::UnknownOrdinal {
364                        ordinal: header.ordinal,
365                        protocol_name:
366                            <HandoffMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
367                    }),
368                }))
369            },
370        )
371    }
372}
373
374/// Lets the session manager handoff a power lease to a session component.
375///
376/// As an example, `session_manager` may take a lease on the
377/// `ApplicationActivity` power element, and offer [`Handoff`] to the
378/// session component. The session component can then take the lease from
379/// `session_manager` when it is started. This way a constant dependency
380/// is maintained on `ApplicationActivity` as the session is restarted.
381#[derive(Debug)]
382pub enum HandoffRequest {
383    /// Take the lease.
384    Take { responder: HandoffTakeResponder },
385    /// An interaction was received which does not match any known method.
386    #[non_exhaustive]
387    _UnknownMethod {
388        /// Ordinal of the method that was called.
389        ordinal: u64,
390        control_handle: HandoffControlHandle,
391        method_type: fidl::MethodType,
392    },
393}
394
395impl HandoffRequest {
396    #[allow(irrefutable_let_patterns)]
397    pub fn into_take(self) -> Option<(HandoffTakeResponder)> {
398        if let HandoffRequest::Take { responder } = self {
399            Some((responder))
400        } else {
401            None
402        }
403    }
404
405    /// Name of the method defined in FIDL
406    pub fn method_name(&self) -> &'static str {
407        match *self {
408            HandoffRequest::Take { .. } => "take",
409            HandoffRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
410                "unknown one-way method"
411            }
412            HandoffRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
413                "unknown two-way method"
414            }
415        }
416    }
417}
418
419#[derive(Debug, Clone)]
420pub struct HandoffControlHandle {
421    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
422}
423
424impl fidl::endpoints::ControlHandle for HandoffControlHandle {
425    fn shutdown(&self) {
426        self.inner.shutdown()
427    }
428    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
429        self.inner.shutdown_with_epitaph(status)
430    }
431
432    fn is_closed(&self) -> bool {
433        self.inner.channel().is_closed()
434    }
435    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
436        self.inner.channel().on_closed()
437    }
438
439    #[cfg(target_os = "fuchsia")]
440    fn signal_peer(
441        &self,
442        clear_mask: zx::Signals,
443        set_mask: zx::Signals,
444    ) -> Result<(), zx_status::Status> {
445        use fidl::Peered;
446        self.inner.channel().signal_peer(clear_mask, set_mask)
447    }
448}
449
450impl HandoffControlHandle {}
451
452#[must_use = "FIDL methods require a response to be sent"]
453#[derive(Debug)]
454pub struct HandoffTakeResponder {
455    control_handle: std::mem::ManuallyDrop<HandoffControlHandle>,
456    tx_id: u32,
457}
458
459/// Set the the channel to be shutdown (see [`HandoffControlHandle::shutdown`])
460/// if the responder is dropped without sending a response, so that the client
461/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
462impl std::ops::Drop for HandoffTakeResponder {
463    fn drop(&mut self) {
464        self.control_handle.shutdown();
465        // Safety: drops once, never accessed again
466        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
467    }
468}
469
470impl fidl::endpoints::Responder for HandoffTakeResponder {
471    type ControlHandle = HandoffControlHandle;
472
473    fn control_handle(&self) -> &HandoffControlHandle {
474        &self.control_handle
475    }
476
477    fn drop_without_shutdown(mut self) {
478        // Safety: drops once, never accessed again due to mem::forget
479        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
480        // Prevent Drop from running (which would shut down the channel)
481        std::mem::forget(self);
482    }
483}
484
485impl HandoffTakeResponder {
486    /// Sends a response to the FIDL transaction.
487    ///
488    /// Sets the channel to shutdown if an error occurs.
489    pub fn send(self, mut result: Result<fidl::Handle, HandoffError>) -> Result<(), fidl::Error> {
490        let _result = self.send_raw(result);
491        if _result.is_err() {
492            self.control_handle.shutdown();
493        }
494        self.drop_without_shutdown();
495        _result
496    }
497
498    /// Similar to "send" but does not shutdown the channel if an error occurs.
499    pub fn send_no_shutdown_on_err(
500        self,
501        mut result: Result<fidl::Handle, HandoffError>,
502    ) -> Result<(), fidl::Error> {
503        let _result = self.send_raw(result);
504        self.drop_without_shutdown();
505        _result
506    }
507
508    fn send_raw(&self, mut result: Result<fidl::Handle, HandoffError>) -> Result<(), fidl::Error> {
509        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
510            HandoffTakeResponse,
511            HandoffError,
512        >>(
513            fidl::encoding::FlexibleResult::new(result.map(|lease| (lease,))),
514            self.tx_id,
515            0x7150089bdc73770b,
516            fidl::encoding::DynamicFlags::FLEXIBLE,
517        )
518    }
519}
520
521mod internal {
522    use super::*;
523
524    impl fidl::encoding::ResourceTypeMarker for HandoffTakeResponse {
525        type Borrowed<'a> = &'a mut Self;
526        fn take_or_borrow<'a>(
527            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
528        ) -> Self::Borrowed<'a> {
529            value
530        }
531    }
532
533    unsafe impl fidl::encoding::TypeMarker for HandoffTakeResponse {
534        type Owned = Self;
535
536        #[inline(always)]
537        fn inline_align(_context: fidl::encoding::Context) -> usize {
538            4
539        }
540
541        #[inline(always)]
542        fn inline_size(_context: fidl::encoding::Context) -> usize {
543            4
544        }
545    }
546
547    unsafe impl
548        fidl::encoding::Encode<HandoffTakeResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
549        for &mut HandoffTakeResponse
550    {
551        #[inline]
552        unsafe fn encode(
553            self,
554            encoder: &mut fidl::encoding::Encoder<
555                '_,
556                fidl::encoding::DefaultFuchsiaResourceDialect,
557            >,
558            offset: usize,
559            _depth: fidl::encoding::Depth,
560        ) -> fidl::Result<()> {
561            encoder.debug_check_bounds::<HandoffTakeResponse>(offset);
562            // Delegate to tuple encoding.
563            fidl::encoding::Encode::<
564                HandoffTakeResponse,
565                fidl::encoding::DefaultFuchsiaResourceDialect,
566            >::encode(
567                (<fidl::encoding::HandleType<
568                    fidl::Handle,
569                    { fidl::ObjectType::NONE.into_raw() },
570                    2147483648,
571                > as fidl::encoding::ResourceTypeMarker>::take_or_borrow(
572                    &mut self.lease
573                ),),
574                encoder,
575                offset,
576                _depth,
577            )
578        }
579    }
580    unsafe impl<
581            T0: fidl::encoding::Encode<
582                fidl::encoding::HandleType<
583                    fidl::Handle,
584                    { fidl::ObjectType::NONE.into_raw() },
585                    2147483648,
586                >,
587                fidl::encoding::DefaultFuchsiaResourceDialect,
588            >,
589        >
590        fidl::encoding::Encode<HandoffTakeResponse, fidl::encoding::DefaultFuchsiaResourceDialect>
591        for (T0,)
592    {
593        #[inline]
594        unsafe fn encode(
595            self,
596            encoder: &mut fidl::encoding::Encoder<
597                '_,
598                fidl::encoding::DefaultFuchsiaResourceDialect,
599            >,
600            offset: usize,
601            depth: fidl::encoding::Depth,
602        ) -> fidl::Result<()> {
603            encoder.debug_check_bounds::<HandoffTakeResponse>(offset);
604            // Zero out padding regions. There's no need to apply masks
605            // because the unmasked parts will be overwritten by fields.
606            // Write the fields.
607            self.0.encode(encoder, offset + 0, depth)?;
608            Ok(())
609        }
610    }
611
612    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
613        for HandoffTakeResponse
614    {
615        #[inline(always)]
616        fn new_empty() -> Self {
617            Self {
618                lease: fidl::new_empty!(fidl::encoding::HandleType<fidl::Handle, { fidl::ObjectType::NONE.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect),
619            }
620        }
621
622        #[inline]
623        unsafe fn decode(
624            &mut self,
625            decoder: &mut fidl::encoding::Decoder<
626                '_,
627                fidl::encoding::DefaultFuchsiaResourceDialect,
628            >,
629            offset: usize,
630            _depth: fidl::encoding::Depth,
631        ) -> fidl::Result<()> {
632            decoder.debug_check_bounds::<Self>(offset);
633            // Verify that padding bytes are zero.
634            fidl::decode!(fidl::encoding::HandleType<fidl::Handle, { fidl::ObjectType::NONE.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, &mut self.lease, decoder, offset + 0, _depth)?;
635            Ok(())
636        }
637    }
638}