Skip to main content

fidl_fuchsia_memorypressure/
fidl_fuchsia_memorypressure.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_memorypressure_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct ProviderRegisterWatcherRequest {
16    pub watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
17}
18
19impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
20    for ProviderRegisterWatcherRequest
21{
22}
23
24#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
25pub struct ProviderMarker;
26
27impl fidl::endpoints::ProtocolMarker for ProviderMarker {
28    type Proxy = ProviderProxy;
29    type RequestStream = ProviderRequestStream;
30    #[cfg(target_os = "fuchsia")]
31    type SynchronousProxy = ProviderSynchronousProxy;
32
33    const DEBUG_NAME: &'static str = "fuchsia.memorypressure.Provider";
34}
35impl fidl::endpoints::DiscoverableProtocolMarker for ProviderMarker {}
36
37pub trait ProviderProxyInterface: Send + Sync {
38    fn r#register_watcher(
39        &self,
40        watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
41    ) -> Result<(), fidl::Error>;
42}
43#[derive(Debug)]
44#[cfg(target_os = "fuchsia")]
45pub struct ProviderSynchronousProxy {
46    client: fidl::client::sync::Client,
47}
48
49#[cfg(target_os = "fuchsia")]
50impl fidl::endpoints::SynchronousProxy for ProviderSynchronousProxy {
51    type Proxy = ProviderProxy;
52    type Protocol = ProviderMarker;
53
54    fn from_channel(inner: fidl::Channel) -> Self {
55        Self::new(inner)
56    }
57
58    fn into_channel(self) -> fidl::Channel {
59        self.client.into_channel()
60    }
61
62    fn as_channel(&self) -> &fidl::Channel {
63        self.client.as_channel()
64    }
65}
66
67#[cfg(target_os = "fuchsia")]
68impl ProviderSynchronousProxy {
69    pub fn new(channel: fidl::Channel) -> Self {
70        Self { client: fidl::client::sync::Client::new(channel) }
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<ProviderEvent, fidl::Error> {
83        ProviderEvent::decode(self.client.wait_for_event::<ProviderMarker>(deadline)?)
84    }
85
86    /// Used to register for memory pressure level changes.
87    /// `watcher`: memory pressure `Watcher` channel that the `Provider` will use to send
88    /// level change messages to the client.
89    ///
90    /// The current memory pressure level is immediately sent to the watcher
91    /// when this method is called.
92    ///
93    /// It is recommended that the root job in a component tree register for changes,
94    /// rather than having individual jobs further down the tree register individually.
95    /// A low client count will help minimize system churn due to a large number of
96    /// memory pressure messages in transit at the same time.
97    /// Also, the more context a job has, the better equipped it will be to react to
98    /// memory pressure by controlling the behavior of children jobs in its tree.
99    pub fn r#register_watcher(
100        &self,
101        mut watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
102    ) -> Result<(), fidl::Error> {
103        self.client.send::<ProviderRegisterWatcherRequest>(
104            (watcher,),
105            0x91e65af25aae4a9,
106            fidl::encoding::DynamicFlags::empty(),
107        )
108    }
109}
110
111#[cfg(target_os = "fuchsia")]
112impl From<ProviderSynchronousProxy> for zx::NullableHandle {
113    fn from(value: ProviderSynchronousProxy) -> Self {
114        value.into_channel().into()
115    }
116}
117
118#[cfg(target_os = "fuchsia")]
119impl From<fidl::Channel> for ProviderSynchronousProxy {
120    fn from(value: fidl::Channel) -> Self {
121        Self::new(value)
122    }
123}
124
125#[cfg(target_os = "fuchsia")]
126impl fidl::endpoints::FromClient for ProviderSynchronousProxy {
127    type Protocol = ProviderMarker;
128
129    fn from_client(value: fidl::endpoints::ClientEnd<ProviderMarker>) -> Self {
130        Self::new(value.into_channel())
131    }
132}
133
134#[derive(Debug, Clone)]
135pub struct ProviderProxy {
136    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
137}
138
139impl fidl::endpoints::Proxy for ProviderProxy {
140    type Protocol = ProviderMarker;
141
142    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
143        Self::new(inner)
144    }
145
146    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
147        self.client.into_channel().map_err(|client| Self { client })
148    }
149
150    fn as_channel(&self) -> &::fidl::AsyncChannel {
151        self.client.as_channel()
152    }
153}
154
155impl ProviderProxy {
156    /// Create a new Proxy for fuchsia.memorypressure/Provider.
157    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
158        let protocol_name = <ProviderMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
159        Self { client: fidl::client::Client::new(channel, protocol_name) }
160    }
161
162    /// Get a Stream of events from the remote end of the protocol.
163    ///
164    /// # Panics
165    ///
166    /// Panics if the event stream was already taken.
167    pub fn take_event_stream(&self) -> ProviderEventStream {
168        ProviderEventStream { event_receiver: self.client.take_event_receiver() }
169    }
170
171    /// Used to register for memory pressure level changes.
172    /// `watcher`: memory pressure `Watcher` channel that the `Provider` will use to send
173    /// level change messages to the client.
174    ///
175    /// The current memory pressure level is immediately sent to the watcher
176    /// when this method is called.
177    ///
178    /// It is recommended that the root job in a component tree register for changes,
179    /// rather than having individual jobs further down the tree register individually.
180    /// A low client count will help minimize system churn due to a large number of
181    /// memory pressure messages in transit at the same time.
182    /// Also, the more context a job has, the better equipped it will be to react to
183    /// memory pressure by controlling the behavior of children jobs in its tree.
184    pub fn r#register_watcher(
185        &self,
186        mut watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
187    ) -> Result<(), fidl::Error> {
188        ProviderProxyInterface::r#register_watcher(self, watcher)
189    }
190}
191
192impl ProviderProxyInterface for ProviderProxy {
193    fn r#register_watcher(
194        &self,
195        mut watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
196    ) -> Result<(), fidl::Error> {
197        self.client.send::<ProviderRegisterWatcherRequest>(
198            (watcher,),
199            0x91e65af25aae4a9,
200            fidl::encoding::DynamicFlags::empty(),
201        )
202    }
203}
204
205pub struct ProviderEventStream {
206    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
207}
208
209impl std::marker::Unpin for ProviderEventStream {}
210
211impl futures::stream::FusedStream for ProviderEventStream {
212    fn is_terminated(&self) -> bool {
213        self.event_receiver.is_terminated()
214    }
215}
216
217impl futures::Stream for ProviderEventStream {
218    type Item = Result<ProviderEvent, fidl::Error>;
219
220    fn poll_next(
221        mut self: std::pin::Pin<&mut Self>,
222        cx: &mut std::task::Context<'_>,
223    ) -> std::task::Poll<Option<Self::Item>> {
224        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
225            &mut self.event_receiver,
226            cx
227        )?) {
228            Some(buf) => std::task::Poll::Ready(Some(ProviderEvent::decode(buf))),
229            None => std::task::Poll::Ready(None),
230        }
231    }
232}
233
234#[derive(Debug)]
235pub enum ProviderEvent {}
236
237impl ProviderEvent {
238    /// Decodes a message buffer as a [`ProviderEvent`].
239    fn decode(
240        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
241    ) -> Result<ProviderEvent, fidl::Error> {
242        let (bytes, _handles) = buf.split_mut();
243        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
244        debug_assert_eq!(tx_header.tx_id, 0);
245        match tx_header.ordinal {
246            _ => Err(fidl::Error::UnknownOrdinal {
247                ordinal: tx_header.ordinal,
248                protocol_name: <ProviderMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
249            }),
250        }
251    }
252}
253
254/// A Stream of incoming requests for fuchsia.memorypressure/Provider.
255pub struct ProviderRequestStream {
256    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
257    is_terminated: bool,
258}
259
260impl std::marker::Unpin for ProviderRequestStream {}
261
262impl futures::stream::FusedStream for ProviderRequestStream {
263    fn is_terminated(&self) -> bool {
264        self.is_terminated
265    }
266}
267
268impl fidl::endpoints::RequestStream for ProviderRequestStream {
269    type Protocol = ProviderMarker;
270    type ControlHandle = ProviderControlHandle;
271
272    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
273        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
274    }
275
276    fn control_handle(&self) -> Self::ControlHandle {
277        ProviderControlHandle { inner: self.inner.clone() }
278    }
279
280    fn into_inner(
281        self,
282    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
283    {
284        (self.inner, self.is_terminated)
285    }
286
287    fn from_inner(
288        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
289        is_terminated: bool,
290    ) -> Self {
291        Self { inner, is_terminated }
292    }
293}
294
295impl futures::Stream for ProviderRequestStream {
296    type Item = Result<ProviderRequest, fidl::Error>;
297
298    fn poll_next(
299        mut self: std::pin::Pin<&mut Self>,
300        cx: &mut std::task::Context<'_>,
301    ) -> std::task::Poll<Option<Self::Item>> {
302        let this = &mut *self;
303        if this.inner.check_shutdown(cx) {
304            this.is_terminated = true;
305            return std::task::Poll::Ready(None);
306        }
307        if this.is_terminated {
308            panic!("polled ProviderRequestStream after completion");
309        }
310        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
311            |bytes, handles| {
312                match this.inner.channel().read_etc(cx, bytes, handles) {
313                    std::task::Poll::Ready(Ok(())) => {}
314                    std::task::Poll::Pending => return std::task::Poll::Pending,
315                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
316                        this.is_terminated = true;
317                        return std::task::Poll::Ready(None);
318                    }
319                    std::task::Poll::Ready(Err(e)) => {
320                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
321                            e.into(),
322                        ))));
323                    }
324                }
325
326                // A message has been received from the channel
327                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
328
329                std::task::Poll::Ready(Some(match header.ordinal {
330                    0x91e65af25aae4a9 => {
331                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
332                        let mut req = fidl::new_empty!(
333                            ProviderRegisterWatcherRequest,
334                            fidl::encoding::DefaultFuchsiaResourceDialect
335                        );
336                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ProviderRegisterWatcherRequest>(&header, _body_bytes, handles, &mut req)?;
337                        let control_handle = ProviderControlHandle { inner: this.inner.clone() };
338                        Ok(ProviderRequest::RegisterWatcher {
339                            watcher: req.watcher,
340
341                            control_handle,
342                        })
343                    }
344                    _ => Err(fidl::Error::UnknownOrdinal {
345                        ordinal: header.ordinal,
346                        protocol_name:
347                            <ProviderMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
348                    }),
349                }))
350            },
351        )
352    }
353}
354
355/// Registration protocol
356#[derive(Debug)]
357pub enum ProviderRequest {
358    /// Used to register for memory pressure level changes.
359    /// `watcher`: memory pressure `Watcher` channel that the `Provider` will use to send
360    /// level change messages to the client.
361    ///
362    /// The current memory pressure level is immediately sent to the watcher
363    /// when this method is called.
364    ///
365    /// It is recommended that the root job in a component tree register for changes,
366    /// rather than having individual jobs further down the tree register individually.
367    /// A low client count will help minimize system churn due to a large number of
368    /// memory pressure messages in transit at the same time.
369    /// Also, the more context a job has, the better equipped it will be to react to
370    /// memory pressure by controlling the behavior of children jobs in its tree.
371    RegisterWatcher {
372        watcher: fidl::endpoints::ClientEnd<WatcherMarker>,
373        control_handle: ProviderControlHandle,
374    },
375}
376
377impl ProviderRequest {
378    #[allow(irrefutable_let_patterns)]
379    pub fn into_register_watcher(
380        self,
381    ) -> Option<(fidl::endpoints::ClientEnd<WatcherMarker>, ProviderControlHandle)> {
382        if let ProviderRequest::RegisterWatcher { watcher, control_handle } = self {
383            Some((watcher, control_handle))
384        } else {
385            None
386        }
387    }
388
389    /// Name of the method defined in FIDL
390    pub fn method_name(&self) -> &'static str {
391        match *self {
392            ProviderRequest::RegisterWatcher { .. } => "register_watcher",
393        }
394    }
395}
396
397#[derive(Debug, Clone)]
398pub struct ProviderControlHandle {
399    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
400}
401
402impl ProviderControlHandle {
403    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
404        self.inner.shutdown_with_epitaph(status.into())
405    }
406}
407
408impl fidl::endpoints::ControlHandle for ProviderControlHandle {
409    fn shutdown(&self) {
410        self.inner.shutdown()
411    }
412
413    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
414        self.inner.shutdown_with_epitaph(status)
415    }
416
417    fn is_closed(&self) -> bool {
418        self.inner.channel().is_closed()
419    }
420    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
421        self.inner.channel().on_closed()
422    }
423
424    #[cfg(target_os = "fuchsia")]
425    fn signal_peer(
426        &self,
427        clear_mask: zx::Signals,
428        set_mask: zx::Signals,
429    ) -> Result<(), zx_status::Status> {
430        use fidl::Peered;
431        self.inner.channel().signal_peer(clear_mask, set_mask)
432    }
433}
434
435impl ProviderControlHandle {}
436
437#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
438pub struct WatcherMarker;
439
440impl fidl::endpoints::ProtocolMarker for WatcherMarker {
441    type Proxy = WatcherProxy;
442    type RequestStream = WatcherRequestStream;
443    #[cfg(target_os = "fuchsia")]
444    type SynchronousProxy = WatcherSynchronousProxy;
445
446    const DEBUG_NAME: &'static str = "(anonymous) Watcher";
447}
448
449pub trait WatcherProxyInterface: Send + Sync {
450    type OnLevelChangedResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
451    fn r#on_level_changed(&self, level: Level) -> Self::OnLevelChangedResponseFut;
452}
453#[derive(Debug)]
454#[cfg(target_os = "fuchsia")]
455pub struct WatcherSynchronousProxy {
456    client: fidl::client::sync::Client,
457}
458
459#[cfg(target_os = "fuchsia")]
460impl fidl::endpoints::SynchronousProxy for WatcherSynchronousProxy {
461    type Proxy = WatcherProxy;
462    type Protocol = WatcherMarker;
463
464    fn from_channel(inner: fidl::Channel) -> Self {
465        Self::new(inner)
466    }
467
468    fn into_channel(self) -> fidl::Channel {
469        self.client.into_channel()
470    }
471
472    fn as_channel(&self) -> &fidl::Channel {
473        self.client.as_channel()
474    }
475}
476
477#[cfg(target_os = "fuchsia")]
478impl WatcherSynchronousProxy {
479    pub fn new(channel: fidl::Channel) -> Self {
480        Self { client: fidl::client::sync::Client::new(channel) }
481    }
482
483    pub fn into_channel(self) -> fidl::Channel {
484        self.client.into_channel()
485    }
486
487    /// Waits until an event arrives and returns it. It is safe for other
488    /// threads to make concurrent requests while waiting for an event.
489    pub fn wait_for_event(
490        &self,
491        deadline: zx::MonotonicInstant,
492    ) -> Result<WatcherEvent, fidl::Error> {
493        WatcherEvent::decode(self.client.wait_for_event::<WatcherMarker>(deadline)?)
494    }
495
496    /// Sent to the registered client when the memory pressure level changes.
497    /// `level`: indicates the current memory pressure level.
498    ///
499    /// Will also be invoked on initial connection via `RegisterWatcher`, so that a newly
500    /// registered client can discover the current memory pressure level.
501    ///
502    /// The watcher must immediately reply with a message to acknowledge that it has
503    /// received the level change notification, and has initiated required actions as a
504    /// result. It may then continue to reclaim memory asynchronously after sending
505    /// the acknowledgement.
506    ///
507    /// Some helpful guidelines for clients:
508    /// 1. The watcher will be notified of new pressure level changes only after a reply
509    /// corresponding to the previous message has been received by the provider.
510    /// If multiple level transitions occur during that time, the watcher will be
511    /// notified of the latest pressure level.
512    ///
513    /// 2. The level changes are edge-triggered, and clients are expected to maintain
514    /// local state to track the current pressure level, if required. For example,
515    /// a job might be notified of a CRITICAL level and drop all its caches as a result.
516    /// Some time after this, it might want to trigger an activity that causes a
517    /// fair amount of memory to be allocated. At this point, the job is expected to
518    /// remember that the last pressure level it saw was CRITICAL, and refrain from
519    /// triggering the memory-intensive activity.
520    ///
521    /// 3. As a performance optimization, the provider may decide to skip sending
522    /// messages for some pressure level changes. For example, when oscillating across
523    /// the NORMAL / WARNING boundary, it might not be worth notifying clients of every
524    /// single transition. The provider might rate-limit messages in this case.
525    /// On a similar note, the provider may decide to send repeated messages at the
526    /// same pressure level, particularly CRITICAL, to indicate that further action
527    /// needs to be taken.
528    pub fn r#on_level_changed(
529        &self,
530        mut level: Level,
531        ___deadline: zx::MonotonicInstant,
532    ) -> Result<(), fidl::Error> {
533        let _response = self.client.send_query::<
534            WatcherOnLevelChangedRequest,
535            fidl::encoding::EmptyPayload,
536            WatcherMarker,
537        >(
538            (level,),
539            0x55d559533407fed9,
540            fidl::encoding::DynamicFlags::empty(),
541            ___deadline,
542        )?;
543        Ok(_response)
544    }
545}
546
547#[cfg(target_os = "fuchsia")]
548impl From<WatcherSynchronousProxy> for zx::NullableHandle {
549    fn from(value: WatcherSynchronousProxy) -> Self {
550        value.into_channel().into()
551    }
552}
553
554#[cfg(target_os = "fuchsia")]
555impl From<fidl::Channel> for WatcherSynchronousProxy {
556    fn from(value: fidl::Channel) -> Self {
557        Self::new(value)
558    }
559}
560
561#[cfg(target_os = "fuchsia")]
562impl fidl::endpoints::FromClient for WatcherSynchronousProxy {
563    type Protocol = WatcherMarker;
564
565    fn from_client(value: fidl::endpoints::ClientEnd<WatcherMarker>) -> Self {
566        Self::new(value.into_channel())
567    }
568}
569
570#[derive(Debug, Clone)]
571pub struct WatcherProxy {
572    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
573}
574
575impl fidl::endpoints::Proxy for WatcherProxy {
576    type Protocol = WatcherMarker;
577
578    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
579        Self::new(inner)
580    }
581
582    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
583        self.client.into_channel().map_err(|client| Self { client })
584    }
585
586    fn as_channel(&self) -> &::fidl::AsyncChannel {
587        self.client.as_channel()
588    }
589}
590
591impl WatcherProxy {
592    /// Create a new Proxy for fuchsia.memorypressure/Watcher.
593    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
594        let protocol_name = <WatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
595        Self { client: fidl::client::Client::new(channel, protocol_name) }
596    }
597
598    /// Get a Stream of events from the remote end of the protocol.
599    ///
600    /// # Panics
601    ///
602    /// Panics if the event stream was already taken.
603    pub fn take_event_stream(&self) -> WatcherEventStream {
604        WatcherEventStream { event_receiver: self.client.take_event_receiver() }
605    }
606
607    /// Sent to the registered client when the memory pressure level changes.
608    /// `level`: indicates the current memory pressure level.
609    ///
610    /// Will also be invoked on initial connection via `RegisterWatcher`, so that a newly
611    /// registered client can discover the current memory pressure level.
612    ///
613    /// The watcher must immediately reply with a message to acknowledge that it has
614    /// received the level change notification, and has initiated required actions as a
615    /// result. It may then continue to reclaim memory asynchronously after sending
616    /// the acknowledgement.
617    ///
618    /// Some helpful guidelines for clients:
619    /// 1. The watcher will be notified of new pressure level changes only after a reply
620    /// corresponding to the previous message has been received by the provider.
621    /// If multiple level transitions occur during that time, the watcher will be
622    /// notified of the latest pressure level.
623    ///
624    /// 2. The level changes are edge-triggered, and clients are expected to maintain
625    /// local state to track the current pressure level, if required. For example,
626    /// a job might be notified of a CRITICAL level and drop all its caches as a result.
627    /// Some time after this, it might want to trigger an activity that causes a
628    /// fair amount of memory to be allocated. At this point, the job is expected to
629    /// remember that the last pressure level it saw was CRITICAL, and refrain from
630    /// triggering the memory-intensive activity.
631    ///
632    /// 3. As a performance optimization, the provider may decide to skip sending
633    /// messages for some pressure level changes. For example, when oscillating across
634    /// the NORMAL / WARNING boundary, it might not be worth notifying clients of every
635    /// single transition. The provider might rate-limit messages in this case.
636    /// On a similar note, the provider may decide to send repeated messages at the
637    /// same pressure level, particularly CRITICAL, to indicate that further action
638    /// needs to be taken.
639    pub fn r#on_level_changed(
640        &self,
641        mut level: Level,
642    ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
643        WatcherProxyInterface::r#on_level_changed(self, level)
644    }
645}
646
647impl WatcherProxyInterface for WatcherProxy {
648    type OnLevelChangedResponseFut =
649        fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
650    fn r#on_level_changed(&self, mut level: Level) -> Self::OnLevelChangedResponseFut {
651        fn _decode(
652            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
653        ) -> Result<(), fidl::Error> {
654            let _response = fidl::client::decode_transaction_body::<
655                fidl::encoding::EmptyPayload,
656                fidl::encoding::DefaultFuchsiaResourceDialect,
657                0x55d559533407fed9,
658            >(_buf?)?;
659            Ok(_response)
660        }
661        self.client.send_query_and_decode::<WatcherOnLevelChangedRequest, ()>(
662            (level,),
663            0x55d559533407fed9,
664            fidl::encoding::DynamicFlags::empty(),
665            _decode,
666        )
667    }
668}
669
670pub struct WatcherEventStream {
671    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
672}
673
674impl std::marker::Unpin for WatcherEventStream {}
675
676impl futures::stream::FusedStream for WatcherEventStream {
677    fn is_terminated(&self) -> bool {
678        self.event_receiver.is_terminated()
679    }
680}
681
682impl futures::Stream for WatcherEventStream {
683    type Item = Result<WatcherEvent, fidl::Error>;
684
685    fn poll_next(
686        mut self: std::pin::Pin<&mut Self>,
687        cx: &mut std::task::Context<'_>,
688    ) -> std::task::Poll<Option<Self::Item>> {
689        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
690            &mut self.event_receiver,
691            cx
692        )?) {
693            Some(buf) => std::task::Poll::Ready(Some(WatcherEvent::decode(buf))),
694            None => std::task::Poll::Ready(None),
695        }
696    }
697}
698
699#[derive(Debug)]
700pub enum WatcherEvent {}
701
702impl WatcherEvent {
703    /// Decodes a message buffer as a [`WatcherEvent`].
704    fn decode(
705        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
706    ) -> Result<WatcherEvent, fidl::Error> {
707        let (bytes, _handles) = buf.split_mut();
708        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
709        debug_assert_eq!(tx_header.tx_id, 0);
710        match tx_header.ordinal {
711            _ => Err(fidl::Error::UnknownOrdinal {
712                ordinal: tx_header.ordinal,
713                protocol_name: <WatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
714            }),
715        }
716    }
717}
718
719/// A Stream of incoming requests for fuchsia.memorypressure/Watcher.
720pub struct WatcherRequestStream {
721    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
722    is_terminated: bool,
723}
724
725impl std::marker::Unpin for WatcherRequestStream {}
726
727impl futures::stream::FusedStream for WatcherRequestStream {
728    fn is_terminated(&self) -> bool {
729        self.is_terminated
730    }
731}
732
733impl fidl::endpoints::RequestStream for WatcherRequestStream {
734    type Protocol = WatcherMarker;
735    type ControlHandle = WatcherControlHandle;
736
737    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
738        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
739    }
740
741    fn control_handle(&self) -> Self::ControlHandle {
742        WatcherControlHandle { inner: self.inner.clone() }
743    }
744
745    fn into_inner(
746        self,
747    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
748    {
749        (self.inner, self.is_terminated)
750    }
751
752    fn from_inner(
753        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
754        is_terminated: bool,
755    ) -> Self {
756        Self { inner, is_terminated }
757    }
758}
759
760impl futures::Stream for WatcherRequestStream {
761    type Item = Result<WatcherRequest, fidl::Error>;
762
763    fn poll_next(
764        mut self: std::pin::Pin<&mut Self>,
765        cx: &mut std::task::Context<'_>,
766    ) -> std::task::Poll<Option<Self::Item>> {
767        let this = &mut *self;
768        if this.inner.check_shutdown(cx) {
769            this.is_terminated = true;
770            return std::task::Poll::Ready(None);
771        }
772        if this.is_terminated {
773            panic!("polled WatcherRequestStream after completion");
774        }
775        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
776            |bytes, handles| {
777                match this.inner.channel().read_etc(cx, bytes, handles) {
778                    std::task::Poll::Ready(Ok(())) => {}
779                    std::task::Poll::Pending => return std::task::Poll::Pending,
780                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
781                        this.is_terminated = true;
782                        return std::task::Poll::Ready(None);
783                    }
784                    std::task::Poll::Ready(Err(e)) => {
785                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
786                            e.into(),
787                        ))));
788                    }
789                }
790
791                // A message has been received from the channel
792                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
793
794                std::task::Poll::Ready(Some(match header.ordinal {
795                    0x55d559533407fed9 => {
796                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
797                        let mut req = fidl::new_empty!(
798                            WatcherOnLevelChangedRequest,
799                            fidl::encoding::DefaultFuchsiaResourceDialect
800                        );
801                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<WatcherOnLevelChangedRequest>(&header, _body_bytes, handles, &mut req)?;
802                        let control_handle = WatcherControlHandle { inner: this.inner.clone() };
803                        Ok(WatcherRequest::OnLevelChanged {
804                            level: req.level,
805
806                            responder: WatcherOnLevelChangedResponder {
807                                control_handle: std::mem::ManuallyDrop::new(control_handle),
808                                tx_id: header.tx_id,
809                            },
810                        })
811                    }
812                    _ => Err(fidl::Error::UnknownOrdinal {
813                        ordinal: header.ordinal,
814                        protocol_name:
815                            <WatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
816                    }),
817                }))
818            },
819        )
820    }
821}
822
823/// Watcher protocol
824/// To be implemented by clients who wish to be notified on memory pressure level changes.
825#[derive(Debug)]
826pub enum WatcherRequest {
827    /// Sent to the registered client when the memory pressure level changes.
828    /// `level`: indicates the current memory pressure level.
829    ///
830    /// Will also be invoked on initial connection via `RegisterWatcher`, so that a newly
831    /// registered client can discover the current memory pressure level.
832    ///
833    /// The watcher must immediately reply with a message to acknowledge that it has
834    /// received the level change notification, and has initiated required actions as a
835    /// result. It may then continue to reclaim memory asynchronously after sending
836    /// the acknowledgement.
837    ///
838    /// Some helpful guidelines for clients:
839    /// 1. The watcher will be notified of new pressure level changes only after a reply
840    /// corresponding to the previous message has been received by the provider.
841    /// If multiple level transitions occur during that time, the watcher will be
842    /// notified of the latest pressure level.
843    ///
844    /// 2. The level changes are edge-triggered, and clients are expected to maintain
845    /// local state to track the current pressure level, if required. For example,
846    /// a job might be notified of a CRITICAL level and drop all its caches as a result.
847    /// Some time after this, it might want to trigger an activity that causes a
848    /// fair amount of memory to be allocated. At this point, the job is expected to
849    /// remember that the last pressure level it saw was CRITICAL, and refrain from
850    /// triggering the memory-intensive activity.
851    ///
852    /// 3. As a performance optimization, the provider may decide to skip sending
853    /// messages for some pressure level changes. For example, when oscillating across
854    /// the NORMAL / WARNING boundary, it might not be worth notifying clients of every
855    /// single transition. The provider might rate-limit messages in this case.
856    /// On a similar note, the provider may decide to send repeated messages at the
857    /// same pressure level, particularly CRITICAL, to indicate that further action
858    /// needs to be taken.
859    OnLevelChanged { level: Level, responder: WatcherOnLevelChangedResponder },
860}
861
862impl WatcherRequest {
863    #[allow(irrefutable_let_patterns)]
864    pub fn into_on_level_changed(self) -> Option<(Level, WatcherOnLevelChangedResponder)> {
865        if let WatcherRequest::OnLevelChanged { level, responder } = self {
866            Some((level, responder))
867        } else {
868            None
869        }
870    }
871
872    /// Name of the method defined in FIDL
873    pub fn method_name(&self) -> &'static str {
874        match *self {
875            WatcherRequest::OnLevelChanged { .. } => "on_level_changed",
876        }
877    }
878}
879
880#[derive(Debug, Clone)]
881pub struct WatcherControlHandle {
882    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
883}
884
885impl WatcherControlHandle {
886    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
887        self.inner.shutdown_with_epitaph(status.into())
888    }
889}
890
891impl fidl::endpoints::ControlHandle for WatcherControlHandle {
892    fn shutdown(&self) {
893        self.inner.shutdown()
894    }
895
896    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
897        self.inner.shutdown_with_epitaph(status)
898    }
899
900    fn is_closed(&self) -> bool {
901        self.inner.channel().is_closed()
902    }
903    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
904        self.inner.channel().on_closed()
905    }
906
907    #[cfg(target_os = "fuchsia")]
908    fn signal_peer(
909        &self,
910        clear_mask: zx::Signals,
911        set_mask: zx::Signals,
912    ) -> Result<(), zx_status::Status> {
913        use fidl::Peered;
914        self.inner.channel().signal_peer(clear_mask, set_mask)
915    }
916}
917
918impl WatcherControlHandle {}
919
920#[must_use = "FIDL methods require a response to be sent"]
921#[derive(Debug)]
922pub struct WatcherOnLevelChangedResponder {
923    control_handle: std::mem::ManuallyDrop<WatcherControlHandle>,
924    tx_id: u32,
925}
926
927/// Set the the channel to be shutdown (see [`WatcherControlHandle::shutdown`])
928/// if the responder is dropped without sending a response, so that the client
929/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
930impl std::ops::Drop for WatcherOnLevelChangedResponder {
931    fn drop(&mut self) {
932        self.control_handle.shutdown();
933        // Safety: drops once, never accessed again
934        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
935    }
936}
937
938impl fidl::endpoints::Responder for WatcherOnLevelChangedResponder {
939    type ControlHandle = WatcherControlHandle;
940
941    fn control_handle(&self) -> &WatcherControlHandle {
942        &self.control_handle
943    }
944
945    fn drop_without_shutdown(mut self) {
946        // Safety: drops once, never accessed again due to mem::forget
947        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
948        // Prevent Drop from running (which would shut down the channel)
949        std::mem::forget(self);
950    }
951}
952
953impl WatcherOnLevelChangedResponder {
954    /// Sends a response to the FIDL transaction.
955    ///
956    /// Sets the channel to shutdown if an error occurs.
957    pub fn send(self) -> Result<(), fidl::Error> {
958        let _result = self.send_raw();
959        if _result.is_err() {
960            self.control_handle.shutdown();
961        }
962        self.drop_without_shutdown();
963        _result
964    }
965
966    /// Similar to "send" but does not shutdown the channel if an error occurs.
967    pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
968        let _result = self.send_raw();
969        self.drop_without_shutdown();
970        _result
971    }
972
973    fn send_raw(&self) -> Result<(), fidl::Error> {
974        self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
975            (),
976            self.tx_id,
977            0x55d559533407fed9,
978            fidl::encoding::DynamicFlags::empty(),
979        )
980    }
981}
982
983mod internal {
984    use super::*;
985
986    impl fidl::encoding::ResourceTypeMarker for ProviderRegisterWatcherRequest {
987        type Borrowed<'a> = &'a mut Self;
988        fn take_or_borrow<'a>(
989            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
990        ) -> Self::Borrowed<'a> {
991            value
992        }
993    }
994
995    unsafe impl fidl::encoding::TypeMarker for ProviderRegisterWatcherRequest {
996        type Owned = Self;
997
998        #[inline(always)]
999        fn inline_align(_context: fidl::encoding::Context) -> usize {
1000            4
1001        }
1002
1003        #[inline(always)]
1004        fn inline_size(_context: fidl::encoding::Context) -> usize {
1005            4
1006        }
1007    }
1008
1009    unsafe impl
1010        fidl::encoding::Encode<
1011            ProviderRegisterWatcherRequest,
1012            fidl::encoding::DefaultFuchsiaResourceDialect,
1013        > for &mut ProviderRegisterWatcherRequest
1014    {
1015        #[inline]
1016        unsafe fn encode(
1017            self,
1018            encoder: &mut fidl::encoding::Encoder<
1019                '_,
1020                fidl::encoding::DefaultFuchsiaResourceDialect,
1021            >,
1022            offset: usize,
1023            _depth: fidl::encoding::Depth,
1024        ) -> fidl::Result<()> {
1025            encoder.debug_check_bounds::<ProviderRegisterWatcherRequest>(offset);
1026            // Delegate to tuple encoding.
1027            fidl::encoding::Encode::<ProviderRegisterWatcherRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
1028                (
1029                    <fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<WatcherMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.watcher),
1030                ),
1031                encoder, offset, _depth
1032            )
1033        }
1034    }
1035    unsafe impl<
1036        T0: fidl::encoding::Encode<
1037                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<WatcherMarker>>,
1038                fidl::encoding::DefaultFuchsiaResourceDialect,
1039            >,
1040    >
1041        fidl::encoding::Encode<
1042            ProviderRegisterWatcherRequest,
1043            fidl::encoding::DefaultFuchsiaResourceDialect,
1044        > for (T0,)
1045    {
1046        #[inline]
1047        unsafe fn encode(
1048            self,
1049            encoder: &mut fidl::encoding::Encoder<
1050                '_,
1051                fidl::encoding::DefaultFuchsiaResourceDialect,
1052            >,
1053            offset: usize,
1054            depth: fidl::encoding::Depth,
1055        ) -> fidl::Result<()> {
1056            encoder.debug_check_bounds::<ProviderRegisterWatcherRequest>(offset);
1057            // Zero out padding regions. There's no need to apply masks
1058            // because the unmasked parts will be overwritten by fields.
1059            // Write the fields.
1060            self.0.encode(encoder, offset + 0, depth)?;
1061            Ok(())
1062        }
1063    }
1064
1065    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1066        for ProviderRegisterWatcherRequest
1067    {
1068        #[inline(always)]
1069        fn new_empty() -> Self {
1070            Self {
1071                watcher: fidl::new_empty!(
1072                    fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<WatcherMarker>>,
1073                    fidl::encoding::DefaultFuchsiaResourceDialect
1074                ),
1075            }
1076        }
1077
1078        #[inline]
1079        unsafe fn decode(
1080            &mut self,
1081            decoder: &mut fidl::encoding::Decoder<
1082                '_,
1083                fidl::encoding::DefaultFuchsiaResourceDialect,
1084            >,
1085            offset: usize,
1086            _depth: fidl::encoding::Depth,
1087        ) -> fidl::Result<()> {
1088            decoder.debug_check_bounds::<Self>(offset);
1089            // Verify that padding bytes are zero.
1090            fidl::decode!(
1091                fidl::encoding::Endpoint<fidl::endpoints::ClientEnd<WatcherMarker>>,
1092                fidl::encoding::DefaultFuchsiaResourceDialect,
1093                &mut self.watcher,
1094                decoder,
1095                offset + 0,
1096                _depth
1097            )?;
1098            Ok(())
1099        }
1100    }
1101}