1use crate::{
6 AnyHandle, AsHandleRef, Channel, ChannelMessageStream, ChannelWriter, Error, Handle,
7 HandleInfo, MessageBuf,
8};
9use fidl::epitaph::ChannelEpitaphExt;
10use fidl_fuchsia_fdomain as proto;
11use futures::{Stream, StreamExt, TryStream};
12use std::cell::RefCell;
13use std::marker::PhantomData;
14use std::sync::{Arc, Mutex};
15use std::task::Poll;
16
17pub trait FDomainFlexibleIntoResult<T> {
18 fn into_result_fdomain<P: ProtocolMarker>(
19 self,
20 method_name: &'static str,
21 ) -> Result<T, fidl::Error>;
22}
23
24impl<T> FDomainFlexibleIntoResult<T> for fidl::encoding::Flexible<T> {
25 fn into_result_fdomain<P: ProtocolMarker>(
26 self,
27 method_name: &'static str,
28 ) -> Result<T, fidl::Error> {
29 match self {
30 fidl::encoding::Flexible::Ok(ok) => Ok(ok),
31 fidl::encoding::Flexible::FrameworkErr(fidl::encoding::FrameworkErr::UnknownMethod) => {
32 Err(fidl::Error::UnsupportedMethod { method_name, protocol_name: P::DEBUG_NAME })
33 }
34 }
35 }
36}
37
38impl<T, E> FDomainFlexibleIntoResult<Result<T, E>> for fidl::encoding::FlexibleResult<T, E> {
39 fn into_result_fdomain<P: ProtocolMarker>(
40 self,
41 method_name: &'static str,
42 ) -> Result<Result<T, E>, fidl::Error> {
43 match self {
44 fidl::encoding::FlexibleResult::Ok(ok) => Ok(Ok(ok)),
45 fidl::encoding::FlexibleResult::DomainErr(err) => Ok(Err(err)),
46 fidl::encoding::FlexibleResult::FrameworkErr(
47 fidl::encoding::FrameworkErr::UnknownMethod,
48 ) => Err(fidl::Error::UnsupportedMethod { method_name, protocol_name: P::DEBUG_NAME }),
49 }
50 }
51}
52
53#[derive(Debug)]
54pub struct FDomainProxyChannel(Mutex<ChannelMessageStream>, ChannelWriter);
55
56impl FDomainProxyChannel {
57 pub fn on_closed(&self) -> crate::OnFDomainSignals {
58 self.1.as_channel().on_closed()
59 }
60
61 pub fn read_etc(
62 &self,
63 ctx: &mut std::task::Context<'_>,
64 bytes: &mut Vec<u8>,
65 handles: &mut Vec<HandleInfo>,
66 ) -> Poll<Result<(), Option<crate::Error>>> {
67 let Some(got) = std::task::ready!(self.0.lock().unwrap().poll_next_unpin(ctx)) else {
68 return Poll::Ready(Err(Some(Error::StreamingAborted)));
69 };
70
71 match got {
72 Ok(got) => {
73 *bytes = got.bytes;
74 *handles = got.handles;
75 Poll::Ready(Ok(()))
76 }
77 Err(Error::FDomain(proto::Error::TargetError(i)))
78 if i == fidl::Status::PEER_CLOSED.into_raw() =>
79 {
80 Poll::Ready(Err(None))
81 }
82 Err(e) => Poll::Ready(Err(Some(e))),
83 }
84 }
85}
86
87impl ::fidl::encoding::ProxyChannelBox<FDomainResourceDialect> for FDomainProxyChannel {
88 fn recv_etc_from(
89 &self,
90 ctx: &mut std::task::Context<'_>,
91 buf: &mut MessageBuf,
92 ) -> Poll<Result<(), Option<Error>>> {
93 let Some(got) = std::task::ready!(self.0.lock().unwrap().poll_next_unpin(ctx)) else {
94 return Poll::Ready(Err(Some(Error::StreamingAborted)));
95 };
96
97 match got {
98 Ok(got) => {
99 *buf = got;
100 Poll::Ready(Ok(()))
101 }
102 Err(Error::FDomain(proto::Error::TargetError(i)))
103 if i == fidl::Status::PEER_CLOSED.into_raw() =>
104 {
105 Poll::Ready(Err(None))
106 }
107 Err(e) => Poll::Ready(Err(Some(e))),
108 }
109 }
110
111 fn write_etc(&self, bytes: &[u8], handles: &mut [HandleInfo]) -> Result<(), Option<Error>> {
112 let mut handle_ops = Vec::new();
113 for handle in handles {
114 handle_ops.push(crate::channel::HandleOp::Move(
115 std::mem::replace(&mut handle.handle, AnyHandle::invalid()).into(),
116 handle.rights,
117 ));
118 }
119 let _ = self.1.fdomain_write_etc(bytes, handle_ops);
120 Ok(())
121 }
122
123 fn is_closed(&self) -> bool {
124 self.0.lock().unwrap().is_closed()
125 }
126
127 fn unbox(self) -> Channel {
128 self.0.into_inner().unwrap().rejoin(self.1)
129 }
130
131 fn as_channel(&self) -> &Channel {
132 self.1.as_channel()
133 }
134}
135
136#[derive(Debug, Copy, Clone, Default)]
137pub struct FDomainResourceDialect;
138impl ::fidl::encoding::ResourceDialect for FDomainResourceDialect {
139 type Handle = Handle;
140 type MessageBufEtc = MessageBuf;
141 type ProxyChannel = Channel;
142
143 #[inline]
144 fn with_tls_buf<R>(f: impl FnOnce(&mut ::fidl::encoding::TlsBuf<Self>) -> R) -> R {
145 thread_local!(static TLS_BUF: RefCell<::fidl::encoding::TlsBuf<FDomainResourceDialect>> =
146 RefCell::new(::fidl::encoding::TlsBuf::default()));
147 TLS_BUF.with(|buf| f(&mut buf.borrow_mut()))
148 }
149}
150
151impl ::fidl::encoding::MessageBufFor<FDomainResourceDialect> for MessageBuf {
152 fn new() -> MessageBuf {
153 MessageBuf { bytes: Vec::new(), handles: Vec::new() }
154 }
155
156 fn split_mut(&mut self) -> (&mut Vec<u8>, &mut Vec<HandleInfo>) {
157 (&mut self.bytes, &mut self.handles)
158 }
159}
160
161impl Into<::fidl::TransportError> for Error {
162 fn into(self) -> ::fidl::TransportError {
163 match self {
164 Error::FDomain(proto::Error::TargetError(i)) => {
165 ::fidl::TransportError::Status(fidl::Status::from_raw(i))
166 }
167 Error::SocketWrite(proto::WriteSocketError {
168 error: proto::Error::TargetError(i),
169 ..
170 }) => ::fidl::TransportError::Status(fidl::Status::from_raw(i)),
171 Error::ChannelWrite(proto::WriteChannelError::Error(proto::Error::TargetError(i))) => {
172 ::fidl::TransportError::Status(fidl::Status::from_raw(i))
173 }
174 Error::ChannelWrite(proto::WriteChannelError::OpErrors(ops)) => {
175 let Some(op) = ops.into_iter().find_map(|x| x) else {
176 let err = Box::<dyn std::error::Error + Send + Sync>::from(
177 "Channel write handle operation reported failure with no status!"
178 .to_owned(),
179 );
180 return ::fidl::TransportError::Other(err.into());
181 };
182 let op = *op;
183 Error::FDomain(op).into()
184 }
185 other => ::fidl::TransportError::Other(std::sync::Arc::new(other)),
186 }
187 }
188}
189
190impl ::fidl::encoding::ProxyChannelFor<FDomainResourceDialect> for Channel {
191 type Boxed = FDomainProxyChannel;
192 type Error = Error;
193 type HandleDisposition = HandleInfo;
194
195 fn boxed(self) -> Self::Boxed {
196 let (a, b) = self.stream().unwrap();
197 FDomainProxyChannel(Mutex::new(a), b)
198 }
199
200 fn write_etc(&self, bytes: &[u8], handles: &mut [HandleInfo]) -> Result<(), Option<Error>> {
201 let mut handle_ops = Vec::new();
202 for handle in handles {
203 handle_ops.push(crate::channel::HandleOp::Move(
204 std::mem::replace(&mut handle.handle, AnyHandle::invalid()).into(),
205 handle.rights,
206 ));
207 }
208 let _ = self.fdomain_write_etc(bytes, handle_ops);
209 Ok(())
210 }
211}
212
213impl ::fidl::epitaph::ChannelLike for Channel {
214 fn write_epitaph(&self, bytes: &[u8]) -> Result<(), ::fidl::TransportError> {
215 let _ = self.write(bytes, vec![]);
216 Ok(())
217 }
218}
219
220impl ::fidl::encoding::HandleFor<FDomainResourceDialect> for Handle {
221 type HandleInfo = HandleInfo;
224
225 fn invalid() -> Self {
226 Handle::invalid()
227 }
228
229 fn is_invalid(&self) -> bool {
230 self.client.upgrade().is_none()
231 }
232}
233
234impl ::fidl::encoding::HandleDispositionFor<FDomainResourceDialect> for HandleInfo {
235 fn from_handle(handle: Handle, object_type: fidl::ObjectType, rights: fidl::Rights) -> Self {
236 HandleInfo { handle: AnyHandle::from_handle(handle, object_type), rights }
237 }
238}
239
240impl ::fidl::encoding::HandleInfoFor<FDomainResourceDialect> for HandleInfo {
241 fn consume(
242 &mut self,
243 expected_object_type: fidl::ObjectType,
244 expected_rights: fidl::Rights,
245 ) -> Result<Handle, ::fidl::Error> {
246 let handle_info = std::mem::replace(
247 self,
248 HandleInfo {
249 handle: crate::AnyHandle::Unknown(Handle::invalid(), fidl::ObjectType::NONE),
250 rights: fidl::Rights::empty(),
251 },
252 );
253 let received_object_type = handle_info.handle.object_type();
254 if expected_object_type != fidl::ObjectType::NONE
255 && received_object_type != fidl::ObjectType::NONE
256 && expected_object_type != received_object_type
257 {
258 return Err(fidl::Error::IncorrectHandleSubtype {
259 expected: fidl::ObjectType::NONE,
263 received: fidl::ObjectType::NONE,
264 });
265 }
266
267 let received_rights = handle_info.rights;
268 if expected_rights != fidl::Rights::SAME_RIGHTS
269 && received_rights != fidl::Rights::SAME_RIGHTS
270 && expected_rights != received_rights
271 {
272 if !received_rights.contains(expected_rights) {
273 return Err(fidl::Error::MissingExpectedHandleRights {
274 missing_rights: fidl::Rights::empty(),
276 });
277 }
278
279 }
283 Ok(handle_info.handle.into())
284 }
285
286 fn drop_in_place(&mut self) {
287 *self = HandleInfo {
288 handle: crate::AnyHandle::Unknown(Handle::invalid(), fidl::ObjectType::NONE),
289 rights: fidl::Rights::empty(),
290 };
291 }
292}
293
294impl ::fidl::encoding::EncodableAsHandle for crate::Event {
295 type Dialect = FDomainResourceDialect;
296}
297
298impl ::fidl::encoding::EncodableAsHandle for crate::EventPair {
299 type Dialect = FDomainResourceDialect;
300}
301
302impl ::fidl::encoding::EncodableAsHandle for crate::Socket {
303 type Dialect = FDomainResourceDialect;
304}
305
306impl ::fidl::encoding::EncodableAsHandle for crate::Channel {
307 type Dialect = FDomainResourceDialect;
308}
309
310impl ::fidl::encoding::EncodableAsHandle for crate::Handle {
311 type Dialect = FDomainResourceDialect;
312}
313
314impl<T: ProtocolMarker> ::fidl::encoding::EncodableAsHandle for ClientEnd<T> {
315 type Dialect = FDomainResourceDialect;
316}
317
318impl<T: ProtocolMarker> ::fidl::encoding::EncodableAsHandle for ServerEnd<T> {
319 type Dialect = FDomainResourceDialect;
320}
321
322pub trait ProtocolMarker: Sized + Send + Sync + 'static {
325 type Proxy: Proxy<Protocol = Self>;
328
329 type RequestStream: RequestStream<Protocol = Self>;
331
332 const DEBUG_NAME: &'static str;
337}
338
339pub trait DiscoverableProtocolMarker: ProtocolMarker {
352 const PROTOCOL_NAME: &'static str = <Self as ProtocolMarker>::DEBUG_NAME;
354}
355
356pub trait Proxy: Sized + Send + Sync {
358 type Protocol: ProtocolMarker<Proxy = Self>;
360
361 fn from_channel(inner: Channel) -> Self;
363
364 fn into_channel(self) -> Result<Channel, Self>;
370
371 fn as_channel(&self) -> &Channel;
377
378 fn domain(&self) -> Arc<crate::Client> {
383 self.as_channel().domain()
384 }
385}
386
387pub trait RequestStream: Sized + Send + Stream + TryStream<Error = fidl::Error> + Unpin {
389 type Protocol: ProtocolMarker<RequestStream = Self>;
391
392 type ControlHandle: ControlHandle;
394
395 fn control_handle(&self) -> Self::ControlHandle;
398
399 fn from_channel(inner: Channel) -> Self;
401
402 fn into_inner(self) -> (std::sync::Arc<fidl::ServeInner<FDomainResourceDialect>>, bool);
404
405 fn from_inner(
407 inner: std::sync::Arc<fidl::ServeInner<FDomainResourceDialect>>,
408 is_terminated: bool,
409 ) -> Self;
410}
411
412pub trait ControlHandle {
415 fn shutdown(&self);
418
419 fn is_closed(&self) -> bool;
421
422 fn on_closed(&self) -> crate::OnFDomainSignals;
425}
426
427pub trait Responder {
430 type ControlHandle: ControlHandle;
432
433 fn control_handle(&self) -> &Self::ControlHandle;
435
436 fn drop_without_shutdown(self);
441}
442
443pub type Request<Marker> = <<Marker as ProtocolMarker>::RequestStream as futures::TryStream>::Ok;
445
446#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
448pub struct ClientEnd<T: ProtocolMarker> {
449 inner: Channel,
450 phantom: PhantomData<T>,
451}
452
453impl<T: ProtocolMarker> ClientEnd<T> {
454 pub fn new(inner: Channel) -> Self {
456 ClientEnd { inner, phantom: PhantomData }
457 }
458
459 pub fn channel(&self) -> &Channel {
461 &self.inner
462 }
463
464 pub fn into_channel(self) -> Channel {
466 self.inner
467 }
468}
469
470impl<'c, T: ProtocolMarker> ClientEnd<T> {
471 pub fn into_proxy(self) -> T::Proxy {
473 T::Proxy::from_channel(self.inner)
474 }
475}
476
477impl<T: ProtocolMarker> From<ClientEnd<T>> for Handle {
478 fn from(client: ClientEnd<T>) -> Handle {
479 client.into_channel().into()
480 }
481}
482
483impl<T: ProtocolMarker> From<Handle> for ClientEnd<T> {
484 fn from(handle: Handle) -> Self {
485 ClientEnd { inner: handle.into(), phantom: PhantomData }
486 }
487}
488
489impl<T: ProtocolMarker> From<Channel> for ClientEnd<T> {
490 fn from(chan: Channel) -> Self {
491 ClientEnd { inner: chan, phantom: PhantomData }
492 }
493}
494
495impl<T: ProtocolMarker> AsHandleRef for ClientEnd<T> {
496 fn as_handle_ref(&self) -> crate::HandleRef<'_> {
497 AsHandleRef::as_handle_ref(&self.inner)
498 }
499
500 fn object_type() -> fidl::ObjectType {
501 <Channel as AsHandleRef>::object_type()
502 }
503}
504
505#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
507pub struct ServerEnd<T: ProtocolMarker> {
508 inner: Channel,
509 phantom: PhantomData<T>,
510}
511
512impl<T: ProtocolMarker> ServerEnd<T> {
513 pub fn new(inner: Channel) -> ServerEnd<T> {
515 ServerEnd { inner, phantom: PhantomData }
516 }
517
518 pub fn channel(&self) -> &Channel {
520 &self.inner
521 }
522
523 pub fn into_channel(self) -> Channel {
525 self.inner
526 }
527
528 pub fn into_stream(self) -> T::RequestStream
530 where
531 T: ProtocolMarker,
532 {
533 T::RequestStream::from_channel(self.inner)
534 }
535
536 pub fn into_stream_and_control_handle(
539 self,
540 ) -> (T::RequestStream, <T::RequestStream as RequestStream>::ControlHandle)
541 where
542 T: ProtocolMarker,
543 {
544 let stream = self.into_stream();
545 let control_handle = stream.control_handle();
546 (stream, control_handle)
547 }
548
549 pub fn close_with_epitaph(self, status: fidl::Status) -> Result<(), fidl::Error> {
551 self.inner.close_with_epitaph(status)
552 }
553}
554
555impl<T: ProtocolMarker> From<ServerEnd<T>> for Handle {
556 fn from(server: ServerEnd<T>) -> Handle {
557 server.into_channel().into()
558 }
559}
560
561impl<T: ProtocolMarker> From<Handle> for ServerEnd<T> {
562 fn from(handle: Handle) -> Self {
563 ServerEnd { inner: handle.into(), phantom: PhantomData }
564 }
565}
566
567impl<T: ProtocolMarker> From<Channel> for ServerEnd<T> {
568 fn from(chan: Channel) -> Self {
569 ServerEnd { inner: chan, phantom: PhantomData }
570 }
571}
572
573impl<T: ProtocolMarker> AsHandleRef for ServerEnd<T> {
574 fn as_handle_ref(&self) -> crate::HandleRef<'_> {
575 AsHandleRef::as_handle_ref(&self.inner)
576 }
577
578 fn object_type() -> fidl::ObjectType {
579 <Channel as AsHandleRef>::object_type()
580 }
581}