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