提交 282033c8 编写于 作者: C chenchong_666

[Bug]: c++ hidumper服务调用rust端服务没有dumper信息

Signed-off-by: Nchenchong_666 <chenchong57@huawei.com>
上级 71f8d370
......@@ -36,7 +36,8 @@
"c_utils",
"access_token",
"dsoftbus",
"napi"
"napi",
"common"
],
"third_party": [
"libuv",
......
......@@ -97,6 +97,9 @@ macro_rules! define_remote_object {
}
}
}
fn on_dump(&self, file: &$crate::FileDesc, args: &mut Vec<$crate::String16>) -> i32 {
self.0.dump(file, args)
}
}
impl $crate::FromRemoteObj for dyn $remote_broker {
......
......@@ -17,7 +17,10 @@ pub mod remote_obj;
pub mod remote_stub;
pub mod macros;
use crate::{BorrowedMsgParcel, MsgParcel, IpcResult, DeathRecipient,};
use crate::{
BorrowedMsgParcel, MsgParcel, IpcResult, DeathRecipient,
FileDesc, IpcStatusCode,
};
use std::ops::{Deref};
use std::cmp::Ordering;
use crate::String16;
......@@ -39,7 +42,7 @@ pub trait IRemoteObj {
/// Determine whether it is a proxy object
fn is_proxy(&self) -> bool;
/// Dump a service through a string
/// Dump a service through a String16
fn dump(&self, fd: i32, args: &mut Vec<String16>) -> i32;
/// Judge whether the object is dead
......@@ -56,6 +59,9 @@ pub trait IRemoteStub: Send + Sync {
/// Callback for deal IPC request
fn on_remote_request(&self, code: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> i32;
/// Callback for IPC dump
fn on_dump(&self, file: &FileDesc, args: &mut Vec<String16>) -> i32;
}
/// Like C++ IRemoteBroker class
......@@ -64,6 +70,11 @@ pub trait IRemoteBroker: Send + Sync {
fn as_object(&self) -> Option<RemoteObj> {
panic!("This is not a RemoteObject.")
}
/// Default dump
fn dump(&self, _file: &FileDesc, _args: &mut Vec<String16>) -> i32 {
println!("This is the default dump function, and you can override it to implement your own dump function");
IpcStatusCode::Ok as i32
}
}
/// Define function which how to convert a RemoteObj to RemoteObjRef, the later contains a
......
......@@ -17,14 +17,21 @@
use std::ptr;
use crate::{
ipc_binding, IRemoteObj, DeathRecipient, IpcResult, IpcStatusCode,
MsgParcel, BorrowedMsgParcel, AsRawPtr, parcel::on_string16_writer,
ipc_binding, IRemoteObj, DeathRecipient, IpcResult,
MsgParcel, BorrowedMsgParcel, AsRawPtr, IpcStatusCode,
parcel::vec_u16_to_string, parse_status_code,
};
use crate::ipc_binding::{CRemoteObject, CDeathRecipient};
use crate::parcel::parcelable::{Serialize, Deserialize, allocate_vec_with_buffer};
use std::ffi::{c_void};
use std::ffi::{c_void, CString, c_char};
use crate::String16;
use hilog_rust::{error, hilog, HiLogLabel, LogType};
const LOG_LABEL: HiLogLabel = HiLogLabel {
log_type: LogType::LogCore,
domain: 0xd001510,
tag: "RustRemoteObj"
};
pub mod death_recipient;
pub mod cmp;
......@@ -93,11 +100,24 @@ impl IRemoteObj for RemoteObj {
}
fn dump(&self, fd: i32, args: &mut Vec<String16>) -> i32 {
let slice = &args[..];
// SAFETY:
unsafe {
ipc_binding::Dump(self.as_inner(), fd, slice.as_ptr() as *const c_void,
slice.len().try_into().unwrap(), on_string16_writer)
let mut parcel = match MsgParcel::new() {
Some(parcel) => parcel,
None => {
error!(LOG_LABEL, "create MsgParcel failed");
return IpcStatusCode::Failed as i32;
}
};
match parcel.write::<Vec<String16>>(args) {
Ok(_) => {
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
unsafe {
ipc_binding::Dump(self.as_inner(), fd, parcel.into_raw())
}
}
_ => {
error!(LOG_LABEL, "create MsgParcel failed");
IpcStatusCode::Failed as i32
}
}
}
......
......@@ -13,11 +13,14 @@
* limitations under the License.
*/
use crate::{ipc_binding, IRemoteStub, IRemoteBroker, RemoteObj, BorrowedMsgParcel};
use crate::{
ipc_binding, IRemoteStub, IRemoteBroker, IpcStatusCode,
RemoteObj, BorrowedMsgParcel, FileDesc, String16,
};
use crate::ipc_binding::{CRemoteObject, CParcel};
use std::ffi::{c_void, CString, c_char};
use std::ops::{Deref};
use hilog_rust::{info, hilog, HiLogLabel, LogType};
use hilog_rust::{info, error, hilog, HiLogLabel, LogType};
const LOG_LABEL: HiLogLabel = HiLogLabel {
log_type: LogType::LogCore,
......@@ -49,8 +52,9 @@ impl<T: IRemoteStub> RemoteStub<T> {
// set rust object pointer to native, so we can figure out who deal
// the request during on_remote_request().
ipc_binding::CreateRemoteStub(descripor.as_ptr(), Self::on_remote_request,
Self::on_destroy, rust as *mut c_void)
Self::on_destroy, rust as *mut c_void, Self::on_dump)
};
if native.is_null() {
None
} else {
......@@ -108,6 +112,8 @@ impl<T: IRemoteStub> RemoteStub<T> {
unsafe extern "C" fn on_remote_request(user_data: *mut c_void, code: u32,
data: *const CParcel, reply: *mut CParcel) -> i32 {
let res = {
// BorrowedMsgParcel calls the correlation function from_raw must return as Some,
// direct deconstruction will not crash.
let mut reply = BorrowedMsgParcel::from_raw(reply).unwrap();
let data = BorrowedMsgParcel::from_raw(data as *mut CParcel).unwrap();
let rust_object: &T = &*(user_data as *mut T);
......@@ -119,6 +125,34 @@ impl<T: IRemoteStub> RemoteStub<T> {
///
/// The parameters passed in should ensure FFI safety
/// user_data pointer, data pointer and reply pointer on the c side must be guaranteed not to be null
unsafe extern "C" fn on_dump(user_data: *mut c_void, data: *const CParcel) -> i32 {
let res = {
let rust_object: &T = &*(user_data as *mut T);
// BorrowedMsgParcel calls the correlation functio from_raw must return as Some,
// direct deconstruction will not crash.
let data = BorrowedMsgParcel::from_raw(data as *mut CParcel).unwrap();
let file: FileDesc = match data.read::<FileDesc>() {
Ok(file) => file,
_ => {
error!(LOG_LABEL, "read FileDesc failed");
return IpcStatusCode::Failed as i32;
}
};
let mut args: Vec<String16> = match data.read::<Vec<String16>>() {
Ok(args) => args,
_ => {
error!(LOG_LABEL, "read String16 array failed");
return IpcStatusCode::Failed as i32;
}
};
rust_object.on_dump(&file, &mut args)
};
res
}
/// # Safety
///
/// The parameters passed in should ensure FFI safety
/// user_data pointer, data pointer and reply pointer on the c side must be guaranteed not to be null
unsafe extern "C" fn on_destroy(user_data: *mut c_void) {
info!(LOG_LABEL, "RemoteStub<T> on_destroy in Rust");
// T will be freed by Box after this function end.
......
......@@ -46,6 +46,13 @@ pub type OnRemoteRequest = unsafe extern "C" fn (
reply: *mut CParcel
) -> i32;
// Callback function type for OnRemoteDump() from native, this
// callback will be called when native recive client IPC dump.
pub type OnRemoteDump = unsafe extern "C" fn (
user_data: *mut c_void,
data: *const CParcel,
) -> i32;
// Callback function type for OnRemoteObjectDestroy() from native,
// this callback will be called when native remote object destroyed.
pub type OnRemoteObjectDestroy = unsafe extern "C" fn (
......@@ -87,6 +94,15 @@ pub type OnStringArrayRead = unsafe extern "C" fn(
len: u32 // C++ vector length
) -> bool;
// Callback function type for CParcelReadString16Array() from native.
// Rust side need read string one by one from native according calling
// CParcelReadString16Element().
pub type OnString16ArrayRead = unsafe extern "C" fn(
data: *const c_void, // C++ vector pointer
value: *mut c_void, // Rust vector pointer
len: u32 // C++ vector length
) -> bool;
// Callback function type for CParcelWriteStringArray() from native.
// Rust side need write string one by one to native according calling
// CParcelWriteStringElement().
......@@ -96,6 +112,15 @@ pub type OnStringArrayWrite = unsafe extern "C" fn(
len: u32, // Rust vector length
) -> bool;
// Callback function type for CParcelWriteString16Array() from native.
// Rust side need write string one by one to native according calling
// CParcelWriteString16Element().
pub type OnString16ArrayWrite = unsafe extern "C" fn(
array: *const c_void, // C++ vector pointer
value: *mut c_void, // Rust vector pointer
len: u32, // Rust vector length
) -> bool;
pub type OnCParcelWriteElement = unsafe extern "C" fn (
value: *mut CParcel,
arr: *const c_void,
......@@ -112,7 +137,7 @@ pub type OnCParcelReadElement = unsafe extern "C" fn (
extern "C" {
pub fn CreateRemoteStub(descripor: *const c_char, on_remote_request: OnRemoteRequest,
on_remote_object_destroy: OnRemoteObjectDestroy,
user_data: *const c_void) -> *mut CRemoteObject;
user_data: *const c_void, on_remote_dump: OnRemoteDump) -> *mut CRemoteObject;
pub fn RemoteObjectIncStrongRef(object: *mut CRemoteObject);
pub fn RemoteObjectDecStrongRef(object: *mut CRemoteObject);
......@@ -131,8 +156,7 @@ extern "C" {
recipient: *mut CDeathRecipient) -> bool;
pub fn IsProxyObject(object: *mut CRemoteObject) -> bool;
pub fn Dump(object: *mut CRemoteObject, fd: i32, value: *const c_void, len: i32,
writer: OnStringArrayWrite) -> i32;
pub fn Dump(object: *mut CRemoteObject, fd: i32, parcel: *mut CParcel) -> i32;
pub fn IsObjectDead(object: *mut CRemoteObject) -> bool;
pub fn GetInterfaceDescriptor(object: *mut CRemoteObject,
......@@ -200,14 +224,20 @@ extern "C" {
allocator: OnCParcelBytesAllocator::<f64>) -> bool;
pub fn CParcelWriteStringArray(parcel: *mut CParcel, value: *const c_void, len: i32,
writer: OnStringArrayWrite) -> bool;
pub fn CParcelWriteString16Array(parcel: *mut CParcel, value: *const c_void, len: i32,
writer: OnString16ArrayWrite) -> bool;
pub fn CParcelWriteStringElement(data: *const c_void, value: *const c_char,
len: i32) -> bool;
pub fn CParcelWritU16stringElement(data: *const c_void, value: *const c_char,
len: i32) -> bool;
pub fn CParcelReadStringArray(parcel: *const CParcel, value: *mut c_void,
reader: OnStringArrayRead) -> bool;
pub fn CParcelReadString16Array(parcel: *const CParcel, value: *mut c_void,
reader: OnString16ArrayRead) -> bool;
pub fn CParcelReadStringElement(index: u32, data: *const c_void, value: *mut c_void,
allocator: OnCParcelBytesAllocator::<u8>) -> bool;
pub fn CParcelReadString16Element(index: u32, data: *const c_void, value: *mut c_void,
allocator: OnCParcelBytesAllocator::<u16>) -> bool;
pub fn CParcelWriteParcelableArray(parcel: *mut CParcel, value: *const c_void, len: i32,
element_writer: OnCParcelWriteElement) -> bool;
pub fn CParcelReadParcelableArray(parcel: *const CParcel, value: *mut c_void,
......
......@@ -140,8 +140,37 @@ impl DeOption for FileDesc {
impl Deserialize for FileDesc {
fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> IpcResult<Self> {
Deserialize::deserialize(parcel)
.transpose()
.unwrap_or(Err(IpcStatusCode::Failed))
let mut fd = -1i32;
// SAFETY:
// `parcel` always contains a valid pointer to an `CParcel`.
// `CParcelWriteFileDescriptor` accepts the value `-1` as the file
// descriptor to signify serializing a null file descriptor.
// The read function passes ownership of the file
// descriptor to its caller if it was non-null, so we must take
// ownership of the file and ensure that it is eventually closed.
let ok_status = unsafe {
ipc_binding::CParcelReadFileDescriptor(
parcel.as_raw(),
&mut fd,
)
};
if ok_status{
if fd < 0 {
error!(LOG_LABEL, "file descriptor is invalid from native");
Err(IpcStatusCode::Failed)
} else {
// SAFETY:
// At this point, we know that the file descriptor was
// not -1, so must be a valid, owned file descriptor which we
// can safely turn into a `File`.
let file = unsafe {
File::from_raw_fd(fd)
};
Ok(FileDesc::new(file))
}
} else {
error!(LOG_LABEL, "read file descriptor failed from native");
Err(IpcStatusCode::Failed)
}
}
}
\ No newline at end of file
......@@ -16,6 +16,7 @@
use super::*;
use crate::{ipc_binding, BorrowedMsgParcel, IpcResult, IpcStatusCode, status_result, AsRawPtr};
use std::convert::TryInto;
use std::mem::MaybeUninit;
use std::ffi::{CString};
use hilog_rust::{error, hilog, HiLogLabel, LogType};
......@@ -86,6 +87,47 @@ impl Deserialize for String16 {
}
}
impl SerArray for String16 {
fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> IpcResult<()> {
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
let ret = unsafe {
ipc_binding::CParcelWriteString16Array(
parcel.as_mut_raw(),
slice.as_ptr() as *const c_void,
slice.len().try_into().unwrap(),
on_string16_writer,
)
};
status_result::<()>(ret as i32, ())
}
}
impl DeArray for String16 {
fn de_array(parcel: &BorrowedMsgParcel<'_>) -> IpcResult<Option<Vec<Self>>> {
let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// `allocate_vec<T>` expects the opaque pointer to
// be of type `*mut Option<Vec<MaybeUninit<T>>>`, so `&mut vec` is
// correct for it.
let ok_status = unsafe {
ipc_binding::CParcelReadString16Array(
parcel.as_raw(),
&mut vec as *mut _ as *mut c_void,
on_string16_reader,
)
};
if ok_status {
// SAFETY: all the MaybeUninits are now properly initialized.
let vec: Option<Vec<Self>> = unsafe {
vec.map(|vec| vec_assume_init(vec))
};
Ok(vec)
} else {
error!(LOG_LABEL, "read string16 from native fail");
Err(IpcStatusCode::Failed)
}
}
}
/// Callback to serialize a String16 array to c++ std::vector<std::u16string>.
///
/// # Safety:
......@@ -120,3 +162,51 @@ pub unsafe extern "C" fn on_string16_writer(
}
true
}
/// Callback to deserialize a String element in Vector<String16>.
///
/// # Safety:
///
/// The opaque array data pointer must be a mutable pointer to an
/// `Option<Vec<MaybeUninit<T>>>` with at least enough elements for `index` to be valid
/// (zero-based).
#[allow(dead_code)]
unsafe extern "C" fn on_string16_reader(
data: *const c_void, // C++ vector pointer
value: *mut c_void, // Rust vector pointer
len: u32, // C++ vector length
) -> bool {
// SAFETY:
// Allocate Vec<String16> capacity, data_len will set correctly by vec.push().
unsafe { allocate_vec_maybeuninit::<String16>(value, 0) };
let vec = &mut *(value as *mut Option<Vec<MaybeUninit<String16>>>);
for index in 0..len {
let mut vec_u16: Option<Vec<u16>> = None;
// SAFETY: The length of the index will not exceed the range,
// as the traversal range is the pointer length of the data passed from the C++side
let ok_status = unsafe {
ipc_binding::CParcelReadString16Element(
index,
data,
&mut vec_u16 as *mut _ as *mut c_void,
allocate_vec_with_buffer::<u16>
)
};
if ok_status {
if let Ok(string) = vec_u16_to_string(vec_u16) {
if let Some(new_vec) = vec {
new_vec.push(MaybeUninit::new(String16::new(string.as_str())));
} else {
error!(LOG_LABEL, "on_string_reader allocate vec failed");
return false;
}
} else {
error!(LOG_LABEL, "on_string_reader vec_to_string failed");
return false;
}
} else {
return false;
}
}
true
}
......@@ -32,6 +32,7 @@ struct CRemoteObjectHolder;
typedef struct CRemoteObjectHolder CRemoteObject;
typedef bool (*OnCParcelBytesAllocator)(void *stringData, char **buffer, int32_t len);
typedef bool (*OnCParcelBytesAllocator16)(void *stringData, int16_t **buffer, int32_t len);
typedef bool (*OnCParcelBoolAllocator)(void *value, bool **buffer, int32_t len);
typedef bool (*OnCParcelInt8Allocator)(void *value, int8_t **buffer, int32_t len);
typedef bool (*OnCParcelInt16Allocator)(void *value, int16_t **buffer, int32_t len);
......@@ -41,7 +42,9 @@ typedef bool (*OnCParcelFloatAllocator)(void *value, float **buffer, int32_t len
typedef bool (*OnCParcelDoubleAllocator)(void *value, double **buffer, int32_t len);
typedef bool (*OnCParcelAllocator)(void *value, int32_t len);
typedef bool (*OnStringArrayWrite)(const void *array, const void *value, uint32_t len);
typedef bool (*OnString16ArrayWrite)(const void *array, const void *value, uint32_t len);
typedef bool (*OnStringArrayRead)(const void *array, const void *value, uint32_t len);
typedef bool (*OnString16ArrayRead)(const void *array, const void *value, uint32_t len);
typedef bool (*OnCParcelWriteElement)(CParcel *value, const void *arr, unsigned long index);
typedef bool (*OnCParcelReadElement)(const CParcel *value, void *arr, unsigned long index);
......@@ -94,12 +97,17 @@ bool CParcelWriteDoubleArray(CParcel *parcel, const double *array, int32_t len);
bool CParcelReadDoubleArray(const CParcel *parcel, void *value, OnCParcelDoubleAllocator allocator);
bool CParcelWriteStringArray(CParcel *parcel, const void *value,
int32_t len, OnStringArrayWrite writer);
bool CParcelWriteString16Array(CParcel *parcel, const void *value,
int32_t len, OnString16ArrayWrite writer);
bool CParcelWriteStringElement(void *data, const char *value, int32_t len);
bool CParcelWritU16stringElement(void *data, const char16_t *value, int32_t len);
bool CParcelWritU16stringElement(void *data, const char *value, int32_t len);
bool CParcelReadStringArray(const CParcel *parcel, void *value, OnStringArrayRead reader);
bool CParcelReadString16Array(const CParcel *parcel, void *value, OnString16ArrayRead reader);
bool CParcelReadStringElement(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator allocator);
bool CParcelReadString16Element(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator16 allocator);
bool CParcelWriteParcelableArray(CParcel *parcel, const void *value, int32_t len,
OnCParcelWriteElement elementWriter);
......
......@@ -32,6 +32,7 @@ typedef struct CDeathRecipient CDeathRecipient;
// Callback as remote stub
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);
// Callback as death recipient
typedef void (*OnDeathRecipientCb)(const void *userData);
......@@ -40,7 +41,7 @@ typedef void (*OnDeathRecipientDestroyCb)(const void *userData);
typedef bool (*On16BytesAllocator)(void *stringData, uint16_t **buffer, int32_t len);
CRemoteObject *CreateRemoteStub(const char *desc, OnRemoteRequestCb callback,
OnRemoteObjectDestroyCb destroy, const void *userData);
OnRemoteObjectDestroyCb destroy, const void *userData, OnRemoteDumpCb dumpCallback);
void RemoteObjectIncStrongRef(CRemoteObject *object);
void RemoteObjectDecStrongRef(CRemoteObject *object);
......@@ -58,8 +59,7 @@ bool AddDeathRecipient(CRemoteObject *object, CDeathRecipient *recipient);
bool RemoveDeathRecipient(CRemoteObject *object, CDeathRecipient *recipient);
bool IsProxyObject(CRemoteObject *object);
int Dump(CRemoteObject *object, int fd, const void *value,
int32_t len, OnStringArrayWrite writer);
int Dump(CRemoteObject *object, int fd, CParcel *parcel);
bool IsObjectDead(CRemoteObject *object);
bool GetInterfaceDescriptor(CRemoteObject *object, void *value, On16BytesAllocator allocator);
......
......@@ -49,14 +49,17 @@ private:
class RemoteServiceHolderStub: public OHOS::IPCObjectStub {
public:
explicit RemoteServiceHolderStub(std::u16string &desc, OnRemoteRequestCb callback,
const void *userData, OnRemoteObjectDestroyCb destroy);
const void *userData, OnRemoteObjectDestroyCb destroy, OnRemoteDumpCb dump);
~RemoteServiceHolderStub();
int OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data,
OHOS::MessageParcel &reply, OHOS::MessageOption &option) override;
int OnRemoteDump(uint32_t code, OHOS::MessageParcel &data,
OHOS::MessageParcel &reply, OHOS::MessageOption &option) override;
private:
OnRemoteRequestCb callback_;
OnRemoteDumpCb dumpCallback_;
const void *userData_;
OnRemoteObjectDestroyCb destroy_;
};
......
......@@ -618,6 +618,26 @@ bool CParcelWriteStringArray(CParcel *parcel, const void *value,
return true;
}
bool CParcelWriteString16Array(CParcel *parcel, const void *value,
int32_t len, OnString16ArrayWrite writer)
{
if (!IsValidParcel(parcel, __func__) || writer == nullptr) {
return false;
}
std::vector<std::u16string> string16Vector;
if (len > 0 && !writer(reinterpret_cast<void *>(&string16Vector),
value, static_cast<uint32_t>(len))) {
ZLOGE(LOG_LABEL, "%{public}s: write u16string array to vector failed\n", __func__);
return false;
}
if (!parcel->parcel_->WriteString16Vector(string16Vector)) {
ZLOGE(LOG_LABEL, "%{public}s: write u16string array to parcel failed\n", __func__);
return false;
}
return true;
}
bool CParcelWriteStringElement(void *data, const char *value, int32_t len)
{
std::vector<std::string> *stringVector = reinterpret_cast<std::vector<std::string> *>(data);
......@@ -633,7 +653,7 @@ bool CParcelWriteStringElement(void *data, const char *value, int32_t len)
return true;
}
bool CParcelWritU16stringElement(void *data, const char16_t *value, int32_t len)
bool CParcelWritU16stringElement(void *data, const char *value, int32_t len)
{
std::vector<std::u16string> *u16stringVector = reinterpret_cast<std::vector<std::u16string> *>(data);
if (u16stringVector == nullptr) {
......@@ -644,7 +664,11 @@ bool CParcelWritU16stringElement(void *data, const char16_t *value, int32_t len)
ZLOGE(LOG_LABEL, "%{public}s: string len is invalid: %d\n", __func__, len);
return false;
}
u16stringVector->push_back(std::u16string(value, len));
std::u16string u16str = std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.from_bytes(
std::string(value, len));
u16stringVector->push_back(u16str);
return true;
}
......@@ -665,6 +689,56 @@ bool CParcelReadStringArray(const CParcel *parcel, void *value, OnStringArrayRea
return true;
}
bool CParcelReadString16Array(const CParcel *parcel, void *value, OnString16ArrayRead reader)
{
if (!IsValidParcel(parcel, __func__) || reader == nullptr) {
return false;
}
std::vector<std::u16string> string16Vector;
if (!parcel->parcel_->ReadString16Vector(&string16Vector)) {
ZLOGE(LOG_LABEL, "%{public}s: read u16string array from parcel failed\n", __func__);
return false;
}
if (!reader(reinterpret_cast<void *>(&string16Vector), value, string16Vector.size())) {
ZLOGE(LOG_LABEL, "%{public}s: read u16string to vector failed\n", __func__);
return false;
}
return true;
}
bool CParcelReadString16Element(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator16 allocator)
{
if (data == nullptr || allocator == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: invalid data and allocator\n", __func__);
return false;
}
const std::vector<std::u16string> *string16Vector =
reinterpret_cast<const std::vector<std::u16string> *>(data);
if (index >= string16Vector->size()) {
ZLOGE(LOG_LABEL, "%{public}s: invalid index: %u, size: %u\n", __func__,
index, static_cast<uint32_t>(string16Vector->size()));
return false;
}
const std::u16string &string16Value = (*string16Vector)[index];
int16_t *buffer = nullptr;
bool isSuccess = allocator(value, &buffer, string16Value.length());
if (!isSuccess) {
ZLOGE(LOG_LABEL, "%{public}s: allocate string16Value buffer failed\n", __func__);
return false;
}
if (string16Value.length() > 0 &&
memcpy_s(buffer, string16Value.length() * sizeof(char16_t),
string16Value.data(), string16Value.length() * sizeof(char16_t)) != EOK) {
ZLOGE(LOG_LABEL, "%{public}s: memcpy string16Value failed\n", __func__);
return false;
}
return true;
}
bool CParcelReadStringElement(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator allocator)
{
......
......@@ -25,9 +25,9 @@
using namespace OHOS;
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "CRemoteObject" };
RemoteServiceHolderStub::RemoteServiceHolderStub(std::u16string &desc,
OnRemoteRequestCb callback, const void *userData, OnRemoteObjectDestroyCb destroy)
: IPCObjectStub(desc), callback_(callback)
RemoteServiceHolderStub::RemoteServiceHolderStub(std::u16string &desc, OnRemoteRequestCb callback,
const void *userData, OnRemoteObjectDestroyCb destroy, OnRemoteDumpCb dumpCallback)
: IPCObjectStub(desc), callback_(callback), dumpCallback_(dumpCallback)
, userData_(userData), destroy_(destroy)
{
}
......@@ -53,6 +53,20 @@ int RemoteServiceHolderStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel
return callback_(userData_, code, &parcelData, &parcelReply);
}
int RemoteServiceHolderStub::OnRemoteDump(uint32_t code, OHOS::MessageParcel &data,
OHOS::MessageParcel &reply, OHOS::MessageOption &option)
{
(void)option;
(void)reply;
if (dumpCallback_ == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: dumpCallback_ is null for code: %u\n", __func__, code);
return -1;
}
CParcel parcelData(&data);
return dumpCallback_(userData_, &parcelData);
}
CDeathRecipient::CDeathRecipient(OnDeathRecipientCb onDeathRecipient,
OnDeathRecipientDestroyCb onDestroy, const void *userData)
: userData_(userData)
......@@ -92,7 +106,7 @@ bool IsValidRemoteObject(const CRemoteObject *object, const char *promot)
}
CRemoteObject *CreateRemoteStub(const char *desc, OnRemoteRequestCb callback,
OnRemoteObjectDestroyCb destroy, const void *userData)
OnRemoteObjectDestroyCb destroy, const void *userData, OnRemoteDumpCb dumpCallback)
{
if (desc == nullptr || callback == nullptr || destroy == nullptr) {
return nullptr;
......@@ -104,7 +118,7 @@ CRemoteObject *CreateRemoteStub(const char *desc, OnRemoteRequestCb callback,
}
std::u16string descriptor = Str8ToStr16(std::string(desc));
holder->remote_ = new (std::nothrow) RemoteServiceHolderStub(
descriptor, callback, userData, destroy);
descriptor, callback, userData, destroy, dumpCallback);
if (holder->remote_ == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: new RemoteServiceHolderStub failed\n", __func__);
delete holder;
......@@ -223,18 +237,20 @@ bool IsProxyObject(CRemoteObject *object)
return object->remote_->IsProxyObject();
}
int Dump(CRemoteObject *object, int fd, const void *value, int32_t len, OnStringArrayWrite writer)
int Dump(CRemoteObject *object, int fd, CParcel *parcel)
{
if (!IsValidRemoteObject(object, __func__) || writer == nullptr) {
if (!IsValidRemoteObject(object, __func__) || parcel == nullptr) {
ZLOGE(LOG_LABEL, "%{public}s: recipient is null\n", __func__);
return -1;
}
std::vector<std::u16string> stringVector;
if (len > 0 && !writer(reinterpret_cast<void *>(&stringVector), value, static_cast<uint32_t>(len))) {
ZLOGE(LOG_LABEL, "%{public}s: write string array to vector failed\n", __func__);
if (fd < 0) {
ZLOGE(LOG_LABEL, "%{public}s: fd is valid\n", __func__);
return -1;
}
return object->remote_->Dump(fd, stringVector);
std::vector<std::u16string> string16Vector;
parcel->parcel_->ReadString16Vector(&string16Vector);
return object->remote_->Dump(fd, string16Vector);
}
bool IsObjectDead(CRemoteObject *object)
......
......@@ -90,15 +90,6 @@ static bool Bytes16Allocator(void *stringData, uint16_t **buffer, int32_t len)
return true;
}
static bool StringArrayWrite(const void *array, const void *value, uint32_t len)
{
if (value == nullptr || len < 0) {
return false;
}
array = value;
return true;
}
/**
* @tc.name: CRemoteObjectRefCount
* @tc.desc: Verify the CRemoteObject reference count functions
......@@ -106,9 +97,9 @@ static bool StringArrayWrite(const void *array, const void *value, uint32_t len)
*/
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectRefCount, TestSize.Level1)
{
CRemoteObject *remote = CreateRemoteStub(nullptr, OnRemoteRequest, OnRemoteObjectDestroy, nullptr);
CRemoteObject *remote = CreateRemoteStub(nullptr, OnRemoteRequest, OnRemoteObjectDestroy, nullptr, nullptr);
EXPECT_EQ(remote, nullptr);
remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, nullptr);
remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, nullptr, nullptr);
EXPECT_NE(remote, nullptr);
RefBase *ref = static_cast<RefBase *>(remote);
EXPECT_EQ(ref->GetSptrRefCount(), 1);
......@@ -130,7 +121,7 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectRefCount, TestSize.Level1)
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectCompare, TestSize.Level1)
{
int8_t userData;
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
EXPECT_FALSE(RemoteObjectLessThan(nullptr, remote));
EXPECT_FALSE(RemoteObjectLessThan(remote, nullptr));
......@@ -216,7 +207,7 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CDeathRecipientStub, TestSize.Level1)
int8_t userData;
CDeathRecipient *recipient = CreateDeathRecipient(OnDeathRecipient, OnDeathRecipientDestroy, &userData);
EXPECT_NE(recipient, nullptr);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
EXPECT_FALSE(AddDeathRecipient(remote, recipient));
EXPECT_FALSE(RemoveDeathRecipient(remote, recipient));
......@@ -259,7 +250,7 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CDeathRecipient, TestSize.Level1)
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectIsProxyObject, TestSize.Level1)
{
int8_t userData;
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
bool ret = IsProxyObject(remote);
......@@ -274,7 +265,7 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectIsProxyObject, TestSize.Level1)
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectIsObjectDead, TestSize.Level1)
{
int8_t userData;
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
bool ret = IsObjectDead(remote);
......@@ -289,7 +280,7 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectIsObjectDead, TestSize.Level1)
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectGetInterfaceDescriptor, TestSize.Level1)
{
int8_t userData;
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
void *data = nullptr;
......@@ -308,10 +299,11 @@ HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectGetInterfaceDescriptor, TestSize
HWTEST_F(IpcCRemoteObjectUnitTest, CRemoteObjectDump, TestSize.Level1)
{
int8_t userData;
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData);
CRemoteObject *remote = CreateRemoteStub(SERVICE_NAME, OnRemoteRequest, OnRemoteObjectDestroy, &userData, nullptr);
EXPECT_NE(remote, nullptr);
const char *data = SERVICE_NAME;
int ret = Dump(remote, 0, reinterpret_cast<const void *>(&data), strlen(data), StringArrayWrite);
CParcel *parcel = CParcelObtain();
EXPECT_NE(parcel, nullptr);
int ret = Dump(remote, 0, parcel);
EXPECT_EQ(ret, 0);
}
\ No newline at end of file
......@@ -33,6 +33,7 @@ use ipc_rust::{
use ipc_rust::{Serialize, Deserialize, BorrowedMsgParcel, Ashmem};
use test_ipc_service::{ITest, TestProxy, IPC_TEST_SERVICE_ID, IFoo, init_access_token};
use std::fs::File;
use std::os::fd::AsRawFd;
fn get_test_service() -> RemoteObjRef<dyn ITest>
{
......@@ -786,8 +787,9 @@ fn test_is_proxy_object() {
fn test_dump() {
let object = get_service(IPC_TEST_SERVICE_ID).expect("get itest service failed");
let args: &mut Vec<String16> = &mut Vec::new();
let file = File::create("data.txt").expect("create failed");
args.push(String16::new("test.ipc.ITestService"));
let res = object.dump(0, args);
let res = object.dump(file.as_raw_fd(), args);
assert_eq!(0, res);
}
......
......@@ -24,9 +24,13 @@ use ipc_rust::{
get_calling_uid, String16, RemoteObj, IRemoteStub, get_local_device_id,
get_calling_device_id, IpcStatusCode,
};
use test_ipc_service::{ITest, TestStub, IPC_TEST_SERVICE_ID, reverse, IFoo, FooStub, init_access_token};
use test_ipc_service::{
ITest, TestStub, IPC_TEST_SERVICE_ID, IPC_TEST_STATUS_SUCCESS,
reverse, IFoo, FooStub, init_access_token, IPC_TEST_STATUS_FAILED,
};
use std::io::Write;
use std::fs::OpenOptions;
use std::os::fd::AsRawFd;
use std::{thread, time};
/// FooService type
......@@ -110,7 +114,22 @@ impl ITest for TestService {
}
}
impl IRemoteBroker for TestService {}
impl IRemoteBroker for TestService {
/// Dump implementation of service rewrite ipc
fn dump(&self, _file: &FileDesc, _args: &mut Vec<String16>) -> i32 {
let fd = _file.as_raw_fd();
if fd < 0 {
println!("fd is invalid: {}", fd);
return IPC_TEST_STATUS_FAILED;
}
for arg in _args.as_slice() {
println!("{}", arg.get_string().as_str());
_file.as_ref().write_all(arg.get_string().as_str().as_bytes()).expect("write failed");
}
IPC_TEST_STATUS_SUCCESS
}
}
fn main() {
init_access_token();
......
......@@ -9,7 +9,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import("//build/ohos.gni")
......@@ -21,10 +21,11 @@ ohos_rust_shared_library("test_ipc_service") {
"src/lib.rs",
]
deps = [
"$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust" ]
external_deps = [
"access_token:libnativetoken",
"access_token:libtoken_setproc",
]
crate_name = "test_ipc_service"
......
......@@ -43,6 +43,10 @@ pub fn reverse(mut value: i32) -> i32 {
/// SA ID for "test.ipc.ITestService"
pub const IPC_TEST_SERVICE_ID: i32 = 1118;
/// Test service success status
pub const IPC_TEST_STATUS_SUCCESS: i32 = 0;
/// Test service failed status
pub const IPC_TEST_STATUS_FAILED: i32 = -1;
/// Function code of ITestService
pub enum ITestCode {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册