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 impl Clone for RemoteObj { clone(&self) -> Self35 fn clone(&self) -> Self { 36 Self { 37 inner: CloneRemoteObj(self.inner.as_ref().unwrap()), 38 } 39 } 40 } 41 42 unsafe impl Send for RemoteObj {} 43 unsafe impl Sync for RemoteObj {} 44 45 pub struct RecipientRemoveHandler { 46 inner: UniquePtr<DeathRecipientRemoveHandler>, 47 } 48 49 impl RemoteObj { 50 /// Creates a Remote Object from C++ IRemoteObejectWrapper. try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self>51 pub fn try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self> { 52 if wrap.is_null() { 53 return None; 54 } 55 Some(Self { inner: wrap }) 56 } 57 58 /// Creates a Remote Object from C++ IRemoteObejectWrapper. new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self59 pub unsafe fn new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self { 60 Self { inner: wrap } 61 } 62 from_ciremote(remote: *mut IRemoteObject) -> Option<Self>63 pub unsafe fn from_ciremote(remote: *mut IRemoteObject) -> Option<Self> { 64 if remote.is_null() { 65 return None; 66 } 67 68 let inner = FromCIRemoteObject(remote); 69 if inner.is_null() { 70 return None; 71 } 72 73 Some(Self { inner }) 74 } 75 76 /// Creates a RemoteObj from RemoteStub. from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self>77 pub fn from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self> { 78 RemoteStubWrapper::new(stub).into_remote() 79 } 80 81 /// Creates a RemoteObj from sptr from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self>82 pub fn from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self> { 83 Self::try_new(FromSptrRemote(sptr)) 84 } 85 86 /// Sends a IPC request to remote service send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel>87 pub fn send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel> { 88 let mut reply = MsgParcel::new(); 89 let mut option = MsgOption::new(); 90 match mem::replace(&mut data.inner, ParcelMem::Null) { 91 ParcelMem::Unique(mut p) => { 92 let res = self.inner.SendRequest( 93 code, 94 p.pin_mut(), 95 reply.pin_mut().unwrap(), 96 option.inner.pin_mut(), 97 ); 98 data.inner = ParcelMem::Unique(p); 99 if res != 0 { 100 return Err(IpcStatusCode::Failed); 101 } 102 Ok(reply) 103 } 104 _ => Err(IpcStatusCode::Failed), 105 } 106 } 107 108 /// Sends asynchronous IPC requests to remote services, The current 109 /// interface will use ylong runtime to start a separate thread to execute 110 /// 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,111 pub fn async_send_request<F, R>( 112 self: &Arc<Self>, 113 code: u32, 114 mut data: MsgParcel, 115 mut option: MsgOption, 116 call_back: F, 117 ) where 118 F: FnOnce(MsgParcel) -> R, 119 F: Send + 'static, 120 R: Send + 'static, 121 { 122 let remote = self.clone(); 123 Runtime::spawn_blocking(move || { 124 let reply = remote.send_request(code, &mut data); 125 match reply { 126 Ok(reply) => { 127 call_back(reply); 128 IpcStatusCode::Ok 129 } 130 _ => IpcStatusCode::Failed, 131 } 132 }); 133 } 134 135 /// Registries a death recipient, and returns a RecipientRemoveHandler, if 136 /// the registration is successful. add_death_recipient(&self, f: fn(Box<RemoteObj>)) -> Option<RecipientRemoveHandler>137 pub fn add_death_recipient(&self, f: fn(Box<RemoteObj>)) -> Option<RecipientRemoveHandler> { 138 let inner = self.inner.AddDeathRecipient(f); 139 inner.is_null().then_some(RecipientRemoveHandler { inner }) 140 } 141 142 /// Returns true if it is a proxy object. is_proxy(&self) -> bool143 pub fn is_proxy(&self) -> bool { 144 self.inner.IsProxyObject() 145 } 146 147 /// Dumps a service through a String dump(&self, fd: i32, args: &[String]) -> i32148 pub fn dump(&self, fd: i32, args: &[String]) -> i32 { 149 self.inner.Dump(fd, args) 150 } 151 152 /// check_legalit(&self) -> bool153 pub fn check_legalit(&self) -> bool { 154 self.inner.CheckObjectLegality() 155 } 156 157 /// Returns true if the object is dead. is_dead(&self) -> bool158 pub fn is_dead(&self) -> bool { 159 self.inner.IsObjectDead() 160 } 161 162 /// Returns interface descriptor. interface_descriptor(&self) -> IpcResult<String>163 pub fn interface_descriptor(&self) -> IpcResult<String> { 164 Ok(self.inner.GetInterfaceDescriptor()) 165 } 166 167 /// Returns Object descriptor. object_descriptor(&self) -> IpcResult<String>168 pub fn object_descriptor(&self) -> IpcResult<String> { 169 Ok(self.inner.GetObjectDescriptor()) 170 } 171 } 172 173 impl RecipientRemoveHandler { remove_recipient(self)174 pub fn remove_recipient(self) { 175 self.inner.remove(); 176 } 177 } 178