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 }