Skip to main content

fidl_fuchsia_ui_input3/
fidl_fuchsia_ui_input3.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_ui_input3_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, PartialEq)]
15pub struct KeyboardAddListenerRequest {
16    pub view_ref: fidl_fuchsia_ui_views::ViewRef,
17    pub listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
18}
19
20impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
21    for KeyboardAddListenerRequest
22{
23}
24
25#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
26pub struct KeyEventInjectorMarker;
27
28impl fidl::endpoints::ProtocolMarker for KeyEventInjectorMarker {
29    type Proxy = KeyEventInjectorProxy;
30    type RequestStream = KeyEventInjectorRequestStream;
31    #[cfg(target_os = "fuchsia")]
32    type SynchronousProxy = KeyEventInjectorSynchronousProxy;
33
34    const DEBUG_NAME: &'static str = "fuchsia.ui.input3.KeyEventInjector";
35}
36impl fidl::endpoints::DiscoverableProtocolMarker for KeyEventInjectorMarker {}
37
38pub trait KeyEventInjectorProxyInterface: Send + Sync {
39    type InjectResponseFut: std::future::Future<Output = Result<KeyEventStatus, fidl::Error>> + Send;
40    fn r#inject(&self, key_event: &KeyEvent) -> Self::InjectResponseFut;
41}
42#[derive(Debug)]
43#[cfg(target_os = "fuchsia")]
44pub struct KeyEventInjectorSynchronousProxy {
45    client: fidl::client::sync::Client,
46}
47
48#[cfg(target_os = "fuchsia")]
49impl fidl::endpoints::SynchronousProxy for KeyEventInjectorSynchronousProxy {
50    type Proxy = KeyEventInjectorProxy;
51    type Protocol = KeyEventInjectorMarker;
52
53    fn from_channel(inner: fidl::Channel) -> Self {
54        Self::new(inner)
55    }
56
57    fn into_channel(self) -> fidl::Channel {
58        self.client.into_channel()
59    }
60
61    fn as_channel(&self) -> &fidl::Channel {
62        self.client.as_channel()
63    }
64}
65
66#[cfg(target_os = "fuchsia")]
67impl KeyEventInjectorSynchronousProxy {
68    pub fn new(channel: fidl::Channel) -> Self {
69        Self { client: fidl::client::sync::Client::new(channel) }
70    }
71
72    pub fn into_channel(self) -> fidl::Channel {
73        self.client.into_channel()
74    }
75
76    /// Waits until an event arrives and returns it. It is safe for other
77    /// threads to make concurrent requests while waiting for an event.
78    pub fn wait_for_event(
79        &self,
80        deadline: zx::MonotonicInstant,
81    ) -> Result<KeyEventInjectorEvent, fidl::Error> {
82        KeyEventInjectorEvent::decode(
83            self.client.wait_for_event::<KeyEventInjectorMarker>(deadline)?,
84        )
85    }
86
87    /// Inject an event into the keyboard subsystem.
88    ///
89    /// # Returns
90    /// * `HANDLED` if the keyboard subsystem delivered the event to a consumer,
91    ///   and the consumer reported that it `HANDLED` the event
92    /// * `NOT_HANDLED` if the keyboard subsystem did not deliever the event to
93    ///   any consumers, or no consumer reported that it `HANDLED` the event.
94    pub fn r#inject(
95        &self,
96        mut key_event: &KeyEvent,
97        ___deadline: zx::MonotonicInstant,
98    ) -> Result<KeyEventStatus, fidl::Error> {
99        let _response = self.client.send_query::<
100            KeyEventInjectorInjectRequest,
101            KeyEventInjectorInjectResponse,
102            KeyEventInjectorMarker,
103        >(
104            (key_event,),
105            0x1eb2c0d795c68949,
106            fidl::encoding::DynamicFlags::empty(),
107            ___deadline,
108        )?;
109        Ok(_response.status)
110    }
111}
112
113#[cfg(target_os = "fuchsia")]
114impl From<KeyEventInjectorSynchronousProxy> for zx::NullableHandle {
115    fn from(value: KeyEventInjectorSynchronousProxy) -> Self {
116        value.into_channel().into()
117    }
118}
119
120#[cfg(target_os = "fuchsia")]
121impl From<fidl::Channel> for KeyEventInjectorSynchronousProxy {
122    fn from(value: fidl::Channel) -> Self {
123        Self::new(value)
124    }
125}
126
127#[cfg(target_os = "fuchsia")]
128impl fidl::endpoints::FromClient for KeyEventInjectorSynchronousProxy {
129    type Protocol = KeyEventInjectorMarker;
130
131    fn from_client(value: fidl::endpoints::ClientEnd<KeyEventInjectorMarker>) -> Self {
132        Self::new(value.into_channel())
133    }
134}
135
136#[derive(Debug, Clone)]
137pub struct KeyEventInjectorProxy {
138    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
139}
140
141impl fidl::endpoints::Proxy for KeyEventInjectorProxy {
142    type Protocol = KeyEventInjectorMarker;
143
144    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
145        Self::new(inner)
146    }
147
148    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
149        self.client.into_channel().map_err(|client| Self { client })
150    }
151
152    fn as_channel(&self) -> &::fidl::AsyncChannel {
153        self.client.as_channel()
154    }
155}
156
157impl KeyEventInjectorProxy {
158    /// Create a new Proxy for fuchsia.ui.input3/KeyEventInjector.
159    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
160        let protocol_name = <KeyEventInjectorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
161        Self { client: fidl::client::Client::new(channel, protocol_name) }
162    }
163
164    /// Get a Stream of events from the remote end of the protocol.
165    ///
166    /// # Panics
167    ///
168    /// Panics if the event stream was already taken.
169    pub fn take_event_stream(&self) -> KeyEventInjectorEventStream {
170        KeyEventInjectorEventStream { event_receiver: self.client.take_event_receiver() }
171    }
172
173    /// Inject an event into the keyboard subsystem.
174    ///
175    /// # Returns
176    /// * `HANDLED` if the keyboard subsystem delivered the event to a consumer,
177    ///   and the consumer reported that it `HANDLED` the event
178    /// * `NOT_HANDLED` if the keyboard subsystem did not deliever the event to
179    ///   any consumers, or no consumer reported that it `HANDLED` the event.
180    pub fn r#inject(
181        &self,
182        mut key_event: &KeyEvent,
183    ) -> fidl::client::QueryResponseFut<KeyEventStatus, fidl::encoding::DefaultFuchsiaResourceDialect>
184    {
185        KeyEventInjectorProxyInterface::r#inject(self, key_event)
186    }
187}
188
189impl KeyEventInjectorProxyInterface for KeyEventInjectorProxy {
190    type InjectResponseFut = fidl::client::QueryResponseFut<
191        KeyEventStatus,
192        fidl::encoding::DefaultFuchsiaResourceDialect,
193    >;
194    fn r#inject(&self, mut key_event: &KeyEvent) -> Self::InjectResponseFut {
195        fn _decode(
196            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
197        ) -> Result<KeyEventStatus, fidl::Error> {
198            let _response = fidl::client::decode_transaction_body::<
199                KeyEventInjectorInjectResponse,
200                fidl::encoding::DefaultFuchsiaResourceDialect,
201                0x1eb2c0d795c68949,
202            >(_buf?)?;
203            Ok(_response.status)
204        }
205        self.client.send_query_and_decode::<KeyEventInjectorInjectRequest, KeyEventStatus>(
206            (key_event,),
207            0x1eb2c0d795c68949,
208            fidl::encoding::DynamicFlags::empty(),
209            _decode,
210        )
211    }
212}
213
214pub struct KeyEventInjectorEventStream {
215    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
216}
217
218impl std::marker::Unpin for KeyEventInjectorEventStream {}
219
220impl futures::stream::FusedStream for KeyEventInjectorEventStream {
221    fn is_terminated(&self) -> bool {
222        self.event_receiver.is_terminated()
223    }
224}
225
226impl futures::Stream for KeyEventInjectorEventStream {
227    type Item = Result<KeyEventInjectorEvent, fidl::Error>;
228
229    fn poll_next(
230        mut self: std::pin::Pin<&mut Self>,
231        cx: &mut std::task::Context<'_>,
232    ) -> std::task::Poll<Option<Self::Item>> {
233        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
234            &mut self.event_receiver,
235            cx
236        )?) {
237            Some(buf) => std::task::Poll::Ready(Some(KeyEventInjectorEvent::decode(buf))),
238            None => std::task::Poll::Ready(None),
239        }
240    }
241}
242
243#[derive(Debug)]
244pub enum KeyEventInjectorEvent {}
245
246impl KeyEventInjectorEvent {
247    /// Decodes a message buffer as a [`KeyEventInjectorEvent`].
248    fn decode(
249        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
250    ) -> Result<KeyEventInjectorEvent, fidl::Error> {
251        let (bytes, _handles) = buf.split_mut();
252        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
253        debug_assert_eq!(tx_header.tx_id, 0);
254        match tx_header.ordinal {
255            _ => Err(fidl::Error::UnknownOrdinal {
256                ordinal: tx_header.ordinal,
257                protocol_name:
258                    <KeyEventInjectorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
259            }),
260        }
261    }
262}
263
264/// A Stream of incoming requests for fuchsia.ui.input3/KeyEventInjector.
265pub struct KeyEventInjectorRequestStream {
266    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
267    is_terminated: bool,
268}
269
270impl std::marker::Unpin for KeyEventInjectorRequestStream {}
271
272impl futures::stream::FusedStream for KeyEventInjectorRequestStream {
273    fn is_terminated(&self) -> bool {
274        self.is_terminated
275    }
276}
277
278impl fidl::endpoints::RequestStream for KeyEventInjectorRequestStream {
279    type Protocol = KeyEventInjectorMarker;
280    type ControlHandle = KeyEventInjectorControlHandle;
281
282    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
283        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
284    }
285
286    fn control_handle(&self) -> Self::ControlHandle {
287        KeyEventInjectorControlHandle { inner: self.inner.clone() }
288    }
289
290    fn into_inner(
291        self,
292    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
293    {
294        (self.inner, self.is_terminated)
295    }
296
297    fn from_inner(
298        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
299        is_terminated: bool,
300    ) -> Self {
301        Self { inner, is_terminated }
302    }
303}
304
305impl futures::Stream for KeyEventInjectorRequestStream {
306    type Item = Result<KeyEventInjectorRequest, fidl::Error>;
307
308    fn poll_next(
309        mut self: std::pin::Pin<&mut Self>,
310        cx: &mut std::task::Context<'_>,
311    ) -> std::task::Poll<Option<Self::Item>> {
312        let this = &mut *self;
313        if this.inner.check_shutdown(cx) {
314            this.is_terminated = true;
315            return std::task::Poll::Ready(None);
316        }
317        if this.is_terminated {
318            panic!("polled KeyEventInjectorRequestStream after completion");
319        }
320        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
321            |bytes, handles| {
322                match this.inner.channel().read_etc(cx, bytes, handles) {
323                    std::task::Poll::Ready(Ok(())) => {}
324                    std::task::Poll::Pending => return std::task::Poll::Pending,
325                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
326                        this.is_terminated = true;
327                        return std::task::Poll::Ready(None);
328                    }
329                    std::task::Poll::Ready(Err(e)) => {
330                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
331                            e.into(),
332                        ))));
333                    }
334                }
335
336                // A message has been received from the channel
337                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
338
339                std::task::Poll::Ready(Some(match header.ordinal {
340                    0x1eb2c0d795c68949 => {
341                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
342                        let mut req = fidl::new_empty!(
343                            KeyEventInjectorInjectRequest,
344                            fidl::encoding::DefaultFuchsiaResourceDialect
345                        );
346                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<KeyEventInjectorInjectRequest>(&header, _body_bytes, handles, &mut req)?;
347                        let control_handle =
348                            KeyEventInjectorControlHandle { inner: this.inner.clone() };
349                        Ok(KeyEventInjectorRequest::Inject {
350                            key_event: req.key_event,
351
352                            responder: KeyEventInjectorInjectResponder {
353                                control_handle: std::mem::ManuallyDrop::new(control_handle),
354                                tx_id: header.tx_id,
355                            },
356                        })
357                    }
358                    _ => Err(fidl::Error::UnknownOrdinal {
359                        ordinal: header.ordinal,
360                        protocol_name:
361                            <KeyEventInjectorMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
362                    }),
363                }))
364            },
365        )
366    }
367}
368
369/// Provides the ability to inject `KeyEvent`s into the keyboard subsystem.
370///
371/// # Roles
372/// This protocol will typically be:
373/// * Implemented by platform components which process and deliver keyboard
374///   events.
375/// * Consumed by components which originiate keyboard events. E.g.
376///   an on-screen keyboard, or the Session Framework Input Pipeline.
377///
378/// # Related protocols
379/// This protocol should be using in preference to legacy protocols which provide
380/// similar functionality. Specifically, this means this protocol should be preferred
381/// over
382/// * `fuchsia.ui.input.ImeService` which provides `InjectInput()`, `DispatchKey()`,
383///   and `DispatchKey3()`
384/// * `fuchsia.ui.input.InputMethodEditor`, which provides `InjectInput()` and
385///   `DispatchKey3()`
386///
387/// # Notes
388/// Products should take care to limit access to this protocol, as events injected
389/// with this protocol are indistinguishable from those coming from physical devices.
390#[derive(Debug)]
391pub enum KeyEventInjectorRequest {
392    /// Inject an event into the keyboard subsystem.
393    ///
394    /// # Returns
395    /// * `HANDLED` if the keyboard subsystem delivered the event to a consumer,
396    ///   and the consumer reported that it `HANDLED` the event
397    /// * `NOT_HANDLED` if the keyboard subsystem did not deliever the event to
398    ///   any consumers, or no consumer reported that it `HANDLED` the event.
399    Inject { key_event: KeyEvent, responder: KeyEventInjectorInjectResponder },
400}
401
402impl KeyEventInjectorRequest {
403    #[allow(irrefutable_let_patterns)]
404    pub fn into_inject(self) -> Option<(KeyEvent, KeyEventInjectorInjectResponder)> {
405        if let KeyEventInjectorRequest::Inject { key_event, responder } = self {
406            Some((key_event, responder))
407        } else {
408            None
409        }
410    }
411
412    /// Name of the method defined in FIDL
413    pub fn method_name(&self) -> &'static str {
414        match *self {
415            KeyEventInjectorRequest::Inject { .. } => "inject",
416        }
417    }
418}
419
420#[derive(Debug, Clone)]
421pub struct KeyEventInjectorControlHandle {
422    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
423}
424
425impl KeyEventInjectorControlHandle {
426    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
427        self.inner.shutdown_with_epitaph(status.into())
428    }
429}
430
431impl fidl::endpoints::ControlHandle for KeyEventInjectorControlHandle {
432    fn shutdown(&self) {
433        self.inner.shutdown()
434    }
435
436    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
437        self.inner.shutdown_with_epitaph(status)
438    }
439
440    fn is_closed(&self) -> bool {
441        self.inner.channel().is_closed()
442    }
443    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
444        self.inner.channel().on_closed()
445    }
446
447    #[cfg(target_os = "fuchsia")]
448    fn signal_peer(
449        &self,
450        clear_mask: zx::Signals,
451        set_mask: zx::Signals,
452    ) -> Result<(), zx_status::Status> {
453        use fidl::Peered;
454        self.inner.channel().signal_peer(clear_mask, set_mask)
455    }
456}
457
458impl KeyEventInjectorControlHandle {}
459
460#[must_use = "FIDL methods require a response to be sent"]
461#[derive(Debug)]
462pub struct KeyEventInjectorInjectResponder {
463    control_handle: std::mem::ManuallyDrop<KeyEventInjectorControlHandle>,
464    tx_id: u32,
465}
466
467/// Set the the channel to be shutdown (see [`KeyEventInjectorControlHandle::shutdown`])
468/// if the responder is dropped without sending a response, so that the client
469/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
470impl std::ops::Drop for KeyEventInjectorInjectResponder {
471    fn drop(&mut self) {
472        self.control_handle.shutdown();
473        // Safety: drops once, never accessed again
474        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
475    }
476}
477
478impl fidl::endpoints::Responder for KeyEventInjectorInjectResponder {
479    type ControlHandle = KeyEventInjectorControlHandle;
480
481    fn control_handle(&self) -> &KeyEventInjectorControlHandle {
482        &self.control_handle
483    }
484
485    fn drop_without_shutdown(mut self) {
486        // Safety: drops once, never accessed again due to mem::forget
487        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
488        // Prevent Drop from running (which would shut down the channel)
489        std::mem::forget(self);
490    }
491}
492
493impl KeyEventInjectorInjectResponder {
494    /// Sends a response to the FIDL transaction.
495    ///
496    /// Sets the channel to shutdown if an error occurs.
497    pub fn send(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
498        let _result = self.send_raw(status);
499        if _result.is_err() {
500            self.control_handle.shutdown();
501        }
502        self.drop_without_shutdown();
503        _result
504    }
505
506    /// Similar to "send" but does not shutdown the channel if an error occurs.
507    pub fn send_no_shutdown_on_err(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
508        let _result = self.send_raw(status);
509        self.drop_without_shutdown();
510        _result
511    }
512
513    fn send_raw(&self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
514        self.control_handle.inner.send::<KeyEventInjectorInjectResponse>(
515            (status,),
516            self.tx_id,
517            0x1eb2c0d795c68949,
518            fidl::encoding::DynamicFlags::empty(),
519        )
520    }
521}
522
523#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
524pub struct KeyboardMarker;
525
526impl fidl::endpoints::ProtocolMarker for KeyboardMarker {
527    type Proxy = KeyboardProxy;
528    type RequestStream = KeyboardRequestStream;
529    #[cfg(target_os = "fuchsia")]
530    type SynchronousProxy = KeyboardSynchronousProxy;
531
532    const DEBUG_NAME: &'static str = "fuchsia.ui.input3.Keyboard";
533}
534impl fidl::endpoints::DiscoverableProtocolMarker for KeyboardMarker {}
535
536pub trait KeyboardProxyInterface: Send + Sync {
537    type AddListenerResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
538    fn r#add_listener(
539        &self,
540        view_ref: fidl_fuchsia_ui_views::ViewRef,
541        listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
542    ) -> Self::AddListenerResponseFut;
543}
544#[derive(Debug)]
545#[cfg(target_os = "fuchsia")]
546pub struct KeyboardSynchronousProxy {
547    client: fidl::client::sync::Client,
548}
549
550#[cfg(target_os = "fuchsia")]
551impl fidl::endpoints::SynchronousProxy for KeyboardSynchronousProxy {
552    type Proxy = KeyboardProxy;
553    type Protocol = KeyboardMarker;
554
555    fn from_channel(inner: fidl::Channel) -> Self {
556        Self::new(inner)
557    }
558
559    fn into_channel(self) -> fidl::Channel {
560        self.client.into_channel()
561    }
562
563    fn as_channel(&self) -> &fidl::Channel {
564        self.client.as_channel()
565    }
566}
567
568#[cfg(target_os = "fuchsia")]
569impl KeyboardSynchronousProxy {
570    pub fn new(channel: fidl::Channel) -> Self {
571        Self { client: fidl::client::sync::Client::new(channel) }
572    }
573
574    pub fn into_channel(self) -> fidl::Channel {
575        self.client.into_channel()
576    }
577
578    /// Waits until an event arrives and returns it. It is safe for other
579    /// threads to make concurrent requests while waiting for an event.
580    pub fn wait_for_event(
581        &self,
582        deadline: zx::MonotonicInstant,
583    ) -> Result<KeyboardEvent, fidl::Error> {
584        KeyboardEvent::decode(self.client.wait_for_event::<KeyboardMarker>(deadline)?)
585    }
586
587    /// Add a key event listener for the specified View.
588    /// If multiple listeners are added, each will receive key events independently and
589    /// should respond with a `Status`.
590    ///
591    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
592    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
593    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
594    pub fn r#add_listener(
595        &self,
596        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
597        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
598        ___deadline: zx::MonotonicInstant,
599    ) -> Result<(), fidl::Error> {
600        let _response = self
601            .client
602            .send_query::<KeyboardAddListenerRequest, fidl::encoding::EmptyPayload, KeyboardMarker>(
603                (&mut view_ref, listener),
604                0x3bc57587fc9b3d22,
605                fidl::encoding::DynamicFlags::empty(),
606                ___deadline,
607            )?;
608        Ok(_response)
609    }
610}
611
612#[cfg(target_os = "fuchsia")]
613impl From<KeyboardSynchronousProxy> for zx::NullableHandle {
614    fn from(value: KeyboardSynchronousProxy) -> Self {
615        value.into_channel().into()
616    }
617}
618
619#[cfg(target_os = "fuchsia")]
620impl From<fidl::Channel> for KeyboardSynchronousProxy {
621    fn from(value: fidl::Channel) -> Self {
622        Self::new(value)
623    }
624}
625
626#[cfg(target_os = "fuchsia")]
627impl fidl::endpoints::FromClient for KeyboardSynchronousProxy {
628    type Protocol = KeyboardMarker;
629
630    fn from_client(value: fidl::endpoints::ClientEnd<KeyboardMarker>) -> Self {
631        Self::new(value.into_channel())
632    }
633}
634
635#[derive(Debug, Clone)]
636pub struct KeyboardProxy {
637    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
638}
639
640impl fidl::endpoints::Proxy for KeyboardProxy {
641    type Protocol = KeyboardMarker;
642
643    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
644        Self::new(inner)
645    }
646
647    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
648        self.client.into_channel().map_err(|client| Self { client })
649    }
650
651    fn as_channel(&self) -> &::fidl::AsyncChannel {
652        self.client.as_channel()
653    }
654}
655
656impl KeyboardProxy {
657    /// Create a new Proxy for fuchsia.ui.input3/Keyboard.
658    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
659        let protocol_name = <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
660        Self { client: fidl::client::Client::new(channel, protocol_name) }
661    }
662
663    /// Get a Stream of events from the remote end of the protocol.
664    ///
665    /// # Panics
666    ///
667    /// Panics if the event stream was already taken.
668    pub fn take_event_stream(&self) -> KeyboardEventStream {
669        KeyboardEventStream { event_receiver: self.client.take_event_receiver() }
670    }
671
672    /// Add a key event listener for the specified View.
673    /// If multiple listeners are added, each will receive key events independently and
674    /// should respond with a `Status`.
675    ///
676    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
677    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
678    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
679    pub fn r#add_listener(
680        &self,
681        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
682        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
683    ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
684        KeyboardProxyInterface::r#add_listener(self, view_ref, listener)
685    }
686}
687
688impl KeyboardProxyInterface for KeyboardProxy {
689    type AddListenerResponseFut =
690        fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
691    fn r#add_listener(
692        &self,
693        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
694        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
695    ) -> Self::AddListenerResponseFut {
696        fn _decode(
697            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
698        ) -> Result<(), fidl::Error> {
699            let _response = fidl::client::decode_transaction_body::<
700                fidl::encoding::EmptyPayload,
701                fidl::encoding::DefaultFuchsiaResourceDialect,
702                0x3bc57587fc9b3d22,
703            >(_buf?)?;
704            Ok(_response)
705        }
706        self.client.send_query_and_decode::<KeyboardAddListenerRequest, ()>(
707            (&mut view_ref, listener),
708            0x3bc57587fc9b3d22,
709            fidl::encoding::DynamicFlags::empty(),
710            _decode,
711        )
712    }
713}
714
715pub struct KeyboardEventStream {
716    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
717}
718
719impl std::marker::Unpin for KeyboardEventStream {}
720
721impl futures::stream::FusedStream for KeyboardEventStream {
722    fn is_terminated(&self) -> bool {
723        self.event_receiver.is_terminated()
724    }
725}
726
727impl futures::Stream for KeyboardEventStream {
728    type Item = Result<KeyboardEvent, fidl::Error>;
729
730    fn poll_next(
731        mut self: std::pin::Pin<&mut Self>,
732        cx: &mut std::task::Context<'_>,
733    ) -> std::task::Poll<Option<Self::Item>> {
734        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
735            &mut self.event_receiver,
736            cx
737        )?) {
738            Some(buf) => std::task::Poll::Ready(Some(KeyboardEvent::decode(buf))),
739            None => std::task::Poll::Ready(None),
740        }
741    }
742}
743
744#[derive(Debug)]
745pub enum KeyboardEvent {}
746
747impl KeyboardEvent {
748    /// Decodes a message buffer as a [`KeyboardEvent`].
749    fn decode(
750        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
751    ) -> Result<KeyboardEvent, fidl::Error> {
752        let (bytes, _handles) = buf.split_mut();
753        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
754        debug_assert_eq!(tx_header.tx_id, 0);
755        match tx_header.ordinal {
756            _ => Err(fidl::Error::UnknownOrdinal {
757                ordinal: tx_header.ordinal,
758                protocol_name: <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
759            }),
760        }
761    }
762}
763
764/// A Stream of incoming requests for fuchsia.ui.input3/Keyboard.
765pub struct KeyboardRequestStream {
766    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
767    is_terminated: bool,
768}
769
770impl std::marker::Unpin for KeyboardRequestStream {}
771
772impl futures::stream::FusedStream for KeyboardRequestStream {
773    fn is_terminated(&self) -> bool {
774        self.is_terminated
775    }
776}
777
778impl fidl::endpoints::RequestStream for KeyboardRequestStream {
779    type Protocol = KeyboardMarker;
780    type ControlHandle = KeyboardControlHandle;
781
782    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
783        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
784    }
785
786    fn control_handle(&self) -> Self::ControlHandle {
787        KeyboardControlHandle { inner: self.inner.clone() }
788    }
789
790    fn into_inner(
791        self,
792    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
793    {
794        (self.inner, self.is_terminated)
795    }
796
797    fn from_inner(
798        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
799        is_terminated: bool,
800    ) -> Self {
801        Self { inner, is_terminated }
802    }
803}
804
805impl futures::Stream for KeyboardRequestStream {
806    type Item = Result<KeyboardRequest, fidl::Error>;
807
808    fn poll_next(
809        mut self: std::pin::Pin<&mut Self>,
810        cx: &mut std::task::Context<'_>,
811    ) -> std::task::Poll<Option<Self::Item>> {
812        let this = &mut *self;
813        if this.inner.check_shutdown(cx) {
814            this.is_terminated = true;
815            return std::task::Poll::Ready(None);
816        }
817        if this.is_terminated {
818            panic!("polled KeyboardRequestStream after completion");
819        }
820        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
821            |bytes, handles| {
822                match this.inner.channel().read_etc(cx, bytes, handles) {
823                    std::task::Poll::Ready(Ok(())) => {}
824                    std::task::Poll::Pending => return std::task::Poll::Pending,
825                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
826                        this.is_terminated = true;
827                        return std::task::Poll::Ready(None);
828                    }
829                    std::task::Poll::Ready(Err(e)) => {
830                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
831                            e.into(),
832                        ))));
833                    }
834                }
835
836                // A message has been received from the channel
837                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
838
839                std::task::Poll::Ready(Some(match header.ordinal {
840                    0x3bc57587fc9b3d22 => {
841                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
842                        let mut req = fidl::new_empty!(
843                            KeyboardAddListenerRequest,
844                            fidl::encoding::DefaultFuchsiaResourceDialect
845                        );
846                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<KeyboardAddListenerRequest>(&header, _body_bytes, handles, &mut req)?;
847                        let control_handle = KeyboardControlHandle { inner: this.inner.clone() };
848                        Ok(KeyboardRequest::AddListener {
849                            view_ref: req.view_ref,
850                            listener: req.listener,
851
852                            responder: KeyboardAddListenerResponder {
853                                control_handle: std::mem::ManuallyDrop::new(control_handle),
854                                tx_id: header.tx_id,
855                            },
856                        })
857                    }
858                    _ => Err(fidl::Error::UnknownOrdinal {
859                        ordinal: header.ordinal,
860                        protocol_name:
861                            <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
862                    }),
863                }))
864            },
865        )
866    }
867}
868
869/// Components may request this service from their namespace to be notified of
870/// physical key events.
871#[derive(Debug)]
872pub enum KeyboardRequest {
873    /// Add a key event listener for the specified View.
874    /// If multiple listeners are added, each will receive key events independently and
875    /// should respond with a `Status`.
876    ///
877    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
878    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
879    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
880    AddListener {
881        view_ref: fidl_fuchsia_ui_views::ViewRef,
882        listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
883        responder: KeyboardAddListenerResponder,
884    },
885}
886
887impl KeyboardRequest {
888    #[allow(irrefutable_let_patterns)]
889    pub fn into_add_listener(
890        self,
891    ) -> Option<(
892        fidl_fuchsia_ui_views::ViewRef,
893        fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
894        KeyboardAddListenerResponder,
895    )> {
896        if let KeyboardRequest::AddListener { view_ref, listener, responder } = self {
897            Some((view_ref, listener, responder))
898        } else {
899            None
900        }
901    }
902
903    /// Name of the method defined in FIDL
904    pub fn method_name(&self) -> &'static str {
905        match *self {
906            KeyboardRequest::AddListener { .. } => "add_listener",
907        }
908    }
909}
910
911#[derive(Debug, Clone)]
912pub struct KeyboardControlHandle {
913    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
914}
915
916impl KeyboardControlHandle {
917    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
918        self.inner.shutdown_with_epitaph(status.into())
919    }
920}
921
922impl fidl::endpoints::ControlHandle for KeyboardControlHandle {
923    fn shutdown(&self) {
924        self.inner.shutdown()
925    }
926
927    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
928        self.inner.shutdown_with_epitaph(status)
929    }
930
931    fn is_closed(&self) -> bool {
932        self.inner.channel().is_closed()
933    }
934    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
935        self.inner.channel().on_closed()
936    }
937
938    #[cfg(target_os = "fuchsia")]
939    fn signal_peer(
940        &self,
941        clear_mask: zx::Signals,
942        set_mask: zx::Signals,
943    ) -> Result<(), zx_status::Status> {
944        use fidl::Peered;
945        self.inner.channel().signal_peer(clear_mask, set_mask)
946    }
947}
948
949impl KeyboardControlHandle {}
950
951#[must_use = "FIDL methods require a response to be sent"]
952#[derive(Debug)]
953pub struct KeyboardAddListenerResponder {
954    control_handle: std::mem::ManuallyDrop<KeyboardControlHandle>,
955    tx_id: u32,
956}
957
958/// Set the the channel to be shutdown (see [`KeyboardControlHandle::shutdown`])
959/// if the responder is dropped without sending a response, so that the client
960/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
961impl std::ops::Drop for KeyboardAddListenerResponder {
962    fn drop(&mut self) {
963        self.control_handle.shutdown();
964        // Safety: drops once, never accessed again
965        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
966    }
967}
968
969impl fidl::endpoints::Responder for KeyboardAddListenerResponder {
970    type ControlHandle = KeyboardControlHandle;
971
972    fn control_handle(&self) -> &KeyboardControlHandle {
973        &self.control_handle
974    }
975
976    fn drop_without_shutdown(mut self) {
977        // Safety: drops once, never accessed again due to mem::forget
978        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
979        // Prevent Drop from running (which would shut down the channel)
980        std::mem::forget(self);
981    }
982}
983
984impl KeyboardAddListenerResponder {
985    /// Sends a response to the FIDL transaction.
986    ///
987    /// Sets the channel to shutdown if an error occurs.
988    pub fn send(self) -> Result<(), fidl::Error> {
989        let _result = self.send_raw();
990        if _result.is_err() {
991            self.control_handle.shutdown();
992        }
993        self.drop_without_shutdown();
994        _result
995    }
996
997    /// Similar to "send" but does not shutdown the channel if an error occurs.
998    pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
999        let _result = self.send_raw();
1000        self.drop_without_shutdown();
1001        _result
1002    }
1003
1004    fn send_raw(&self) -> Result<(), fidl::Error> {
1005        self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
1006            (),
1007            self.tx_id,
1008            0x3bc57587fc9b3d22,
1009            fidl::encoding::DynamicFlags::empty(),
1010        )
1011    }
1012}
1013
1014#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1015pub struct KeyboardListenerMarker;
1016
1017impl fidl::endpoints::ProtocolMarker for KeyboardListenerMarker {
1018    type Proxy = KeyboardListenerProxy;
1019    type RequestStream = KeyboardListenerRequestStream;
1020    #[cfg(target_os = "fuchsia")]
1021    type SynchronousProxy = KeyboardListenerSynchronousProxy;
1022
1023    const DEBUG_NAME: &'static str = "(anonymous) KeyboardListener";
1024}
1025
1026pub trait KeyboardListenerProxyInterface: Send + Sync {
1027    type OnKeyEventResponseFut: std::future::Future<Output = Result<KeyEventStatus, fidl::Error>>
1028        + Send;
1029    fn r#on_key_event(&self, event: &KeyEvent) -> Self::OnKeyEventResponseFut;
1030}
1031#[derive(Debug)]
1032#[cfg(target_os = "fuchsia")]
1033pub struct KeyboardListenerSynchronousProxy {
1034    client: fidl::client::sync::Client,
1035}
1036
1037#[cfg(target_os = "fuchsia")]
1038impl fidl::endpoints::SynchronousProxy for KeyboardListenerSynchronousProxy {
1039    type Proxy = KeyboardListenerProxy;
1040    type Protocol = KeyboardListenerMarker;
1041
1042    fn from_channel(inner: fidl::Channel) -> Self {
1043        Self::new(inner)
1044    }
1045
1046    fn into_channel(self) -> fidl::Channel {
1047        self.client.into_channel()
1048    }
1049
1050    fn as_channel(&self) -> &fidl::Channel {
1051        self.client.as_channel()
1052    }
1053}
1054
1055#[cfg(target_os = "fuchsia")]
1056impl KeyboardListenerSynchronousProxy {
1057    pub fn new(channel: fidl::Channel) -> Self {
1058        Self { client: fidl::client::sync::Client::new(channel) }
1059    }
1060
1061    pub fn into_channel(self) -> fidl::Channel {
1062        self.client.into_channel()
1063    }
1064
1065    /// Waits until an event arrives and returns it. It is safe for other
1066    /// threads to make concurrent requests while waiting for an event.
1067    pub fn wait_for_event(
1068        &self,
1069        deadline: zx::MonotonicInstant,
1070    ) -> Result<KeyboardListenerEvent, fidl::Error> {
1071        KeyboardListenerEvent::decode(
1072            self.client.wait_for_event::<KeyboardListenerMarker>(deadline)?,
1073        )
1074    }
1075
1076    /// Called when a key event takes place, such as key press or release.
1077    ///
1078    /// Protocol implementers must respond to acknowledge the event by returning Status
1079    /// in a timely manner, i.e. not introducing significant delays to the
1080    /// input pipeline (typically 10s of milliseconds).
1081    ///
1082    /// Returning `NOT_HANDLED` means the event may be offered to other
1083    /// clients of other related APIs.
1084    ///
1085    /// Clients that do not acknowledge their events will eventually be disconnected.
1086    ///
1087    /// Notification is only dispatched to a view that has focus. No other views,
1088    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1089    pub fn r#on_key_event(
1090        &self,
1091        mut event: &KeyEvent,
1092        ___deadline: zx::MonotonicInstant,
1093    ) -> Result<KeyEventStatus, fidl::Error> {
1094        let _response = self.client.send_query::<
1095            KeyboardListenerOnKeyEventRequest,
1096            KeyboardListenerOnKeyEventResponse,
1097            KeyboardListenerMarker,
1098        >(
1099            (event,),
1100            0x2ef2ee16ac509093,
1101            fidl::encoding::DynamicFlags::empty(),
1102            ___deadline,
1103        )?;
1104        Ok(_response.status)
1105    }
1106}
1107
1108#[cfg(target_os = "fuchsia")]
1109impl From<KeyboardListenerSynchronousProxy> for zx::NullableHandle {
1110    fn from(value: KeyboardListenerSynchronousProxy) -> Self {
1111        value.into_channel().into()
1112    }
1113}
1114
1115#[cfg(target_os = "fuchsia")]
1116impl From<fidl::Channel> for KeyboardListenerSynchronousProxy {
1117    fn from(value: fidl::Channel) -> Self {
1118        Self::new(value)
1119    }
1120}
1121
1122#[cfg(target_os = "fuchsia")]
1123impl fidl::endpoints::FromClient for KeyboardListenerSynchronousProxy {
1124    type Protocol = KeyboardListenerMarker;
1125
1126    fn from_client(value: fidl::endpoints::ClientEnd<KeyboardListenerMarker>) -> Self {
1127        Self::new(value.into_channel())
1128    }
1129}
1130
1131#[derive(Debug, Clone)]
1132pub struct KeyboardListenerProxy {
1133    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
1134}
1135
1136impl fidl::endpoints::Proxy for KeyboardListenerProxy {
1137    type Protocol = KeyboardListenerMarker;
1138
1139    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
1140        Self::new(inner)
1141    }
1142
1143    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
1144        self.client.into_channel().map_err(|client| Self { client })
1145    }
1146
1147    fn as_channel(&self) -> &::fidl::AsyncChannel {
1148        self.client.as_channel()
1149    }
1150}
1151
1152impl KeyboardListenerProxy {
1153    /// Create a new Proxy for fuchsia.ui.input3/KeyboardListener.
1154    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
1155        let protocol_name = <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1156        Self { client: fidl::client::Client::new(channel, protocol_name) }
1157    }
1158
1159    /// Get a Stream of events from the remote end of the protocol.
1160    ///
1161    /// # Panics
1162    ///
1163    /// Panics if the event stream was already taken.
1164    pub fn take_event_stream(&self) -> KeyboardListenerEventStream {
1165        KeyboardListenerEventStream { event_receiver: self.client.take_event_receiver() }
1166    }
1167
1168    /// Called when a key event takes place, such as key press or release.
1169    ///
1170    /// Protocol implementers must respond to acknowledge the event by returning Status
1171    /// in a timely manner, i.e. not introducing significant delays to the
1172    /// input pipeline (typically 10s of milliseconds).
1173    ///
1174    /// Returning `NOT_HANDLED` means the event may be offered to other
1175    /// clients of other related APIs.
1176    ///
1177    /// Clients that do not acknowledge their events will eventually be disconnected.
1178    ///
1179    /// Notification is only dispatched to a view that has focus. No other views,
1180    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1181    pub fn r#on_key_event(
1182        &self,
1183        mut event: &KeyEvent,
1184    ) -> fidl::client::QueryResponseFut<KeyEventStatus, fidl::encoding::DefaultFuchsiaResourceDialect>
1185    {
1186        KeyboardListenerProxyInterface::r#on_key_event(self, event)
1187    }
1188}
1189
1190impl KeyboardListenerProxyInterface for KeyboardListenerProxy {
1191    type OnKeyEventResponseFut = fidl::client::QueryResponseFut<
1192        KeyEventStatus,
1193        fidl::encoding::DefaultFuchsiaResourceDialect,
1194    >;
1195    fn r#on_key_event(&self, mut event: &KeyEvent) -> Self::OnKeyEventResponseFut {
1196        fn _decode(
1197            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1198        ) -> Result<KeyEventStatus, fidl::Error> {
1199            let _response = fidl::client::decode_transaction_body::<
1200                KeyboardListenerOnKeyEventResponse,
1201                fidl::encoding::DefaultFuchsiaResourceDialect,
1202                0x2ef2ee16ac509093,
1203            >(_buf?)?;
1204            Ok(_response.status)
1205        }
1206        self.client.send_query_and_decode::<KeyboardListenerOnKeyEventRequest, KeyEventStatus>(
1207            (event,),
1208            0x2ef2ee16ac509093,
1209            fidl::encoding::DynamicFlags::empty(),
1210            _decode,
1211        )
1212    }
1213}
1214
1215pub struct KeyboardListenerEventStream {
1216    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
1217}
1218
1219impl std::marker::Unpin for KeyboardListenerEventStream {}
1220
1221impl futures::stream::FusedStream for KeyboardListenerEventStream {
1222    fn is_terminated(&self) -> bool {
1223        self.event_receiver.is_terminated()
1224    }
1225}
1226
1227impl futures::Stream for KeyboardListenerEventStream {
1228    type Item = Result<KeyboardListenerEvent, fidl::Error>;
1229
1230    fn poll_next(
1231        mut self: std::pin::Pin<&mut Self>,
1232        cx: &mut std::task::Context<'_>,
1233    ) -> std::task::Poll<Option<Self::Item>> {
1234        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
1235            &mut self.event_receiver,
1236            cx
1237        )?) {
1238            Some(buf) => std::task::Poll::Ready(Some(KeyboardListenerEvent::decode(buf))),
1239            None => std::task::Poll::Ready(None),
1240        }
1241    }
1242}
1243
1244#[derive(Debug)]
1245pub enum KeyboardListenerEvent {}
1246
1247impl KeyboardListenerEvent {
1248    /// Decodes a message buffer as a [`KeyboardListenerEvent`].
1249    fn decode(
1250        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
1251    ) -> Result<KeyboardListenerEvent, fidl::Error> {
1252        let (bytes, _handles) = buf.split_mut();
1253        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1254        debug_assert_eq!(tx_header.tx_id, 0);
1255        match tx_header.ordinal {
1256            _ => Err(fidl::Error::UnknownOrdinal {
1257                ordinal: tx_header.ordinal,
1258                protocol_name:
1259                    <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1260            }),
1261        }
1262    }
1263}
1264
1265/// A Stream of incoming requests for fuchsia.ui.input3/KeyboardListener.
1266pub struct KeyboardListenerRequestStream {
1267    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1268    is_terminated: bool,
1269}
1270
1271impl std::marker::Unpin for KeyboardListenerRequestStream {}
1272
1273impl futures::stream::FusedStream for KeyboardListenerRequestStream {
1274    fn is_terminated(&self) -> bool {
1275        self.is_terminated
1276    }
1277}
1278
1279impl fidl::endpoints::RequestStream for KeyboardListenerRequestStream {
1280    type Protocol = KeyboardListenerMarker;
1281    type ControlHandle = KeyboardListenerControlHandle;
1282
1283    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
1284        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
1285    }
1286
1287    fn control_handle(&self) -> Self::ControlHandle {
1288        KeyboardListenerControlHandle { inner: self.inner.clone() }
1289    }
1290
1291    fn into_inner(
1292        self,
1293    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
1294    {
1295        (self.inner, self.is_terminated)
1296    }
1297
1298    fn from_inner(
1299        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1300        is_terminated: bool,
1301    ) -> Self {
1302        Self { inner, is_terminated }
1303    }
1304}
1305
1306impl futures::Stream for KeyboardListenerRequestStream {
1307    type Item = Result<KeyboardListenerRequest, fidl::Error>;
1308
1309    fn poll_next(
1310        mut self: std::pin::Pin<&mut Self>,
1311        cx: &mut std::task::Context<'_>,
1312    ) -> std::task::Poll<Option<Self::Item>> {
1313        let this = &mut *self;
1314        if this.inner.check_shutdown(cx) {
1315            this.is_terminated = true;
1316            return std::task::Poll::Ready(None);
1317        }
1318        if this.is_terminated {
1319            panic!("polled KeyboardListenerRequestStream after completion");
1320        }
1321        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
1322            |bytes, handles| {
1323                match this.inner.channel().read_etc(cx, bytes, handles) {
1324                    std::task::Poll::Ready(Ok(())) => {}
1325                    std::task::Poll::Pending => return std::task::Poll::Pending,
1326                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
1327                        this.is_terminated = true;
1328                        return std::task::Poll::Ready(None);
1329                    }
1330                    std::task::Poll::Ready(Err(e)) => {
1331                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
1332                            e.into(),
1333                        ))));
1334                    }
1335                }
1336
1337                // A message has been received from the channel
1338                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1339
1340                std::task::Poll::Ready(Some(match header.ordinal {
1341                    0x2ef2ee16ac509093 => {
1342                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1343                        let mut req = fidl::new_empty!(
1344                            KeyboardListenerOnKeyEventRequest,
1345                            fidl::encoding::DefaultFuchsiaResourceDialect
1346                        );
1347                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<KeyboardListenerOnKeyEventRequest>(&header, _body_bytes, handles, &mut req)?;
1348                        let control_handle =
1349                            KeyboardListenerControlHandle { inner: this.inner.clone() };
1350                        Ok(KeyboardListenerRequest::OnKeyEvent {
1351                            event: req.event,
1352
1353                            responder: KeyboardListenerOnKeyEventResponder {
1354                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1355                                tx_id: header.tx_id,
1356                            },
1357                        })
1358                    }
1359                    _ => Err(fidl::Error::UnknownOrdinal {
1360                        ordinal: header.ordinal,
1361                        protocol_name:
1362                            <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1363                    }),
1364                }))
1365            },
1366        )
1367    }
1368}
1369
1370/// Client should implement this protocol to get notified of key events.
1371#[derive(Debug)]
1372pub enum KeyboardListenerRequest {
1373    /// Called when a key event takes place, such as key press or release.
1374    ///
1375    /// Protocol implementers must respond to acknowledge the event by returning Status
1376    /// in a timely manner, i.e. not introducing significant delays to the
1377    /// input pipeline (typically 10s of milliseconds).
1378    ///
1379    /// Returning `NOT_HANDLED` means the event may be offered to other
1380    /// clients of other related APIs.
1381    ///
1382    /// Clients that do not acknowledge their events will eventually be disconnected.
1383    ///
1384    /// Notification is only dispatched to a view that has focus. No other views,
1385    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1386    OnKeyEvent { event: KeyEvent, responder: KeyboardListenerOnKeyEventResponder },
1387}
1388
1389impl KeyboardListenerRequest {
1390    #[allow(irrefutable_let_patterns)]
1391    pub fn into_on_key_event(self) -> Option<(KeyEvent, KeyboardListenerOnKeyEventResponder)> {
1392        if let KeyboardListenerRequest::OnKeyEvent { event, responder } = self {
1393            Some((event, responder))
1394        } else {
1395            None
1396        }
1397    }
1398
1399    /// Name of the method defined in FIDL
1400    pub fn method_name(&self) -> &'static str {
1401        match *self {
1402            KeyboardListenerRequest::OnKeyEvent { .. } => "on_key_event",
1403        }
1404    }
1405}
1406
1407#[derive(Debug, Clone)]
1408pub struct KeyboardListenerControlHandle {
1409    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1410}
1411
1412impl KeyboardListenerControlHandle {
1413    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
1414        self.inner.shutdown_with_epitaph(status.into())
1415    }
1416}
1417
1418impl fidl::endpoints::ControlHandle for KeyboardListenerControlHandle {
1419    fn shutdown(&self) {
1420        self.inner.shutdown()
1421    }
1422
1423    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
1424        self.inner.shutdown_with_epitaph(status)
1425    }
1426
1427    fn is_closed(&self) -> bool {
1428        self.inner.channel().is_closed()
1429    }
1430    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1431        self.inner.channel().on_closed()
1432    }
1433
1434    #[cfg(target_os = "fuchsia")]
1435    fn signal_peer(
1436        &self,
1437        clear_mask: zx::Signals,
1438        set_mask: zx::Signals,
1439    ) -> Result<(), zx_status::Status> {
1440        use fidl::Peered;
1441        self.inner.channel().signal_peer(clear_mask, set_mask)
1442    }
1443}
1444
1445impl KeyboardListenerControlHandle {}
1446
1447#[must_use = "FIDL methods require a response to be sent"]
1448#[derive(Debug)]
1449pub struct KeyboardListenerOnKeyEventResponder {
1450    control_handle: std::mem::ManuallyDrop<KeyboardListenerControlHandle>,
1451    tx_id: u32,
1452}
1453
1454/// Set the the channel to be shutdown (see [`KeyboardListenerControlHandle::shutdown`])
1455/// if the responder is dropped without sending a response, so that the client
1456/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1457impl std::ops::Drop for KeyboardListenerOnKeyEventResponder {
1458    fn drop(&mut self) {
1459        self.control_handle.shutdown();
1460        // Safety: drops once, never accessed again
1461        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1462    }
1463}
1464
1465impl fidl::endpoints::Responder for KeyboardListenerOnKeyEventResponder {
1466    type ControlHandle = KeyboardListenerControlHandle;
1467
1468    fn control_handle(&self) -> &KeyboardListenerControlHandle {
1469        &self.control_handle
1470    }
1471
1472    fn drop_without_shutdown(mut self) {
1473        // Safety: drops once, never accessed again due to mem::forget
1474        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1475        // Prevent Drop from running (which would shut down the channel)
1476        std::mem::forget(self);
1477    }
1478}
1479
1480impl KeyboardListenerOnKeyEventResponder {
1481    /// Sends a response to the FIDL transaction.
1482    ///
1483    /// Sets the channel to shutdown if an error occurs.
1484    pub fn send(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1485        let _result = self.send_raw(status);
1486        if _result.is_err() {
1487            self.control_handle.shutdown();
1488        }
1489        self.drop_without_shutdown();
1490        _result
1491    }
1492
1493    /// Similar to "send" but does not shutdown the channel if an error occurs.
1494    pub fn send_no_shutdown_on_err(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1495        let _result = self.send_raw(status);
1496        self.drop_without_shutdown();
1497        _result
1498    }
1499
1500    fn send_raw(&self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1501        self.control_handle.inner.send::<KeyboardListenerOnKeyEventResponse>(
1502            (status,),
1503            self.tx_id,
1504            0x2ef2ee16ac509093,
1505            fidl::encoding::DynamicFlags::empty(),
1506        )
1507    }
1508}
1509
1510mod internal {
1511    use super::*;
1512
1513    impl fidl::encoding::ResourceTypeMarker for KeyboardAddListenerRequest {
1514        type Borrowed<'a> = &'a mut Self;
1515        fn take_or_borrow<'a>(
1516            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1517        ) -> Self::Borrowed<'a> {
1518            value
1519        }
1520    }
1521
1522    unsafe impl fidl::encoding::TypeMarker for KeyboardAddListenerRequest {
1523        type Owned = Self;
1524
1525        #[inline(always)]
1526        fn inline_align(_context: fidl::encoding::Context) -> usize {
1527            4
1528        }
1529
1530        #[inline(always)]
1531        fn inline_size(_context: fidl::encoding::Context) -> usize {
1532            8
1533        }
1534    }
1535
1536    unsafe impl
1537        fidl::encoding::Encode<
1538            KeyboardAddListenerRequest,
1539            fidl::encoding::DefaultFuchsiaResourceDialect,
1540        > for &mut KeyboardAddListenerRequest
1541    {
1542        #[inline]
1543        unsafe fn encode(
1544            self,
1545            encoder: &mut fidl::encoding::Encoder<
1546                '_,
1547                fidl::encoding::DefaultFuchsiaResourceDialect,
1548            >,
1549            offset: usize,
1550            _depth: fidl::encoding::Depth,
1551        ) -> fidl::Result<()> {
1552            encoder.debug_check_bounds::<KeyboardAddListenerRequest>(offset);
1553            // Delegate to tuple encoding.
1554            fidl::encoding::Encode::<KeyboardAddListenerRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
1555                (
1556                    <fidl_fuchsia_ui_views::ViewRef as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.view_ref),
1557                    <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.listener),
1558                ),
1559                encoder, offset, _depth
1560            )
1561        }
1562    }
1563    unsafe impl<
1564        T0: fidl::encoding::Encode<
1565                fidl_fuchsia_ui_views::ViewRef,
1566                fidl::encoding::DefaultFuchsiaResourceDialect,
1567            >,
1568        T1: fidl::encoding::Encode<
1569                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1570                fidl::encoding::DefaultFuchsiaResourceDialect,
1571            >,
1572    >
1573        fidl::encoding::Encode<
1574            KeyboardAddListenerRequest,
1575            fidl::encoding::DefaultFuchsiaResourceDialect,
1576        > for (T0, T1)
1577    {
1578        #[inline]
1579        unsafe fn encode(
1580            self,
1581            encoder: &mut fidl::encoding::Encoder<
1582                '_,
1583                fidl::encoding::DefaultFuchsiaResourceDialect,
1584            >,
1585            offset: usize,
1586            depth: fidl::encoding::Depth,
1587        ) -> fidl::Result<()> {
1588            encoder.debug_check_bounds::<KeyboardAddListenerRequest>(offset);
1589            // Zero out padding regions. There's no need to apply masks
1590            // because the unmasked parts will be overwritten by fields.
1591            // Write the fields.
1592            self.0.encode(encoder, offset + 0, depth)?;
1593            self.1.encode(encoder, offset + 4, depth)?;
1594            Ok(())
1595        }
1596    }
1597
1598    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1599        for KeyboardAddListenerRequest
1600    {
1601        #[inline(always)]
1602        fn new_empty() -> Self {
1603            Self {
1604                view_ref: fidl::new_empty!(
1605                    fidl_fuchsia_ui_views::ViewRef,
1606                    fidl::encoding::DefaultFuchsiaResourceDialect
1607                ),
1608                listener: fidl::new_empty!(
1609                    fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1610                    fidl::encoding::DefaultFuchsiaResourceDialect
1611                ),
1612            }
1613        }
1614
1615        #[inline]
1616        unsafe fn decode(
1617            &mut self,
1618            decoder: &mut fidl::encoding::Decoder<
1619                '_,
1620                fidl::encoding::DefaultFuchsiaResourceDialect,
1621            >,
1622            offset: usize,
1623            _depth: fidl::encoding::Depth,
1624        ) -> fidl::Result<()> {
1625            decoder.debug_check_bounds::<Self>(offset);
1626            // Verify that padding bytes are zero.
1627            fidl::decode!(
1628                fidl_fuchsia_ui_views::ViewRef,
1629                fidl::encoding::DefaultFuchsiaResourceDialect,
1630                &mut self.view_ref,
1631                decoder,
1632                offset + 0,
1633                _depth
1634            )?;
1635            fidl::decode!(
1636                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1637                fidl::encoding::DefaultFuchsiaResourceDialect,
1638                &mut self.listener,
1639                decoder,
1640                offset + 4,
1641                _depth
1642            )?;
1643            Ok(())
1644        }
1645    }
1646}