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