rsbinder/
macros.rs

1// Copyright 2022 Jeff Kim <hiking90@gmail.com>
2// SPDX-License-Identifier: Apache-2.0
3
4/*
5 * Copyright (C) 2020 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#[cfg(feature = "async")]
21#[macro_export]
22macro_rules! __declare_binder_interface {
23    {
24        $interface:path[$descriptor:expr] {
25            native: {
26                $native:ident($on_transact:path),
27                $(adapter: $native_adapter:ident,)?
28                $(r#async: $native_async:ident,)?
29            },
30            proxy: $proxy:ident {
31                $($fname:ident: $fty:ty = $finit:expr),*
32            },
33            $(r#async: $async_interface:ident,)?
34            stability: $stability:expr,
35        }
36    } => {
37        $(
38            pub trait $native_adapter {
39                fn as_sync(&self) -> &dyn $interface;
40                #[allow(dead_code)]
41                fn as_async(&self) -> &dyn $native_async;
42            }
43
44            pub struct $native(Box<dyn $native_adapter + Send + Sync + 'static>);
45
46            impl $native {
47                /// Create a new binder service.
48                pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
49                    struct Wrapper<T> {
50                        _inner: T,
51                    }
52                    impl<T> $native_adapter for Wrapper<T>
53                    where
54                        T: $interface + Sync + Send + 'static,
55                    {
56                        fn as_sync(&self) -> &dyn $interface { &self._inner }
57                        fn as_async(&self) -> &dyn $native_async {
58                            unreachable!("{} doesn't support async interface.", stringify!($interface))
59                        }
60                    }
61                    let binder = $crate::native::Binder::new_with_stability($native(Box::new(Wrapper {_inner: inner})), $stability);
62                    $crate::Strong::new(Box::new(binder))
63                }
64            }
65
66            impl $crate::Remotable for $native {
67                fn descriptor() -> &'static str where Self: Sized {
68                    $descriptor
69                }
70
71                fn on_transact(&self, code: $crate::TransactionCode, reader: &mut $crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
72                    $on_transact(self.0.as_sync(), code, reader, reply)
73                }
74
75                fn on_dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> $crate::Result<()> {
76                    self.0.as_sync().dump(_writer, _args)
77                }
78            }
79        )?
80
81        $(
82            // Async interface trait implementations.
83            impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
84                fn try_from(ibinder: $crate::SIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
85                    match <$proxy as $crate::Proxy>::from_binder(ibinder.clone()) {
86                        Some(proxy) => Ok($crate::Strong::new(Box::new(proxy))),
87                        None => {
88                            match $crate::native::Binder::<$native>::try_from(ibinder) {
89                                Ok(native) => {
90                                    Ok($crate::Strong::new(Box::new(native.clone())))
91                                }
92                                Err(err) => Err(err),
93                            }
94                        }
95                    }
96                }
97            }
98
99            impl<P: $crate::BinderAsyncPool> $crate::Serialize for dyn $async_interface<P> + '_ {
100                fn serialize(&self, parcel: &mut $crate::Parcel) -> std::result::Result<(), $crate::StatusCode> {
101                    let binder = $crate::Interface::as_binder(self);
102                    parcel.write(&binder)
103                }
104            }
105
106            impl<P: $crate::BinderAsyncPool> $crate::SerializeOption for dyn $async_interface<P> + '_ {
107                fn serialize_option(this: Option<&Self>, parcel: &mut $crate::Parcel) -> std::result::Result<(), $crate::StatusCode> {
108                    parcel.write(&this.map($crate::Interface::as_binder))
109                }
110            }
111
112            impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
113                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114                    f.pad(stringify!($async_interface))
115                }
116            }
117
118            // / Convert a &dyn $async_interface to Strong<dyn $async_interface>
119            // impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
120            //     type Owned = $crate::Strong<dyn $async_interface<P>>;
121            //     fn to_owned(&self) -> Self::Owned {
122            //         self.as_binder().into_interface()
123            //             .expect(concat!("Error cloning interface ", stringify!($async_interface)))
124            //     }
125            // }
126
127            impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface {
128                type Target = dyn $async_interface<P>;
129            }
130
131            impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> {
132                type Target = dyn $interface;
133            }
134        )?
135    };
136}
137
138#[cfg(not(feature = "async"))]
139#[macro_export]
140macro_rules! __declare_binder_interface {
141    {
142        $interface:path[$descriptor:expr] {
143            native: {
144                $native:ident($on_transact:path),
145                $(adapter: $native_adapter:ident,)?
146                $(r#async: $native_async:ident,)?
147            },
148            proxy: $proxy:ident {
149                $($fname:ident: $fty:ty = $finit:expr),*
150            },
151            $(r#async: $async_interface:ident,)?
152            stability: $stability:expr,
153        }
154    } => {
155        pub struct $native(Box<dyn $interface + Send + Sync + 'static>);
156
157        impl $native {
158            /// Create a new binder service.
159            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
160                let binder = $crate::native::Binder::new_with_stability($native(Box::new(inner)), $stability);
161                $crate::Strong::new(Box::new(binder))
162            }
163        }
164
165        impl $crate::Remotable for $native {
166            fn descriptor() -> &'static str where Self: Sized {
167                $descriptor
168            }
169
170            fn on_transact(&self, code: $crate::TransactionCode, reader: &mut $crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
171                $on_transact(&*self.0, code, reader, reply)
172            }
173
174            fn on_dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> $crate::Result<()> {
175                self.0.dump(_writer, _args)
176            }
177        }
178    };
179}
180
181/// Declare a binder interface.
182///
183/// This is mainly used internally by the AIDL compiler.
184#[macro_export]
185macro_rules! declare_binder_interface {
186    {
187        $interface:path[$descriptor:expr] {
188            native: {
189                $native:ident($on_transact:path),
190                $(adapter: $native_adapter:ident,)?
191                $(r#async: $native_async:ident,)?
192            },
193            proxy: $proxy:ident,
194            $(r#async: $async_interface:ident,)?
195        }
196    } => {
197        $crate::declare_binder_interface! {
198            $interface[$descriptor] {
199                native: {
200                    $native($on_transact),
201                    $(adapter: $native_adapter,)?
202                    $(r#async: $native_async,)?
203                },
204                proxy: $proxy {},
205                $(r#async: $async_interface,)?
206                stability: $crate::Stability::default(),
207            }
208        }
209    };
210
211    {
212        $interface:path[$descriptor:expr] {
213            native: {
214                $native:ident($on_transact:path),
215                $(adapter: $native_adapter:ident,)?
216                $(r#async: $native_async:ident,)?
217            },
218            proxy: $proxy:ident,
219            $(r#async: $async_interface:ident,)?
220            stability: $stability:expr,
221        }
222    } => {
223        $crate::declare_binder_interface! {
224            $interface[$descriptor] {
225                native: {
226                    $native($on_transact),
227                    $(adapter: $native_adapter,)?
228                    $(r#async: $native_async,)?
229                },
230                proxy: $proxy {},
231                $(r#async: $async_interface,)?
232                stability: $stability,
233            }
234        }
235    };
236
237    {
238        $interface:path[$descriptor:expr] {
239            native: {
240                $native:ident($on_transact:path),
241                $(adapter: $native_adapter:ident,)?
242                $(r#async: $native_async:ident,)?
243            },
244            proxy: $proxy:ident {
245                $($fname:ident: $fty:ty = $finit:expr),*
246            },
247            $(r#async: $async_interface:ident,)?
248        }
249    } => {
250        $crate::declare_binder_interface! {
251            $interface[$descriptor] {
252                native: {
253                    $native($on_transact),
254                    $(adapter: $native_adapter,)?
255                    $(r#async: $native_async,)?
256                },
257                proxy: $proxy {
258                    $($fname: $fty = $finit),*
259                },
260                $(r#async: $async_interface,)?
261                stability: $crate::Stability::default(),
262            }
263        }
264    };
265
266    {
267        $interface:path[$descriptor:expr] {
268            native: {
269                $native:ident($on_transact:path),
270                $(adapter: $native_adapter:ident,)?
271                $(r#async: $native_async:ident,)?
272            },
273            proxy: $proxy:ident {
274                $($fname:ident: $fty:ty = $finit:expr),*
275            },
276            $(r#async: $async_interface:ident,)?
277            stability: $stability:expr,
278        }
279    } => {
280        $crate::declare_binder_interface! {
281            $interface[$descriptor] {
282                @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
283                native: {
284                    $native($on_transact),
285                    $(adapter: $native_adapter,)?
286                    $(r#async: $native_async,)?
287                },
288                @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
289                proxy: $proxy {
290                    $($fname: $fty = $finit),*
291                },
292                $(r#async: $async_interface,)?
293                stability: $stability,
294            }
295        }
296    };
297
298    {
299        $interface:path[$descriptor:expr] {
300            @doc[$native_doc:expr]
301            native: {
302                $native:ident($on_transact:path),
303                $(adapter: $native_adapter:ident,)?
304                $(r#async: $native_async:ident,)?
305            },
306            @doc[$proxy_doc:expr]
307            proxy: $proxy:ident {
308                $($fname:ident: $fty:ty = $finit:expr),*
309            },
310            $( r#async: $async_interface:ident, )?
311
312            stability: $stability:expr,
313        }
314    } => {
315        #[doc = $proxy_doc]
316        pub struct $proxy {
317            binder: $crate::SIBinder,
318            $($fname: $fty,)*
319        }
320
321        impl $crate::Interface for $proxy {
322            fn as_binder(&self) -> $crate::SIBinder {
323                self.binder.clone()
324            }
325        }
326
327        impl $crate::Proxy for $proxy
328        where
329            $proxy: $interface,
330        {
331            fn descriptor() -> &'static str {
332                $descriptor
333            }
334
335            fn from_binder(binder: $crate::SIBinder) -> std::option::Option<Self> {
336                if binder.descriptor() != $descriptor {
337                    return None
338                }
339                if let Some(_) = binder.as_proxy() {
340                    Some(Self { binder, $($fname: $finit),* })
341                } else {
342                    None
343                }
344            }
345        }
346
347        $crate::__declare_binder_interface!{
348            $interface[$descriptor] {
349                native: {
350                    $native($on_transact),
351                    $(adapter: $native_adapter,)?
352                    $(r#async: $native_async,)?
353                },
354                proxy: $proxy {
355                    $($fname: $fty = $finit),*
356                },
357                $(r#async: $async_interface,)?
358                stability: $stability,
359            }
360        }
361
362        impl $crate::FromIBinder for dyn $interface {
363            fn try_from(binder: $crate::SIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
364                match <$proxy as $crate::Proxy>::from_binder(binder.clone()) {
365                    Some(proxy) => Ok($crate::Strong::new(Box::new(proxy))),
366                    None => {
367                        match $crate::native::Binder::<$native>::try_from(binder) {
368                            Ok(native) => Ok($crate::Strong::new(Box::new(native.clone()))),
369                            Err(err) => Err(err),
370                        }
371                    }
372                }
373            }
374        }
375
376        impl $crate::parcelable::Serialize for dyn $interface
377        where
378            dyn $interface: $crate::Interface
379        {
380            fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
381                let binder = $crate::Interface::as_binder(self);
382                parcel.write(&binder)?;
383                Ok(())
384            }
385        }
386
387        impl $crate::parcelable::SerializeOption for dyn $interface {
388            fn serialize_option(this: Option<&Self>, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
389                parcel.write(&this.map($crate::Interface::as_binder))
390            }
391        }
392
393        impl std::fmt::Debug for dyn $interface + '_ {
394            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
395                f.pad(stringify!($interface))
396            }
397        }
398    }
399}
400
401/// Implement `Serialize` trait and friends for a parcelable
402///
403/// This is an internal macro used by the AIDL compiler to implement
404/// `Serialize`, `SerializeArray` and `SerializeOption` for
405/// structured parcelables. The target type must implement the
406/// `Parcelable` trait.
407#[macro_export]
408macro_rules! impl_serialize_for_parcelable {
409    ($parcelable:ident) => {
410        impl $crate::Serialize for $parcelable {
411            fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
412                <Self as $crate::SerializeOption>::serialize_option(Some(self), parcel)
413            }
414        }
415
416        impl $crate::SerializeArray for $parcelable {}
417
418        impl $crate::SerializeOption for $parcelable {
419            fn serialize_option(
420                this: Option<&Self>,
421                parcel: &mut $crate::Parcel,
422            ) -> $crate::Result<()> {
423                if let Some(this) = this {
424                    use $crate::Parcelable;
425                    parcel.write(&$crate::NON_NULL_PARCELABLE_FLAG)?;
426                    this.write_to_parcel(parcel)
427                } else {
428                    parcel.write(&$crate::NULL_PARCELABLE_FLAG)
429                }
430            }
431        }
432    };
433}
434
435/// Implement `Deserialize` trait and friends for a parcelable
436///
437/// This is an internal macro used by the AIDL compiler to implement
438/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
439/// structured parcelables. The target type must implement the
440/// `Parcelable` trait.
441#[macro_export]
442macro_rules! impl_deserialize_for_parcelable {
443    ($parcelable:ident) => {
444        impl $crate::Deserialize for $parcelable {
445            fn deserialize(parcel: &mut $crate::Parcel) -> $crate::Result<Self> {
446                $crate::DeserializeOption::deserialize_option(parcel)
447                    .transpose()
448                    .unwrap_or(Err($crate::StatusCode::UnexpectedNull.into()))
449            }
450            fn deserialize_from(&mut self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
451                let status: i32 = parcel.read()?;
452                if status == $crate::NULL_PARCELABLE_FLAG {
453                    Err($crate::StatusCode::UnexpectedNull.into())
454                } else {
455                    use $crate::Parcelable;
456                    self.read_from_parcel(parcel)
457                }
458            }
459        }
460
461        impl $crate::DeserializeArray for $parcelable {}
462
463        impl $crate::DeserializeOption for $parcelable {
464            fn deserialize_option(parcel: &mut $crate::Parcel) -> $crate::Result<Option<Self>> {
465                let mut result = None;
466                Self::deserialize_option_from(&mut result, parcel)?;
467                Ok(result)
468            }
469            fn deserialize_option_from(
470                this: &mut Option<Self>,
471                parcel: &mut $crate::Parcel,
472            ) -> $crate::Result<()> {
473                let status: i32 = parcel.read()?;
474                if status == $crate::NULL_PARCELABLE_FLAG {
475                    *this = None;
476                    Ok(())
477                } else {
478                    use $crate::Parcelable;
479                    this.get_or_insert_with(Self::default)
480                        .read_from_parcel(parcel)
481                }
482            }
483        }
484    };
485}
486
487/// Declare an AIDL enumeration.
488///
489/// This is mainly used internally by the AIDL compiler.
490#[macro_export]
491macro_rules! declare_binder_enum {
492    {
493        $( #[$attr:meta] )*
494        $enum:ident : [$backing:ty; $size:expr] {
495            $( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
496        }
497    } => {
498        $( #[$attr] )*
499        #[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
500        #[allow(missing_docs)]
501        pub struct $enum(pub $backing);
502        impl $enum {
503            $( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
504
505            #[inline(always)]
506            #[allow(missing_docs)]
507            pub const fn enum_values() -> [Self; $size] {
508                [$(Self::$name),*]
509            }
510        }
511
512        impl $crate::Serialize for $enum {
513            fn serialize(&self, parcel: &mut $crate::Parcel) -> $crate::Result<()> {
514                parcel.write(&self.0)
515            }
516        }
517
518        impl $crate::SerializeArray for $enum {
519            fn serialize_array(slice: &[Self], parcel: &mut $crate::Parcel) -> $crate::Result<()> {
520                let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
521                <$backing as $crate::SerializeArray>::serialize_array(&v[..], parcel)
522            }
523        }
524
525        impl $crate::Deserialize for $enum {
526            fn deserialize(parcel: &mut $crate::Parcel) -> $crate::Result<Self> {
527                let res = parcel.read().map(Self);
528                res
529            }
530        }
531
532        impl $crate::DeserializeArray for $enum {
533            fn deserialize_array(parcel: &mut $crate::Parcel) -> $crate::Result<Option<Vec<Self>>> {
534                let v: Option<Vec<$backing>> =
535                    <$backing as $crate::DeserializeArray>::deserialize_array(parcel)?;
536                Ok(v.map(|v| v.into_iter().map(Self).collect()))
537            }
538        }
539    };
540}
541
542#[cfg(test)]
543mod tests {
544    use crate::{Binder, Interface, Parcel, Result, TransactionCode};
545
546    pub trait IEcho: Interface {
547        fn echo(&self, echo: &str) -> Result<String>;
548    }
549
550    pub trait IEchoAsyncService: Interface {
551        #[allow(dead_code)]
552        fn echo(&self, echo: &str) -> Result<String>;
553    }
554
555    declare_binder_interface! {
556        IEcho["my.echo"] {
557            native: {
558                BnEcho(on_transact),
559                adapter: BnEchoAdapter,
560                r#async: IEchoAsyncService,
561            },
562            proxy: BpEcho{},
563        }
564    }
565
566    #[allow(dead_code)]
567    impl IEcho for Binder<BnEcho> {
568        #[cfg(feature = "async")]
569        fn echo(&self, echo: &str) -> Result<String> {
570            self.0.as_sync().echo(echo)
571        }
572        #[cfg(not(feature = "async"))]
573        fn echo(&self, echo: &str) -> Result<String> {
574            self.0.echo(echo)
575        }
576    }
577
578    impl IEcho for BpEcho {
579        fn echo(&self, _echo: &str) -> Result<String> {
580            unimplemented!("BpEcho::echo")
581        }
582    }
583
584    fn on_transact(
585        _service: &dyn IEcho,
586        _code: TransactionCode,
587        _data: &mut Parcel,
588        _reply: &mut Parcel,
589    ) -> Result<()> {
590        // ...
591        Ok(())
592    }
593
594    struct EchoService {}
595
596    impl Interface for EchoService {}
597
598    impl IEcho for EchoService {
599        fn echo(&self, echo: &str) -> Result<String> {
600            Ok(echo.to_owned())
601        }
602    }
603
604    #[test]
605    fn test_declare_binder_interface() {
606        let _ = BnEcho::new_binder(EchoService {});
607    }
608
609    #[cfg(feature = "async")]
610    #[test]
611    fn test_try_from() {
612        use async_trait::async_trait;
613
614        #[allow(dead_code)]
615        pub trait IEcho: Interface + Send {
616            fn echo(&self, echo: &str) -> crate::status::Result<String>;
617        }
618        pub trait IEchoAsync<P>: Interface + Send {
619            #[allow(dead_code)]
620            fn echo<'a>(
621                &'a self,
622                echo: &'a str,
623            ) -> crate::BoxFuture<'a, crate::status::Result<String>>;
624        }
625
626        #[allow(dead_code)]
627        #[async_trait]
628        pub trait IEchoAsyncService: Interface + Send {
629            async fn echo(&self, echo: &str) -> crate::status::Result<String>;
630        }
631        pub struct BpEcho {
632            binder: crate::SIBinder,
633        }
634        impl IEcho for BpEcho {
635            fn echo(&self, _echo: &str) -> crate::status::Result<String> {
636                todo!()
637            }
638        }
639        impl<P: crate::BinderAsyncPool> IEchoAsync<P> for BpEcho {
640            fn echo<'a>(
641                &'a self,
642                _echo: &'a str,
643            ) -> crate::BoxFuture<'a, crate::status::Result<String>> {
644                P::spawn(move || 0, |_| async move { Ok("".to_string()) })
645            }
646        }
647        impl Interface for BpEcho {
648            fn as_binder(&self) -> crate::SIBinder {
649                self.binder.clone()
650            }
651        }
652        impl crate::Proxy for BpEcho
653        where
654            BpEcho: IEcho,
655        {
656            fn descriptor() -> &'static str {
657                "my.echo"
658            }
659
660            fn from_binder(binder: crate::SIBinder) -> std::option::Option<Self> {
661                if binder.descriptor() != Self::descriptor() {
662                    return None;
663                }
664                if binder.as_proxy().is_some() {
665                    Some(Self { binder })
666                } else {
667                    None
668                }
669            }
670        }
671
672        #[allow(dead_code)]
673        pub trait BnEchoAdapter: Send + Sync {
674            fn as_sync(&self) -> &dyn IEcho;
675            fn as_async(&self) -> &dyn IEchoAsyncService;
676        }
677
678        #[allow(dead_code)]
679        struct Wrapper<T, R> {
680            inner: T,
681            rt: R,
682        }
683
684        impl<T, R> Interface for Wrapper<T, R>
685        where
686            T: IEchoAsyncService + Sync + Send + 'static,
687            R: crate::BinderAsyncRuntime + Send + Sync + 'static,
688        {
689            fn as_binder(&self) -> crate::SIBinder {
690                self.inner.as_binder()
691            }
692
693            fn dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> Result<()> {
694                self.inner.dump(_writer, _args)
695            }
696        }
697
698        impl<T, R> IEcho for Wrapper<T, R>
699        where
700            T: IEchoAsyncService + Sync + Send + 'static,
701            R: crate::BinderAsyncRuntime + Send + Sync + 'static,
702        {
703            fn echo(&self, echo: &str) -> crate::status::Result<String> {
704                self.rt.block_on(self.inner.echo(echo))
705            }
706        }
707
708        impl<T, R> BnEchoAdapter for Wrapper<T, R>
709        where
710            T: IEchoAsyncService + Sync + Send + 'static,
711            R: crate::BinderAsyncRuntime + Send + Sync + 'static,
712        {
713            fn as_sync(&self) -> &dyn IEcho {
714                self
715            }
716            fn as_async(&self) -> &dyn IEchoAsyncService {
717                &self.inner
718            }
719        }
720
721        #[allow(dead_code)]
722        pub struct BnEcho(Box<dyn BnEchoAdapter>);
723
724        impl BnEcho {
725            /// Create a new binder service.
726            pub fn new_binder<T, R>(inner: T, rt: R) -> crate::Strong<dyn IEcho>
727            where
728                T: IEchoAsyncService + Sync + Send + 'static,
729                R: crate::BinderAsyncRuntime + Send + Sync + 'static,
730            {
731                let bn = BnEcho(Box::new(Wrapper { inner, rt }));
732                let binder =
733                    crate::native::Binder::new_with_stability(bn, crate::Stability::default());
734                crate::Strong::new(Box::new(binder))
735            }
736        }
737
738        impl crate::Remotable for BnEcho {
739            fn descriptor() -> &'static str
740            where
741                Self: Sized,
742            {
743                "my.echo"
744            }
745
746            fn on_transact(
747                &self,
748                _code: crate::TransactionCode,
749                _reader: &mut crate::Parcel,
750                _reply: &mut crate::Parcel,
751            ) -> crate::Result<()> {
752                todo!()
753            }
754
755            fn on_dump(
756                &self,
757                _writer: &mut dyn std::io::Write,
758                _args: &[String],
759            ) -> crate::Result<()> {
760                Ok(())
761            }
762        }
763
764        impl IEcho for crate::Binder<BnEcho> {
765            fn echo(&self, echo: &str) -> crate::status::Result<String> {
766                self.0.as_sync().echo(echo)
767            }
768        }
769
770        impl<P: crate::BinderAsyncPool> IEchoAsync<P> for crate::Binder<BnEcho> {
771            fn echo<'a>(
772                &'a self,
773                echo: &'a str,
774            ) -> crate::BoxFuture<'a, crate::status::Result<String>> {
775                self.0.as_async().echo(echo)
776            }
777        }
778
779        impl crate::FromIBinder for dyn IEcho {
780            fn try_from(binder: crate::SIBinder) -> crate::Result<crate::Strong<dyn IEcho>> {
781                match <BpEcho as crate::Proxy>::from_binder(binder.clone()) {
782                    Some(proxy) => Ok(crate::Strong::new(Box::new(proxy))),
783                    None => match crate::native::Binder::<BnEcho>::try_from(binder) {
784                        Ok(native) => Ok(crate::Strong::new(Box::new(native.clone()))),
785                        Err(err) => Err(err),
786                    },
787                }
788            }
789        }
790
791        impl<P: crate::BinderAsyncPool> crate::FromIBinder for dyn IEchoAsync<P> {
792            fn try_from(
793                binder: crate::SIBinder,
794            ) -> crate::Result<crate::Strong<dyn IEchoAsync<P>>> {
795                match <BpEcho as crate::Proxy>::from_binder(binder.clone()) {
796                    Some(proxy) => Ok(crate::Strong::new(Box::new(proxy))),
797                    None => {
798                        match crate::native::Binder::<BnEcho>::try_from(binder) {
799                            Ok(native) => Ok(crate::Strong::new(Box::new(native.clone()))),
800                            Err(err) => Err(err),
801                        }
802                        // Err(crate::StatusCode::BadType.into())
803                    }
804                }
805            }
806        }
807
808        impl<P: crate::BinderAsyncPool> crate::ToAsyncInterface<P> for dyn IEcho {
809            type Target = dyn IEchoAsync<P>;
810        }
811
812        impl<P: crate::BinderAsyncPool> crate::ToSyncInterface for dyn IEchoAsync<P> {
813            type Target = dyn IEcho;
814        }
815
816        struct MyEcho {}
817        impl Interface for MyEcho {}
818        #[async_trait]
819        impl IEchoAsyncService for MyEcho {
820            async fn echo(&self, echo: &str) -> crate::status::Result<String> {
821                Ok(echo.to_owned())
822            }
823        }
824
825        struct MyRuntime {}
826        impl crate::BinderAsyncRuntime for MyRuntime {
827            fn block_on<F: std::future::Future>(&self, _future: F) -> F::Output {
828                todo!()
829            }
830        }
831
832        let _echo = BnEcho::new_binder(MyEcho {}, MyRuntime {});
833
834        // echo.into_async::<Tokio>().echo("hello");
835    }
836}