1 // Copyright (C) 2024 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::mem; 15 use std::sync::Arc; 16 17 use cxx::UniquePtr; 18 19 use super::wrapper::{ 20 CloneRemoteObj, DeathRecipientRemoveHandler, FromCIRemoteObject, FromSptrRemote, IRemoteObject, 21 IRemoteObjectWrapper, RemoteStubWrapper, SptrIRemoteObject, 22 }; 23 use super::RemoteStub; 24 use crate::errors::{IpcResult, IpcStatusCode}; 25 use crate::ipc_async::{IpcAsyncRuntime, Runtime}; 26 use crate::parcel::msg::ParcelMem; 27 use crate::parcel::{MsgOption, MsgParcel}; 28 29 /// Remote Object 30 pub struct RemoteObj { 31 pub(crate) inner: UniquePtr<IRemoteObjectWrapper>, 32 } 33 34 pub struct ClosureWrapper { 35 inner: Box<dyn FnMut(Box<RemoteObj>)>, 36 } 37 38 impl ClosureWrapper { execute(&mut self, obj: Box<RemoteObj>)39 pub fn execute(&mut self, obj: Box<RemoteObj>) { 40 (self.inner)(obj); 41 } 42 } 43 44 impl Clone for RemoteObj { clone(&self) -> Self45 fn clone(&self) -> Self { 46 Self { 47 inner: CloneRemoteObj(self.inner.as_ref().unwrap()), 48 } 49 } 50 } 51 52 unsafe impl Send for RemoteObj {} 53 unsafe impl Sync for RemoteObj {} 54 55 pub struct RecipientRemoveHandler { 56 inner: UniquePtr<DeathRecipientRemoveHandler>, 57 } 58 59 impl RemoteObj { 60 /// Creates a Remote Object from C++ IRemoteObejectWrapper. try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self>61 pub fn try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self> { 62 if wrap.is_null() { 63 return None; 64 } 65 Some(Self { inner: wrap }) 66 } 67 68 /// Creates a Remote Object from C++ IRemoteObejectWrapper. new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self69 pub unsafe fn new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self { 70 Self { inner: wrap } 71 } 72 from_ciremote(remote: *mut IRemoteObject) -> Option<Self>73 pub unsafe fn from_ciremote(remote: *mut IRemoteObject) -> Option<Self> { 74 if remote.is_null() { 75 return None; 76 } 77 78 let inner = FromCIRemoteObject(remote); 79 if inner.is_null() { 80 return None; 81 } 82 83 Some(Self { inner }) 84 } 85 86 /// Creates a RemoteObj from RemoteStub. from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self>87 pub fn from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self> { 88 RemoteStubWrapper::new(stub).into_remote() 89 } 90 91 /// Creates a RemoteObj from sptr from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self>92 pub fn from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self> { 93 Self::try_new(FromSptrRemote(sptr)) 94 } 95 96 /// Sends a IPC request to remote service send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel>97 pub fn send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel> { 98 let mut reply = MsgParcel::new(); 99 let mut option = MsgOption::new(); 100 match mem::replace(&mut data.inner, ParcelMem::Null) { 101 ParcelMem::Unique(mut p) => { 102 let res = self.inner.SendRequest( 103 code, 104 p.pin_mut(), 105 reply.pin_mut().unwrap(), 106 option.inner.pin_mut(), 107 ); 108 data.inner = ParcelMem::Unique(p); 109 match res { 110 0 => Ok(reply), 111 29189 => Err(IpcStatusCode::ServiceDied), 112 _ => Err(IpcStatusCode::Failed), 113 } 114 } 115 _ => Err(IpcStatusCode::Failed), 116 } 117 } 118 119 /// Sends asynchronous IPC requests to remote services, The current 120 /// interface will use ylong runtime to start a separate thread to execute 121 /// requests async_send_request<F, R>( self: &Arc<Self>, code: u32, mut data: MsgParcel, mut option: MsgOption, call_back: F, ) where F: FnOnce(MsgParcel) -> R, F: Send + 'static, R: Send + 'static,122 pub fn async_send_request<F, R>( 123 self: &Arc<Self>, 124 code: u32, 125 mut data: MsgParcel, 126 mut option: MsgOption, 127 call_back: F, 128 ) where 129 F: FnOnce(MsgParcel) -> R, 130 F: Send + 'static, 131 R: Send + 'static, 132 { 133 let remote = self.clone(); 134 Runtime::spawn_blocking(move || { 135 let reply = remote.send_request(code, &mut data); 136 match reply { 137 Ok(reply) => { 138 call_back(reply); 139 IpcStatusCode::Ok 140 } 141 _ => IpcStatusCode::Failed, 142 } 143 }); 144 } 145 146 /// Registries a death recipient, and returns a RecipientRemoveHandler, if 147 /// the registration is successful. add_death_recipient<F: FnMut(Box<RemoteObj>) + 'static>( &self, f: F, ) -> Option<RecipientRemoveHandler>148 pub fn add_death_recipient<F: FnMut(Box<RemoteObj>) + 'static>( 149 &self, 150 f: F, 151 ) -> Option<RecipientRemoveHandler> { 152 let inner = self.inner.AddDeathRecipient(Box::new(ClosureWrapper { inner: Box::new(f) })); 153 inner.is_null().then_some(RecipientRemoveHandler { inner }) 154 } 155 156 /// Returns true if it is a proxy object. is_proxy(&self) -> bool157 pub fn is_proxy(&self) -> bool { 158 self.inner.IsProxyObject() 159 } 160 161 /// Dumps a service through a String dump(&self, fd: i32, args: &[String]) -> i32162 pub fn dump(&self, fd: i32, args: &[String]) -> i32 { 163 self.inner.Dump(fd, args) 164 } 165 166 /// check_legalit(&self) -> bool167 pub fn check_legalit(&self) -> bool { 168 self.inner.CheckObjectLegality() 169 } 170 171 /// Returns true if the object is dead. is_dead(&self) -> bool172 pub fn is_dead(&self) -> bool { 173 self.inner.IsObjectDead() 174 } 175 176 /// Returns interface descriptor. interface_descriptor(&self) -> IpcResult<String>177 pub fn interface_descriptor(&self) -> IpcResult<String> { 178 Ok(self.inner.GetInterfaceDescriptor()) 179 } 180 181 /// Returns Object descriptor. object_descriptor(&self) -> IpcResult<String>182 pub fn object_descriptor(&self) -> IpcResult<String> { 183 Ok(self.inner.GetObjectDescriptor()) 184 } 185 } 186 187 impl RecipientRemoveHandler { remove_recipient(self)188 pub fn remove_recipient(self) { 189 self.inner.remove(); 190 } 191 } 192