提供由c++ IRemoteObject对象向rust RemoteObj对象转换

Signed-off-by: chenchong_666 <chenchong57@huawei.com>
This commit is contained in:
chenchong_666 2023-08-17 19:20:24 +08:00
parent 7f0820765a
commit 5e28f14c0f
7 changed files with 82 additions and 6 deletions

View File

@ -37,7 +37,8 @@
"access_token",
"dsoftbus",
"napi",
"common"
"common",
"build_framework"
],
"third_party": [
"libuv",

View File

@ -21,7 +21,7 @@ use crate::{
MsgParcel, BorrowedMsgParcel, AsRawPtr, IpcStatusCode,
parcel::vec_u16_to_string, parse_status_code,
};
use crate::ipc_binding::{CRemoteObject, CDeathRecipient};
use crate::ipc_binding::{CRemoteObject, CDeathRecipient, CIRemoteObject};
use crate::parcel::parcelable::{Serialize, Deserialize, allocate_vec_with_buffer};
use std::ffi::{c_void, CString, c_char};
use crate::String16;
@ -59,6 +59,26 @@ impl RemoteObj {
pub unsafe fn as_inner(&self) -> *mut CRemoteObject {
self.0.as_ptr()
}
/// Convert an `RemoteObj` by `CIRemoteObject` pointer.
pub fn from_raw_ciremoteobj(obj: *mut CIRemoteObject) -> Option<RemoteObj> {
if obj.is_null() {
None
} else {
// SAFETY: he returned CIRemoteObject may be a null pointer
unsafe {
let sa = ipc_binding::CreateCRemoteObject(obj as *mut _ as *mut c_void);
RemoteObj::from_raw(sa)
}
}
}
/// Extract a raw `CIRemoteObject` pointer from this wrapper.
/// # Safety
/// The returned CIRemoteObject may be a null pointer
pub unsafe fn as_raw_ciremoteobj(&self) -> *mut CIRemoteObject {
ipc_binding::GetCIRemoteObject(self.0.as_ptr()) as *mut CIRemoteObject
}
}
impl IRemoteObj for RemoteObj {

View File

@ -22,6 +22,11 @@ pub struct CRemoteObject {
_private: [u8; 0],
}
#[repr(C)]
pub struct CIRemoteObject {
_private: [u8; 0],
}
#[repr(C)]
pub struct CDeathRecipient {
_private: [u8; 0],
@ -135,6 +140,8 @@ pub type OnCParcelReadElement = unsafe extern "C" fn (
// C interface for IPC core object
extern "C" {
pub fn CreateCRemoteObject(object: *mut c_void) -> *mut CRemoteObject;
pub fn GetCIRemoteObject(object: *mut CRemoteObject) -> *mut c_void;
pub fn CreateRemoteStub(descripor: *const c_char, on_remote_request: OnRemoteRequest,
on_remote_object_destroy: OnRemoteObjectDestroy,
user_data: *const c_void, on_remote_dump: OnRemoteDump) -> *mut CRemoteObject;

View File

@ -30,7 +30,7 @@ struct CDeathRecipient;
typedef struct CDeathRecipient CDeathRecipient;
// Callback as remote stub
typedef int (*OnRemoteRequestCb)(const void *userData, int code,
typedef int (*OnRemoteRequestCb)(const void *userData, int code,
const CParcel *data, CParcel *reply);
typedef int (*OnRemoteDumpCb)(const void *userData, const CParcel *data);
typedef void (*OnRemoteObjectDestroyCb)(const void *userData);
@ -40,6 +40,8 @@ typedef void (*OnDeathRecipientDestroyCb)(const void *userData);
typedef bool (*On16BytesAllocator)(void *stringData, uint16_t **buffer, int32_t len);
CRemoteObject *CreateCRemoteObject(void *obj);
void *GetCIRemoteObject(CRemoteObject* obj);
CRemoteObject *CreateRemoteStub(const char *desc, OnRemoteRequestCb callback,
OnRemoteObjectDestroyCb destroy, const void *userData, OnRemoteDumpCb dumpCallback);

View File

@ -289,4 +289,37 @@ bool GetInterfaceDescriptor(CRemoteObject *object, void *value, On16BytesAllocat
return false;
}
return true;
}
CRemoteObject *CreateCRemoteObject(void *obj)
{
if (obj == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
return nullptr;
}
CRemoteObject *holder = new (std::nothrow) CRemoteObjectHolder();
if (holder == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: create proxy holder failed\n", __func__);
return nullptr;
}
sptr<IRemoteObject> sa = reinterpret_cast<IRemoteObject* >(obj);
holder->IncStrongRef(nullptr);
holder->remote_ = sa;
return holder;
}
void *GetCIRemoteObject(CRemoteObject* obj)
{
if (!IsValidRemoteObject(obj, __func__)) {
ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
return nullptr;
}
if (obj->remote_ == nullptr) {
ZLOGI(LOG_LABEL, "%{public}s: The pointer inside CRemoteObject is a null pointer\n", __func__);
return nullptr;
}
return obj->remote_.GetRefPtr();
}

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
#![allow(clippy::needless_borrow)]
#![allow(clippy::needless_borrow)]
#![allow(clippy::bool_assert_comparison)]
#![allow(non_snake_case)]
extern crate ipc_rust;
@ -28,6 +28,7 @@ use ipc_rust::{
get_self_token_id, get_calling_pid, get_calling_uid, IMsgParcel, IpcResult,
RawData, set_max_work_thread, reset_calling_identity, set_calling_identity,
is_local_calling, get_local_device_id, get_calling_device_id, IpcStatusCode,
RemoteObj,
};
use ipc_rust::{Serialize, Deserialize, BorrowedMsgParcel, Ashmem};
@ -806,4 +807,16 @@ fn test_get_interface_descriptor() {
let descriptor = String16::new(TestProxy::get_descriptor());
let ret = remote.interface_descriptor().expect("get interface descriptor failed");
assert_eq!(descriptor.get_string(), ret);
}
}
#[test]
fn test_get_interface_descriptor_002() {
let remote = get_service(IPC_TEST_SERVICE_ID).expect("get itest service failed");
// SAFETY:
let remote = unsafe {
RemoteObj::from_raw_ciremoteobj(remote.as_raw_ciremoteobj()).unwrap()
};
let descriptor = String16::new(TestProxy::get_descriptor());
let ret = remote.interface_descriptor().expect("get interface descriptor failed");
assert_eq!(descriptor.get_string(), ret);
}

View File

@ -138,5 +138,5 @@ fn main() {
add_service(&service.as_object().expect("get ITest service failed"),
IPC_TEST_SERVICE_ID).expect("add server to samgr failed");
println!("join to ipc work thread");
join_work_thread();
join_work_thread();
}