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 //! Implement of RemoteObj type, which represent a C++ IRemoteObject. 17 18 use std::ptr; 19 use crate::{ 20 ipc_binding, IRemoteObj, DeathRecipient, IpcResult, 21 MsgParcel, BorrowedMsgParcel, AsRawPtr, IpcStatusCode, 22 parcel::vec_u16_to_string, parse_status_code, 23 }; 24 use crate::ipc_binding::{CRemoteObject, CDeathRecipient}; 25 use crate::parcel::parcelable::{Serialize, Deserialize, allocate_vec_with_buffer}; 26 use std::ffi::{c_void, CString, c_char}; 27 use crate::String16; 28 use hilog_rust::{error, hilog, HiLogLabel, LogType}; 29 30 const LOG_LABEL: HiLogLabel = HiLogLabel { 31 log_type: LogType::LogCore, 32 domain: 0xd001510, 33 tag: "RustRemoteObj" 34 }; 35 36 pub mod death_recipient; 37 pub mod cmp; 38 39 /// RemoteObject can be used as proxy or stub object. 40 /// It always contained a native CRemoteObject pointer. 41 /// # Invariant 42 /// 43 /// `*mut CRemoteObject` must be valid 44 pub struct RemoteObj(ptr::NonNull<CRemoteObject>); 45 46 impl RemoteObj { 47 /// Create an `RemoteObj` wrapper object from a raw `CRemoteObject` pointer. 48 /// # Safety from_raw(obj: *mut CRemoteObject) -> Option<RemoteObj>49 pub unsafe fn from_raw(obj: *mut CRemoteObject) -> Option<RemoteObj> { 50 if obj.is_null() { 51 None 52 } else { 53 Some(RemoteObj(unsafe{ptr::NonNull::new_unchecked(obj)})) 54 } 55 } 56 57 /// Extract a raw `CRemoteObject` pointer from this wrapper. 58 /// # Safety as_inner(&self) -> *mut CRemoteObject59 pub unsafe fn as_inner(&self) -> *mut CRemoteObject { 60 self.0.as_ptr() 61 } 62 } 63 64 impl IRemoteObj for RemoteObj { send_request(&self, code: u32, data: &MsgParcel, is_async: bool) -> IpcResult<MsgParcel>65 fn send_request(&self, code: u32, data: &MsgParcel, is_async: bool) -> IpcResult<MsgParcel> { 66 // SAFETY: 67 unsafe { 68 let mut reply = MsgParcel::new().expect("create reply MsgParcel not success"); 69 let result = ipc_binding::RemoteObjectSendRequest(self.as_inner(), code, data.as_raw(), 70 reply.as_mut_raw(), is_async); 71 if result == 0 { 72 Ok(reply) 73 } else { 74 Err(parse_status_code(result)) 75 } 76 } 77 } 78 79 // Add death Recipient add_death_recipient(&self, recipient: &mut DeathRecipient) -> bool80 fn add_death_recipient(&self, recipient: &mut DeathRecipient) -> bool { 81 // SAFETY: 82 unsafe { 83 ipc_binding::AddDeathRecipient(self.as_inner(), recipient.as_mut_raw()) 84 } 85 } 86 87 // remove death Recipients remove_death_recipient(&self, recipient: &mut DeathRecipient) -> bool88 fn remove_death_recipient(&self, recipient: &mut DeathRecipient) -> bool { 89 // SAFETY: 90 unsafe { 91 ipc_binding::RemoveDeathRecipient(self.as_inner(), recipient.as_mut_raw()) 92 } 93 } 94 is_proxy(&self) -> bool95 fn is_proxy(&self) -> bool { 96 // SAFETY: 97 unsafe { 98 ipc_binding::IsProxyObject(self.as_inner()) 99 } 100 } 101 dump(&self, fd: i32, args: &mut Vec<String16>) -> i32102 fn dump(&self, fd: i32, args: &mut Vec<String16>) -> i32 { 103 let mut parcel = match MsgParcel::new() { 104 Some(parcel) => parcel, 105 None => { 106 error!(LOG_LABEL, "create MsgParcel failed"); 107 return IpcStatusCode::Failed as i32; 108 } 109 }; 110 match parcel.write::<Vec<String16>>(args) { 111 Ok(_) => { 112 // SAFETY: `parcel` always contains a valid pointer to a `CParcel` 113 unsafe { 114 ipc_binding::Dump(self.as_inner(), fd, parcel.into_raw()) 115 } 116 } 117 _ => { 118 error!(LOG_LABEL, "create MsgParcel failed"); 119 IpcStatusCode::Failed as i32 120 } 121 } 122 } 123 is_dead(&self) -> bool124 fn is_dead(&self) -> bool { 125 // SAFETY: 126 unsafe { 127 ipc_binding::IsObjectDead(self.as_inner()) 128 } 129 } 130 interface_descriptor(&self) -> IpcResult<String>131 fn interface_descriptor(&self) -> IpcResult<String> { 132 let mut vec: Option<Vec<u16>> = None; 133 // SAFETY: 134 let ok_status = unsafe { 135 ipc_binding::GetInterfaceDescriptor( 136 self.as_inner(), 137 &mut vec as *mut _ as *mut c_void, 138 allocate_vec_with_buffer::<u16> 139 ) 140 }; 141 if ok_status { 142 vec_u16_to_string(vec) 143 } else { 144 Err(IpcStatusCode::Failed) 145 } 146 } 147 } 148 149 impl Serialize for RemoteObj { serialize(&self, parcel: &mut BorrowedMsgParcel<'_>) -> IpcResult<()>150 fn serialize(&self, parcel: &mut BorrowedMsgParcel<'_>) -> IpcResult<()> { 151 let ret = unsafe { 152 ipc_binding::CParcelWriteRemoteObject(parcel.as_mut_raw(), self.as_inner()) 153 }; 154 if ret { 155 Ok(()) 156 } else { 157 Err(IpcStatusCode::Failed) 158 } 159 } 160 } 161 162 impl Deserialize for RemoteObj { deserialize(parcel: &BorrowedMsgParcel<'_>) -> IpcResult<Self>163 fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> IpcResult<Self> { 164 // Safety: `Parcel` always contains a valid pointer to an 165 // `AParcel`. We pass a valid, mutable pointer to `val`, a 166 // literal of type `$ty`, and `$read_fn` will write the 167 let object = unsafe { 168 let remote = ipc_binding::CParcelReadRemoteObject(parcel.as_raw()); 169 Self::from_raw(remote) 170 }; 171 if let Some(x) = object { 172 Ok(x) 173 } else { 174 Err(IpcStatusCode::Failed) 175 } 176 } 177 } 178 179 /// # Safety 180 /// 181 /// An `RemoteObj` is an immutable handle to CRemoteObject, which is thread-safe 182 unsafe impl Send for RemoteObj {} 183 /// # Safety 184 /// 185 /// An `RemoteObj` is an immutable handle to CRemoteObject, which is thread-safe 186 unsafe impl Sync for RemoteObj {} 187 188 impl Clone for RemoteObj { clone(&self) -> Self189 fn clone(&self) -> Self { 190 // SAFETY: 191 unsafe { 192 ipc_binding::RemoteObjectIncStrongRef(self.as_inner()); 193 } 194 // SAFETY: no `None` here, cause `self` is valid 195 Self(self.0) 196 } 197 } 198 199 impl Drop for RemoteObj { drop(&mut self)200 fn drop(&mut self) { 201 // SAFETY: 202 unsafe { 203 ipc_binding::RemoteObjectDecStrongRef(self.as_inner()); 204 } 205 } 206 } 207