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 14use std::mem; 15use std::sync::Arc; 16 17use cxx::UniquePtr; 18 19use super::wrapper::{ 20 CloneRemoteObj, DeathRecipientRemoveHandler, FromCIRemoteObject, FromSptrRemote, IRemoteObject, 21 IRemoteObjectWrapper, RemoteStubWrapper, SptrIRemoteObject, 22}; 23use super::RemoteStub; 24use crate::errors::{IpcResult, IpcStatusCode}; 25use crate::ipc_async::{IpcAsyncRuntime, Runtime}; 26use crate::parcel::msg::ParcelMem; 27use crate::parcel::{MsgOption, MsgParcel}; 28 29/// Remote Object 30pub struct RemoteObj { 31 pub(crate) inner: UniquePtr<IRemoteObjectWrapper>, 32} 33 34impl Clone for RemoteObj { 35 fn clone(&self) -> Self { 36 Self { 37 inner: CloneRemoteObj(self.inner.as_ref().unwrap()), 38 } 39 } 40} 41 42unsafe impl Send for RemoteObj {} 43unsafe impl Sync for RemoteObj {} 44 45pub struct RecipientRemoveHandler { 46 inner: UniquePtr<DeathRecipientRemoveHandler>, 47} 48 49impl RemoteObj { 50 /// Creates a Remote Object from C++ IRemoteObejectWrapper. 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. 59 pub unsafe fn new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self { 60 Self { inner: wrap } 61 } 62 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. 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 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 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 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. 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. 143 pub fn is_proxy(&self) -> bool { 144 self.inner.IsProxyObject() 145 } 146 147 /// Dumps a service through a String 148 pub fn dump(&self, fd: i32, args: &[String]) -> i32 { 149 self.inner.Dump(fd, args) 150 } 151 152 /// 153 pub fn check_legalit(&self) -> bool { 154 self.inner.CheckObjectLegality() 155 } 156 157 /// Returns true if the object is dead. 158 pub fn is_dead(&self) -> bool { 159 self.inner.IsObjectDead() 160 } 161 162 /// Returns interface descriptor. 163 pub fn interface_descriptor(&self) -> IpcResult<String> { 164 Ok(self.inner.GetInterfaceDescriptor()) 165 } 166 167 /// Returns Object descriptor. 168 pub fn object_descriptor(&self) -> IpcResult<String> { 169 Ok(self.inner.GetObjectDescriptor()) 170 } 171} 172 173impl RecipientRemoveHandler { 174 pub fn remove_recipient(self) { 175 self.inner.remove(); 176 } 177} 178