• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /// This macro can define a rust IPC proxy and stub releations.
17 #[macro_export]
18 macro_rules! define_remote_object {
19     {
20         $remote_broker:path[$descriptor:expr] {
21             stub: $stub:ident($on_remote_request:path),
22             proxy: $proxy:ident,
23         }
24     } => {
25         $crate::define_remote_object! {
26             $remote_broker[$descriptor] {
27                 stub: $stub($on_remote_request),
28                 proxy: $proxy {},
29             }
30         }
31     };
32 
33     {
34         $remote_broker:path[$descriptor:expr] {
35             stub: $stub:ident($on_remote_request:path),
36             proxy: $proxy:ident {
37                 $($item_name:ident: $item_type:ty = $item_init:expr),*
38             },
39         }
40     } => {
41         /// IPC proxy type
42         pub struct $proxy {
43             remote: $crate::RemoteObj,
44             $($item_name: $item_type,)*
45         }
46 
47         impl $proxy {
48             /// Create proxy object by RemoteObj
49             fn from_remote_object(remote: &RemoteObj) -> $crate::IpcResult<Self> {
50                 Ok(Self {
51                     remote: remote.clone(),
52                     $($item_name: $item_init),*
53                 })
54             }
55 
56             /// Get proxy object descriptor
57             #[allow(dead_code)]
58             pub fn get_descriptor() -> &'static str {
59                 $descriptor
60             }
61         }
62 
63         impl $crate::IRemoteBroker for $proxy {
64             /// Get RemoteObject object from proxy
65             fn as_object(&self) -> Option<$crate::RemoteObj> {
66                 Some(self.remote.clone())
67             }
68         }
69 
70         /// IPC stub type
71         pub struct $stub(Box<dyn $remote_broker + Sync + Send>);
72 
73         impl $stub {
74             /// Create a new remote stub service
75             #[allow(dead_code)]
76             pub fn new_remote_stub<T: $remote_broker + Send + Sync + 'static>(obj: T) -> Option<$crate::RemoteStub<Self>> {
77                 RemoteStub::new($stub(Box::new(obj)))
78             }
79         }
80 
81         impl $crate::IRemoteStub for $stub {
82             /// Get stub object descriptor
83             fn get_descriptor() -> &'static str {
84                 $descriptor
85             }
86 
87             /// Callback to deal IPC request for this stub
88             fn on_remote_request(&self, code: u32, data: &$crate::BorrowedMsgParcel,
89                 reply: &mut $crate::BorrowedMsgParcel) -> i32 {
90                 // For example, "self.0" is "Box<dyn ITest>", "*self.0" is "dyn ITest"
91                 let result = $on_remote_request(&*self.0, code, data, reply);
92 
93                 match result {
94                     Ok(_) => 0,
95                     Err(error) => {
96                         error as i32
97                     }
98                 }
99             }
100             fn on_dump(&self, file: &$crate::FileDesc, args: &mut Vec<$crate::String16>) -> i32 {
101                 self.0.dump(file, args)
102             }
103         }
104 
105         impl $crate::FromRemoteObj for dyn $remote_broker {
106             /// For example, convert RemoteObj to RemoteObjRef<dyn ITest>
107             fn try_from(object: $crate::RemoteObj)
108                 -> $crate::IpcResult<$crate::RemoteObjRef<dyn $remote_broker>> {
109                 Ok($crate::RemoteObjRef::new(Box::new($proxy::from_remote_object(&object)?)))
110             }
111         }
112     };
113 }