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 fidl::endpoints::ControlHandle for KeyEventInjectorControlHandle {
426    fn shutdown(&self) {
427        self.inner.shutdown()
428    }
429
430    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
431        self.inner.shutdown_with_epitaph(status)
432    }
433
434    fn is_closed(&self) -> bool {
435        self.inner.channel().is_closed()
436    }
437    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
438        self.inner.channel().on_closed()
439    }
440
441    #[cfg(target_os = "fuchsia")]
442    fn signal_peer(
443        &self,
444        clear_mask: zx::Signals,
445        set_mask: zx::Signals,
446    ) -> Result<(), zx_status::Status> {
447        use fidl::Peered;
448        self.inner.channel().signal_peer(clear_mask, set_mask)
449    }
450}
451
452impl KeyEventInjectorControlHandle {}
453
454#[must_use = "FIDL methods require a response to be sent"]
455#[derive(Debug)]
456pub struct KeyEventInjectorInjectResponder {
457    control_handle: std::mem::ManuallyDrop<KeyEventInjectorControlHandle>,
458    tx_id: u32,
459}
460
461/// Set the the channel to be shutdown (see [`KeyEventInjectorControlHandle::shutdown`])
462/// if the responder is dropped without sending a response, so that the client
463/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
464impl std::ops::Drop for KeyEventInjectorInjectResponder {
465    fn drop(&mut self) {
466        self.control_handle.shutdown();
467        // Safety: drops once, never accessed again
468        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
469    }
470}
471
472impl fidl::endpoints::Responder for KeyEventInjectorInjectResponder {
473    type ControlHandle = KeyEventInjectorControlHandle;
474
475    fn control_handle(&self) -> &KeyEventInjectorControlHandle {
476        &self.control_handle
477    }
478
479    fn drop_without_shutdown(mut self) {
480        // Safety: drops once, never accessed again due to mem::forget
481        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
482        // Prevent Drop from running (which would shut down the channel)
483        std::mem::forget(self);
484    }
485}
486
487impl KeyEventInjectorInjectResponder {
488    /// Sends a response to the FIDL transaction.
489    ///
490    /// Sets the channel to shutdown if an error occurs.
491    pub fn send(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
492        let _result = self.send_raw(status);
493        if _result.is_err() {
494            self.control_handle.shutdown();
495        }
496        self.drop_without_shutdown();
497        _result
498    }
499
500    /// Similar to "send" but does not shutdown the channel if an error occurs.
501    pub fn send_no_shutdown_on_err(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
502        let _result = self.send_raw(status);
503        self.drop_without_shutdown();
504        _result
505    }
506
507    fn send_raw(&self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
508        self.control_handle.inner.send::<KeyEventInjectorInjectResponse>(
509            (status,),
510            self.tx_id,
511            0x1eb2c0d795c68949,
512            fidl::encoding::DynamicFlags::empty(),
513        )
514    }
515}
516
517#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
518pub struct KeyboardMarker;
519
520impl fidl::endpoints::ProtocolMarker for KeyboardMarker {
521    type Proxy = KeyboardProxy;
522    type RequestStream = KeyboardRequestStream;
523    #[cfg(target_os = "fuchsia")]
524    type SynchronousProxy = KeyboardSynchronousProxy;
525
526    const DEBUG_NAME: &'static str = "fuchsia.ui.input3.Keyboard";
527}
528impl fidl::endpoints::DiscoverableProtocolMarker for KeyboardMarker {}
529
530pub trait KeyboardProxyInterface: Send + Sync {
531    type AddListenerResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
532    fn r#add_listener(
533        &self,
534        view_ref: fidl_fuchsia_ui_views::ViewRef,
535        listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
536    ) -> Self::AddListenerResponseFut;
537}
538#[derive(Debug)]
539#[cfg(target_os = "fuchsia")]
540pub struct KeyboardSynchronousProxy {
541    client: fidl::client::sync::Client,
542}
543
544#[cfg(target_os = "fuchsia")]
545impl fidl::endpoints::SynchronousProxy for KeyboardSynchronousProxy {
546    type Proxy = KeyboardProxy;
547    type Protocol = KeyboardMarker;
548
549    fn from_channel(inner: fidl::Channel) -> Self {
550        Self::new(inner)
551    }
552
553    fn into_channel(self) -> fidl::Channel {
554        self.client.into_channel()
555    }
556
557    fn as_channel(&self) -> &fidl::Channel {
558        self.client.as_channel()
559    }
560}
561
562#[cfg(target_os = "fuchsia")]
563impl KeyboardSynchronousProxy {
564    pub fn new(channel: fidl::Channel) -> Self {
565        Self { client: fidl::client::sync::Client::new(channel) }
566    }
567
568    pub fn into_channel(self) -> fidl::Channel {
569        self.client.into_channel()
570    }
571
572    /// Waits until an event arrives and returns it. It is safe for other
573    /// threads to make concurrent requests while waiting for an event.
574    pub fn wait_for_event(
575        &self,
576        deadline: zx::MonotonicInstant,
577    ) -> Result<KeyboardEvent, fidl::Error> {
578        KeyboardEvent::decode(self.client.wait_for_event::<KeyboardMarker>(deadline)?)
579    }
580
581    /// Add a key event listener for the specified View.
582    /// If multiple listeners are added, each will receive key events independently and
583    /// should respond with a `Status`.
584    ///
585    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
586    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
587    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
588    pub fn r#add_listener(
589        &self,
590        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
591        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
592        ___deadline: zx::MonotonicInstant,
593    ) -> Result<(), fidl::Error> {
594        let _response = self
595            .client
596            .send_query::<KeyboardAddListenerRequest, fidl::encoding::EmptyPayload, KeyboardMarker>(
597                (&mut view_ref, listener),
598                0x3bc57587fc9b3d22,
599                fidl::encoding::DynamicFlags::empty(),
600                ___deadline,
601            )?;
602        Ok(_response)
603    }
604}
605
606#[cfg(target_os = "fuchsia")]
607impl From<KeyboardSynchronousProxy> for zx::NullableHandle {
608    fn from(value: KeyboardSynchronousProxy) -> Self {
609        value.into_channel().into()
610    }
611}
612
613#[cfg(target_os = "fuchsia")]
614impl From<fidl::Channel> for KeyboardSynchronousProxy {
615    fn from(value: fidl::Channel) -> Self {
616        Self::new(value)
617    }
618}
619
620#[cfg(target_os = "fuchsia")]
621impl fidl::endpoints::FromClient for KeyboardSynchronousProxy {
622    type Protocol = KeyboardMarker;
623
624    fn from_client(value: fidl::endpoints::ClientEnd<KeyboardMarker>) -> Self {
625        Self::new(value.into_channel())
626    }
627}
628
629#[derive(Debug, Clone)]
630pub struct KeyboardProxy {
631    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
632}
633
634impl fidl::endpoints::Proxy for KeyboardProxy {
635    type Protocol = KeyboardMarker;
636
637    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
638        Self::new(inner)
639    }
640
641    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
642        self.client.into_channel().map_err(|client| Self { client })
643    }
644
645    fn as_channel(&self) -> &::fidl::AsyncChannel {
646        self.client.as_channel()
647    }
648}
649
650impl KeyboardProxy {
651    /// Create a new Proxy for fuchsia.ui.input3/Keyboard.
652    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
653        let protocol_name = <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
654        Self { client: fidl::client::Client::new(channel, protocol_name) }
655    }
656
657    /// Get a Stream of events from the remote end of the protocol.
658    ///
659    /// # Panics
660    ///
661    /// Panics if the event stream was already taken.
662    pub fn take_event_stream(&self) -> KeyboardEventStream {
663        KeyboardEventStream { event_receiver: self.client.take_event_receiver() }
664    }
665
666    /// Add a key event listener for the specified View.
667    /// If multiple listeners are added, each will receive key events independently and
668    /// should respond with a `Status`.
669    ///
670    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
671    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
672    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
673    pub fn r#add_listener(
674        &self,
675        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
676        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
677    ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
678        KeyboardProxyInterface::r#add_listener(self, view_ref, listener)
679    }
680}
681
682impl KeyboardProxyInterface for KeyboardProxy {
683    type AddListenerResponseFut =
684        fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
685    fn r#add_listener(
686        &self,
687        mut view_ref: fidl_fuchsia_ui_views::ViewRef,
688        mut listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
689    ) -> Self::AddListenerResponseFut {
690        fn _decode(
691            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
692        ) -> Result<(), fidl::Error> {
693            let _response = fidl::client::decode_transaction_body::<
694                fidl::encoding::EmptyPayload,
695                fidl::encoding::DefaultFuchsiaResourceDialect,
696                0x3bc57587fc9b3d22,
697            >(_buf?)?;
698            Ok(_response)
699        }
700        self.client.send_query_and_decode::<KeyboardAddListenerRequest, ()>(
701            (&mut view_ref, listener),
702            0x3bc57587fc9b3d22,
703            fidl::encoding::DynamicFlags::empty(),
704            _decode,
705        )
706    }
707}
708
709pub struct KeyboardEventStream {
710    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
711}
712
713impl std::marker::Unpin for KeyboardEventStream {}
714
715impl futures::stream::FusedStream for KeyboardEventStream {
716    fn is_terminated(&self) -> bool {
717        self.event_receiver.is_terminated()
718    }
719}
720
721impl futures::Stream for KeyboardEventStream {
722    type Item = Result<KeyboardEvent, fidl::Error>;
723
724    fn poll_next(
725        mut self: std::pin::Pin<&mut Self>,
726        cx: &mut std::task::Context<'_>,
727    ) -> std::task::Poll<Option<Self::Item>> {
728        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
729            &mut self.event_receiver,
730            cx
731        )?) {
732            Some(buf) => std::task::Poll::Ready(Some(KeyboardEvent::decode(buf))),
733            None => std::task::Poll::Ready(None),
734        }
735    }
736}
737
738#[derive(Debug)]
739pub enum KeyboardEvent {}
740
741impl KeyboardEvent {
742    /// Decodes a message buffer as a [`KeyboardEvent`].
743    fn decode(
744        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
745    ) -> Result<KeyboardEvent, fidl::Error> {
746        let (bytes, _handles) = buf.split_mut();
747        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
748        debug_assert_eq!(tx_header.tx_id, 0);
749        match tx_header.ordinal {
750            _ => Err(fidl::Error::UnknownOrdinal {
751                ordinal: tx_header.ordinal,
752                protocol_name: <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
753            }),
754        }
755    }
756}
757
758/// A Stream of incoming requests for fuchsia.ui.input3/Keyboard.
759pub struct KeyboardRequestStream {
760    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
761    is_terminated: bool,
762}
763
764impl std::marker::Unpin for KeyboardRequestStream {}
765
766impl futures::stream::FusedStream for KeyboardRequestStream {
767    fn is_terminated(&self) -> bool {
768        self.is_terminated
769    }
770}
771
772impl fidl::endpoints::RequestStream for KeyboardRequestStream {
773    type Protocol = KeyboardMarker;
774    type ControlHandle = KeyboardControlHandle;
775
776    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
777        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
778    }
779
780    fn control_handle(&self) -> Self::ControlHandle {
781        KeyboardControlHandle { inner: self.inner.clone() }
782    }
783
784    fn into_inner(
785        self,
786    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
787    {
788        (self.inner, self.is_terminated)
789    }
790
791    fn from_inner(
792        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
793        is_terminated: bool,
794    ) -> Self {
795        Self { inner, is_terminated }
796    }
797}
798
799impl futures::Stream for KeyboardRequestStream {
800    type Item = Result<KeyboardRequest, fidl::Error>;
801
802    fn poll_next(
803        mut self: std::pin::Pin<&mut Self>,
804        cx: &mut std::task::Context<'_>,
805    ) -> std::task::Poll<Option<Self::Item>> {
806        let this = &mut *self;
807        if this.inner.check_shutdown(cx) {
808            this.is_terminated = true;
809            return std::task::Poll::Ready(None);
810        }
811        if this.is_terminated {
812            panic!("polled KeyboardRequestStream after completion");
813        }
814        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
815            |bytes, handles| {
816                match this.inner.channel().read_etc(cx, bytes, handles) {
817                    std::task::Poll::Ready(Ok(())) => {}
818                    std::task::Poll::Pending => return std::task::Poll::Pending,
819                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
820                        this.is_terminated = true;
821                        return std::task::Poll::Ready(None);
822                    }
823                    std::task::Poll::Ready(Err(e)) => {
824                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
825                            e.into(),
826                        ))));
827                    }
828                }
829
830                // A message has been received from the channel
831                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
832
833                std::task::Poll::Ready(Some(match header.ordinal {
834                    0x3bc57587fc9b3d22 => {
835                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
836                        let mut req = fidl::new_empty!(
837                            KeyboardAddListenerRequest,
838                            fidl::encoding::DefaultFuchsiaResourceDialect
839                        );
840                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<KeyboardAddListenerRequest>(&header, _body_bytes, handles, &mut req)?;
841                        let control_handle = KeyboardControlHandle { inner: this.inner.clone() };
842                        Ok(KeyboardRequest::AddListener {
843                            view_ref: req.view_ref,
844                            listener: req.listener,
845
846                            responder: KeyboardAddListenerResponder {
847                                control_handle: std::mem::ManuallyDrop::new(control_handle),
848                                tx_id: header.tx_id,
849                            },
850                        })
851                    }
852                    _ => Err(fidl::Error::UnknownOrdinal {
853                        ordinal: header.ordinal,
854                        protocol_name:
855                            <KeyboardMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
856                    }),
857                }))
858            },
859        )
860    }
861}
862
863/// Components may request this service from their namespace to be notified of
864/// physical key events.
865#[derive(Debug)]
866pub enum KeyboardRequest {
867    /// Add a key event listener for the specified View.
868    /// If multiple listeners are added, each will receive key events independently and
869    /// should respond with a `Status`.
870    ///
871    /// The client calling `AddListener` should keep the connection to `Keyboard` alive
872    /// for as long as the events from `KeyboardListener` need to be received.  Dropping the
873    /// connection to the `Keyboard` protocol will terminate `KeyboardListener` as well.
874    AddListener {
875        view_ref: fidl_fuchsia_ui_views::ViewRef,
876        listener: fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
877        responder: KeyboardAddListenerResponder,
878    },
879}
880
881impl KeyboardRequest {
882    #[allow(irrefutable_let_patterns)]
883    pub fn into_add_listener(
884        self,
885    ) -> Option<(
886        fidl_fuchsia_ui_views::ViewRef,
887        fidl::endpoints::ClientEnd<KeyboardListenerMarker>,
888        KeyboardAddListenerResponder,
889    )> {
890        if let KeyboardRequest::AddListener { view_ref, listener, responder } = self {
891            Some((view_ref, listener, responder))
892        } else {
893            None
894        }
895    }
896
897    /// Name of the method defined in FIDL
898    pub fn method_name(&self) -> &'static str {
899        match *self {
900            KeyboardRequest::AddListener { .. } => "add_listener",
901        }
902    }
903}
904
905#[derive(Debug, Clone)]
906pub struct KeyboardControlHandle {
907    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
908}
909
910impl fidl::endpoints::ControlHandle for KeyboardControlHandle {
911    fn shutdown(&self) {
912        self.inner.shutdown()
913    }
914
915    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
916        self.inner.shutdown_with_epitaph(status)
917    }
918
919    fn is_closed(&self) -> bool {
920        self.inner.channel().is_closed()
921    }
922    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
923        self.inner.channel().on_closed()
924    }
925
926    #[cfg(target_os = "fuchsia")]
927    fn signal_peer(
928        &self,
929        clear_mask: zx::Signals,
930        set_mask: zx::Signals,
931    ) -> Result<(), zx_status::Status> {
932        use fidl::Peered;
933        self.inner.channel().signal_peer(clear_mask, set_mask)
934    }
935}
936
937impl KeyboardControlHandle {}
938
939#[must_use = "FIDL methods require a response to be sent"]
940#[derive(Debug)]
941pub struct KeyboardAddListenerResponder {
942    control_handle: std::mem::ManuallyDrop<KeyboardControlHandle>,
943    tx_id: u32,
944}
945
946/// Set the the channel to be shutdown (see [`KeyboardControlHandle::shutdown`])
947/// if the responder is dropped without sending a response, so that the client
948/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
949impl std::ops::Drop for KeyboardAddListenerResponder {
950    fn drop(&mut self) {
951        self.control_handle.shutdown();
952        // Safety: drops once, never accessed again
953        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
954    }
955}
956
957impl fidl::endpoints::Responder for KeyboardAddListenerResponder {
958    type ControlHandle = KeyboardControlHandle;
959
960    fn control_handle(&self) -> &KeyboardControlHandle {
961        &self.control_handle
962    }
963
964    fn drop_without_shutdown(mut self) {
965        // Safety: drops once, never accessed again due to mem::forget
966        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
967        // Prevent Drop from running (which would shut down the channel)
968        std::mem::forget(self);
969    }
970}
971
972impl KeyboardAddListenerResponder {
973    /// Sends a response to the FIDL transaction.
974    ///
975    /// Sets the channel to shutdown if an error occurs.
976    pub fn send(self) -> Result<(), fidl::Error> {
977        let _result = self.send_raw();
978        if _result.is_err() {
979            self.control_handle.shutdown();
980        }
981        self.drop_without_shutdown();
982        _result
983    }
984
985    /// Similar to "send" but does not shutdown the channel if an error occurs.
986    pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
987        let _result = self.send_raw();
988        self.drop_without_shutdown();
989        _result
990    }
991
992    fn send_raw(&self) -> Result<(), fidl::Error> {
993        self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
994            (),
995            self.tx_id,
996            0x3bc57587fc9b3d22,
997            fidl::encoding::DynamicFlags::empty(),
998        )
999    }
1000}
1001
1002#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1003pub struct KeyboardListenerMarker;
1004
1005impl fidl::endpoints::ProtocolMarker for KeyboardListenerMarker {
1006    type Proxy = KeyboardListenerProxy;
1007    type RequestStream = KeyboardListenerRequestStream;
1008    #[cfg(target_os = "fuchsia")]
1009    type SynchronousProxy = KeyboardListenerSynchronousProxy;
1010
1011    const DEBUG_NAME: &'static str = "(anonymous) KeyboardListener";
1012}
1013
1014pub trait KeyboardListenerProxyInterface: Send + Sync {
1015    type OnKeyEventResponseFut: std::future::Future<Output = Result<KeyEventStatus, fidl::Error>>
1016        + Send;
1017    fn r#on_key_event(&self, event: &KeyEvent) -> Self::OnKeyEventResponseFut;
1018}
1019#[derive(Debug)]
1020#[cfg(target_os = "fuchsia")]
1021pub struct KeyboardListenerSynchronousProxy {
1022    client: fidl::client::sync::Client,
1023}
1024
1025#[cfg(target_os = "fuchsia")]
1026impl fidl::endpoints::SynchronousProxy for KeyboardListenerSynchronousProxy {
1027    type Proxy = KeyboardListenerProxy;
1028    type Protocol = KeyboardListenerMarker;
1029
1030    fn from_channel(inner: fidl::Channel) -> Self {
1031        Self::new(inner)
1032    }
1033
1034    fn into_channel(self) -> fidl::Channel {
1035        self.client.into_channel()
1036    }
1037
1038    fn as_channel(&self) -> &fidl::Channel {
1039        self.client.as_channel()
1040    }
1041}
1042
1043#[cfg(target_os = "fuchsia")]
1044impl KeyboardListenerSynchronousProxy {
1045    pub fn new(channel: fidl::Channel) -> Self {
1046        Self { client: fidl::client::sync::Client::new(channel) }
1047    }
1048
1049    pub fn into_channel(self) -> fidl::Channel {
1050        self.client.into_channel()
1051    }
1052
1053    /// Waits until an event arrives and returns it. It is safe for other
1054    /// threads to make concurrent requests while waiting for an event.
1055    pub fn wait_for_event(
1056        &self,
1057        deadline: zx::MonotonicInstant,
1058    ) -> Result<KeyboardListenerEvent, fidl::Error> {
1059        KeyboardListenerEvent::decode(
1060            self.client.wait_for_event::<KeyboardListenerMarker>(deadline)?,
1061        )
1062    }
1063
1064    /// Called when a key event takes place, such as key press or release.
1065    ///
1066    /// Protocol implementers must respond to acknowledge the event by returning Status
1067    /// in a timely manner, i.e. not introducing significant delays to the
1068    /// input pipeline (typically 10s of milliseconds).
1069    ///
1070    /// Returning `NOT_HANDLED` means the event may be offered to other
1071    /// clients of other related APIs.
1072    ///
1073    /// Clients that do not acknowledge their events will eventually be disconnected.
1074    ///
1075    /// Notification is only dispatched to a view that has focus. No other views,
1076    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1077    pub fn r#on_key_event(
1078        &self,
1079        mut event: &KeyEvent,
1080        ___deadline: zx::MonotonicInstant,
1081    ) -> Result<KeyEventStatus, fidl::Error> {
1082        let _response = self.client.send_query::<
1083            KeyboardListenerOnKeyEventRequest,
1084            KeyboardListenerOnKeyEventResponse,
1085            KeyboardListenerMarker,
1086        >(
1087            (event,),
1088            0x2ef2ee16ac509093,
1089            fidl::encoding::DynamicFlags::empty(),
1090            ___deadline,
1091        )?;
1092        Ok(_response.status)
1093    }
1094}
1095
1096#[cfg(target_os = "fuchsia")]
1097impl From<KeyboardListenerSynchronousProxy> for zx::NullableHandle {
1098    fn from(value: KeyboardListenerSynchronousProxy) -> Self {
1099        value.into_channel().into()
1100    }
1101}
1102
1103#[cfg(target_os = "fuchsia")]
1104impl From<fidl::Channel> for KeyboardListenerSynchronousProxy {
1105    fn from(value: fidl::Channel) -> Self {
1106        Self::new(value)
1107    }
1108}
1109
1110#[cfg(target_os = "fuchsia")]
1111impl fidl::endpoints::FromClient for KeyboardListenerSynchronousProxy {
1112    type Protocol = KeyboardListenerMarker;
1113
1114    fn from_client(value: fidl::endpoints::ClientEnd<KeyboardListenerMarker>) -> Self {
1115        Self::new(value.into_channel())
1116    }
1117}
1118
1119#[derive(Debug, Clone)]
1120pub struct KeyboardListenerProxy {
1121    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
1122}
1123
1124impl fidl::endpoints::Proxy for KeyboardListenerProxy {
1125    type Protocol = KeyboardListenerMarker;
1126
1127    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
1128        Self::new(inner)
1129    }
1130
1131    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
1132        self.client.into_channel().map_err(|client| Self { client })
1133    }
1134
1135    fn as_channel(&self) -> &::fidl::AsyncChannel {
1136        self.client.as_channel()
1137    }
1138}
1139
1140impl KeyboardListenerProxy {
1141    /// Create a new Proxy for fuchsia.ui.input3/KeyboardListener.
1142    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
1143        let protocol_name = <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1144        Self { client: fidl::client::Client::new(channel, protocol_name) }
1145    }
1146
1147    /// Get a Stream of events from the remote end of the protocol.
1148    ///
1149    /// # Panics
1150    ///
1151    /// Panics if the event stream was already taken.
1152    pub fn take_event_stream(&self) -> KeyboardListenerEventStream {
1153        KeyboardListenerEventStream { event_receiver: self.client.take_event_receiver() }
1154    }
1155
1156    /// Called when a key event takes place, such as key press or release.
1157    ///
1158    /// Protocol implementers must respond to acknowledge the event by returning Status
1159    /// in a timely manner, i.e. not introducing significant delays to the
1160    /// input pipeline (typically 10s of milliseconds).
1161    ///
1162    /// Returning `NOT_HANDLED` means the event may be offered to other
1163    /// clients of other related APIs.
1164    ///
1165    /// Clients that do not acknowledge their events will eventually be disconnected.
1166    ///
1167    /// Notification is only dispatched to a view that has focus. No other views,
1168    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1169    pub fn r#on_key_event(
1170        &self,
1171        mut event: &KeyEvent,
1172    ) -> fidl::client::QueryResponseFut<KeyEventStatus, fidl::encoding::DefaultFuchsiaResourceDialect>
1173    {
1174        KeyboardListenerProxyInterface::r#on_key_event(self, event)
1175    }
1176}
1177
1178impl KeyboardListenerProxyInterface for KeyboardListenerProxy {
1179    type OnKeyEventResponseFut = fidl::client::QueryResponseFut<
1180        KeyEventStatus,
1181        fidl::encoding::DefaultFuchsiaResourceDialect,
1182    >;
1183    fn r#on_key_event(&self, mut event: &KeyEvent) -> Self::OnKeyEventResponseFut {
1184        fn _decode(
1185            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1186        ) -> Result<KeyEventStatus, fidl::Error> {
1187            let _response = fidl::client::decode_transaction_body::<
1188                KeyboardListenerOnKeyEventResponse,
1189                fidl::encoding::DefaultFuchsiaResourceDialect,
1190                0x2ef2ee16ac509093,
1191            >(_buf?)?;
1192            Ok(_response.status)
1193        }
1194        self.client.send_query_and_decode::<KeyboardListenerOnKeyEventRequest, KeyEventStatus>(
1195            (event,),
1196            0x2ef2ee16ac509093,
1197            fidl::encoding::DynamicFlags::empty(),
1198            _decode,
1199        )
1200    }
1201}
1202
1203pub struct KeyboardListenerEventStream {
1204    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
1205}
1206
1207impl std::marker::Unpin for KeyboardListenerEventStream {}
1208
1209impl futures::stream::FusedStream for KeyboardListenerEventStream {
1210    fn is_terminated(&self) -> bool {
1211        self.event_receiver.is_terminated()
1212    }
1213}
1214
1215impl futures::Stream for KeyboardListenerEventStream {
1216    type Item = Result<KeyboardListenerEvent, fidl::Error>;
1217
1218    fn poll_next(
1219        mut self: std::pin::Pin<&mut Self>,
1220        cx: &mut std::task::Context<'_>,
1221    ) -> std::task::Poll<Option<Self::Item>> {
1222        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
1223            &mut self.event_receiver,
1224            cx
1225        )?) {
1226            Some(buf) => std::task::Poll::Ready(Some(KeyboardListenerEvent::decode(buf))),
1227            None => std::task::Poll::Ready(None),
1228        }
1229    }
1230}
1231
1232#[derive(Debug)]
1233pub enum KeyboardListenerEvent {}
1234
1235impl KeyboardListenerEvent {
1236    /// Decodes a message buffer as a [`KeyboardListenerEvent`].
1237    fn decode(
1238        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
1239    ) -> Result<KeyboardListenerEvent, fidl::Error> {
1240        let (bytes, _handles) = buf.split_mut();
1241        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1242        debug_assert_eq!(tx_header.tx_id, 0);
1243        match tx_header.ordinal {
1244            _ => Err(fidl::Error::UnknownOrdinal {
1245                ordinal: tx_header.ordinal,
1246                protocol_name:
1247                    <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1248            }),
1249        }
1250    }
1251}
1252
1253/// A Stream of incoming requests for fuchsia.ui.input3/KeyboardListener.
1254pub struct KeyboardListenerRequestStream {
1255    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1256    is_terminated: bool,
1257}
1258
1259impl std::marker::Unpin for KeyboardListenerRequestStream {}
1260
1261impl futures::stream::FusedStream for KeyboardListenerRequestStream {
1262    fn is_terminated(&self) -> bool {
1263        self.is_terminated
1264    }
1265}
1266
1267impl fidl::endpoints::RequestStream for KeyboardListenerRequestStream {
1268    type Protocol = KeyboardListenerMarker;
1269    type ControlHandle = KeyboardListenerControlHandle;
1270
1271    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
1272        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
1273    }
1274
1275    fn control_handle(&self) -> Self::ControlHandle {
1276        KeyboardListenerControlHandle { inner: self.inner.clone() }
1277    }
1278
1279    fn into_inner(
1280        self,
1281    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
1282    {
1283        (self.inner, self.is_terminated)
1284    }
1285
1286    fn from_inner(
1287        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1288        is_terminated: bool,
1289    ) -> Self {
1290        Self { inner, is_terminated }
1291    }
1292}
1293
1294impl futures::Stream for KeyboardListenerRequestStream {
1295    type Item = Result<KeyboardListenerRequest, fidl::Error>;
1296
1297    fn poll_next(
1298        mut self: std::pin::Pin<&mut Self>,
1299        cx: &mut std::task::Context<'_>,
1300    ) -> std::task::Poll<Option<Self::Item>> {
1301        let this = &mut *self;
1302        if this.inner.check_shutdown(cx) {
1303            this.is_terminated = true;
1304            return std::task::Poll::Ready(None);
1305        }
1306        if this.is_terminated {
1307            panic!("polled KeyboardListenerRequestStream after completion");
1308        }
1309        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
1310            |bytes, handles| {
1311                match this.inner.channel().read_etc(cx, bytes, handles) {
1312                    std::task::Poll::Ready(Ok(())) => {}
1313                    std::task::Poll::Pending => return std::task::Poll::Pending,
1314                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
1315                        this.is_terminated = true;
1316                        return std::task::Poll::Ready(None);
1317                    }
1318                    std::task::Poll::Ready(Err(e)) => {
1319                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
1320                            e.into(),
1321                        ))));
1322                    }
1323                }
1324
1325                // A message has been received from the channel
1326                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1327
1328                std::task::Poll::Ready(Some(match header.ordinal {
1329                    0x2ef2ee16ac509093 => {
1330                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1331                        let mut req = fidl::new_empty!(
1332                            KeyboardListenerOnKeyEventRequest,
1333                            fidl::encoding::DefaultFuchsiaResourceDialect
1334                        );
1335                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<KeyboardListenerOnKeyEventRequest>(&header, _body_bytes, handles, &mut req)?;
1336                        let control_handle =
1337                            KeyboardListenerControlHandle { inner: this.inner.clone() };
1338                        Ok(KeyboardListenerRequest::OnKeyEvent {
1339                            event: req.event,
1340
1341                            responder: KeyboardListenerOnKeyEventResponder {
1342                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1343                                tx_id: header.tx_id,
1344                            },
1345                        })
1346                    }
1347                    _ => Err(fidl::Error::UnknownOrdinal {
1348                        ordinal: header.ordinal,
1349                        protocol_name:
1350                            <KeyboardListenerMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1351                    }),
1352                }))
1353            },
1354        )
1355    }
1356}
1357
1358/// Client should implement this protocol to get notified of key events.
1359#[derive(Debug)]
1360pub enum KeyboardListenerRequest {
1361    /// Called when a key event takes place, such as key press or release.
1362    ///
1363    /// Protocol implementers must respond to acknowledge the event by returning Status
1364    /// in a timely manner, i.e. not introducing significant delays to the
1365    /// input pipeline (typically 10s of milliseconds).
1366    ///
1367    /// Returning `NOT_HANDLED` means the event may be offered to other
1368    /// clients of other related APIs.
1369    ///
1370    /// Clients that do not acknowledge their events will eventually be disconnected.
1371    ///
1372    /// Notification is only dispatched to a view that has focus. No other views,
1373    /// including parents or children, will get notified specifically via `OnKeyEvent`.
1374    OnKeyEvent { event: KeyEvent, responder: KeyboardListenerOnKeyEventResponder },
1375}
1376
1377impl KeyboardListenerRequest {
1378    #[allow(irrefutable_let_patterns)]
1379    pub fn into_on_key_event(self) -> Option<(KeyEvent, KeyboardListenerOnKeyEventResponder)> {
1380        if let KeyboardListenerRequest::OnKeyEvent { event, responder } = self {
1381            Some((event, responder))
1382        } else {
1383            None
1384        }
1385    }
1386
1387    /// Name of the method defined in FIDL
1388    pub fn method_name(&self) -> &'static str {
1389        match *self {
1390            KeyboardListenerRequest::OnKeyEvent { .. } => "on_key_event",
1391        }
1392    }
1393}
1394
1395#[derive(Debug, Clone)]
1396pub struct KeyboardListenerControlHandle {
1397    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1398}
1399
1400impl fidl::endpoints::ControlHandle for KeyboardListenerControlHandle {
1401    fn shutdown(&self) {
1402        self.inner.shutdown()
1403    }
1404
1405    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1406        self.inner.shutdown_with_epitaph(status)
1407    }
1408
1409    fn is_closed(&self) -> bool {
1410        self.inner.channel().is_closed()
1411    }
1412    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1413        self.inner.channel().on_closed()
1414    }
1415
1416    #[cfg(target_os = "fuchsia")]
1417    fn signal_peer(
1418        &self,
1419        clear_mask: zx::Signals,
1420        set_mask: zx::Signals,
1421    ) -> Result<(), zx_status::Status> {
1422        use fidl::Peered;
1423        self.inner.channel().signal_peer(clear_mask, set_mask)
1424    }
1425}
1426
1427impl KeyboardListenerControlHandle {}
1428
1429#[must_use = "FIDL methods require a response to be sent"]
1430#[derive(Debug)]
1431pub struct KeyboardListenerOnKeyEventResponder {
1432    control_handle: std::mem::ManuallyDrop<KeyboardListenerControlHandle>,
1433    tx_id: u32,
1434}
1435
1436/// Set the the channel to be shutdown (see [`KeyboardListenerControlHandle::shutdown`])
1437/// if the responder is dropped without sending a response, so that the client
1438/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1439impl std::ops::Drop for KeyboardListenerOnKeyEventResponder {
1440    fn drop(&mut self) {
1441        self.control_handle.shutdown();
1442        // Safety: drops once, never accessed again
1443        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1444    }
1445}
1446
1447impl fidl::endpoints::Responder for KeyboardListenerOnKeyEventResponder {
1448    type ControlHandle = KeyboardListenerControlHandle;
1449
1450    fn control_handle(&self) -> &KeyboardListenerControlHandle {
1451        &self.control_handle
1452    }
1453
1454    fn drop_without_shutdown(mut self) {
1455        // Safety: drops once, never accessed again due to mem::forget
1456        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1457        // Prevent Drop from running (which would shut down the channel)
1458        std::mem::forget(self);
1459    }
1460}
1461
1462impl KeyboardListenerOnKeyEventResponder {
1463    /// Sends a response to the FIDL transaction.
1464    ///
1465    /// Sets the channel to shutdown if an error occurs.
1466    pub fn send(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1467        let _result = self.send_raw(status);
1468        if _result.is_err() {
1469            self.control_handle.shutdown();
1470        }
1471        self.drop_without_shutdown();
1472        _result
1473    }
1474
1475    /// Similar to "send" but does not shutdown the channel if an error occurs.
1476    pub fn send_no_shutdown_on_err(self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1477        let _result = self.send_raw(status);
1478        self.drop_without_shutdown();
1479        _result
1480    }
1481
1482    fn send_raw(&self, mut status: KeyEventStatus) -> Result<(), fidl::Error> {
1483        self.control_handle.inner.send::<KeyboardListenerOnKeyEventResponse>(
1484            (status,),
1485            self.tx_id,
1486            0x2ef2ee16ac509093,
1487            fidl::encoding::DynamicFlags::empty(),
1488        )
1489    }
1490}
1491
1492mod internal {
1493    use super::*;
1494
1495    impl fidl::encoding::ResourceTypeMarker for KeyboardAddListenerRequest {
1496        type Borrowed<'a> = &'a mut Self;
1497        fn take_or_borrow<'a>(
1498            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1499        ) -> Self::Borrowed<'a> {
1500            value
1501        }
1502    }
1503
1504    unsafe impl fidl::encoding::TypeMarker for KeyboardAddListenerRequest {
1505        type Owned = Self;
1506
1507        #[inline(always)]
1508        fn inline_align(_context: fidl::encoding::Context) -> usize {
1509            4
1510        }
1511
1512        #[inline(always)]
1513        fn inline_size(_context: fidl::encoding::Context) -> usize {
1514            8
1515        }
1516    }
1517
1518    unsafe impl
1519        fidl::encoding::Encode<
1520            KeyboardAddListenerRequest,
1521            fidl::encoding::DefaultFuchsiaResourceDialect,
1522        > for &mut KeyboardAddListenerRequest
1523    {
1524        #[inline]
1525        unsafe fn encode(
1526            self,
1527            encoder: &mut fidl::encoding::Encoder<
1528                '_,
1529                fidl::encoding::DefaultFuchsiaResourceDialect,
1530            >,
1531            offset: usize,
1532            _depth: fidl::encoding::Depth,
1533        ) -> fidl::Result<()> {
1534            encoder.debug_check_bounds::<KeyboardAddListenerRequest>(offset);
1535            // Delegate to tuple encoding.
1536            fidl::encoding::Encode::<KeyboardAddListenerRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
1537                (
1538                    <fidl_fuchsia_ui_views::ViewRef as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.view_ref),
1539                    <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.listener),
1540                ),
1541                encoder, offset, _depth
1542            )
1543        }
1544    }
1545    unsafe impl<
1546        T0: fidl::encoding::Encode<
1547                fidl_fuchsia_ui_views::ViewRef,
1548                fidl::encoding::DefaultFuchsiaResourceDialect,
1549            >,
1550        T1: fidl::encoding::Encode<
1551                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1552                fidl::encoding::DefaultFuchsiaResourceDialect,
1553            >,
1554    >
1555        fidl::encoding::Encode<
1556            KeyboardAddListenerRequest,
1557            fidl::encoding::DefaultFuchsiaResourceDialect,
1558        > for (T0, T1)
1559    {
1560        #[inline]
1561        unsafe fn encode(
1562            self,
1563            encoder: &mut fidl::encoding::Encoder<
1564                '_,
1565                fidl::encoding::DefaultFuchsiaResourceDialect,
1566            >,
1567            offset: usize,
1568            depth: fidl::encoding::Depth,
1569        ) -> fidl::Result<()> {
1570            encoder.debug_check_bounds::<KeyboardAddListenerRequest>(offset);
1571            // Zero out padding regions. There's no need to apply masks
1572            // because the unmasked parts will be overwritten by fields.
1573            // Write the fields.
1574            self.0.encode(encoder, offset + 0, depth)?;
1575            self.1.encode(encoder, offset + 4, depth)?;
1576            Ok(())
1577        }
1578    }
1579
1580    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1581        for KeyboardAddListenerRequest
1582    {
1583        #[inline(always)]
1584        fn new_empty() -> Self {
1585            Self {
1586                view_ref: fidl::new_empty!(
1587                    fidl_fuchsia_ui_views::ViewRef,
1588                    fidl::encoding::DefaultFuchsiaResourceDialect
1589                ),
1590                listener: fidl::new_empty!(
1591                    fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1592                    fidl::encoding::DefaultFuchsiaResourceDialect
1593                ),
1594            }
1595        }
1596
1597        #[inline]
1598        unsafe fn decode(
1599            &mut self,
1600            decoder: &mut fidl::encoding::Decoder<
1601                '_,
1602                fidl::encoding::DefaultFuchsiaResourceDialect,
1603            >,
1604            offset: usize,
1605            _depth: fidl::encoding::Depth,
1606        ) -> fidl::Result<()> {
1607            decoder.debug_check_bounds::<Self>(offset);
1608            // Verify that padding bytes are zero.
1609            fidl::decode!(
1610                fidl_fuchsia_ui_views::ViewRef,
1611                fidl::encoding::DefaultFuchsiaResourceDialect,
1612                &mut self.view_ref,
1613                decoder,
1614                offset + 0,
1615                _depth
1616            )?;
1617            fidl::decode!(
1618                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<KeyboardListenerMarker>>,
1619                fidl::encoding::DefaultFuchsiaResourceDialect,
1620                &mut self.listener,
1621                decoder,
1622                offset + 4,
1623                _depth
1624            )?;
1625            Ok(())
1626        }
1627    }
1628}