提交 caf7796f 编写于 作者: F fanxiaoyu

Add ipc rust interface.

Signed-off-by: Nfanxiaoyu <fanxiaoyu3@huawei.com>
上级 4923df2e
......@@ -45,6 +45,7 @@ group("ipc_components") {
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder",
"//foundation/communication/ipc/interfaces/innerkits/rust:rust_ipc_component",
"//foundation/communication/ipc/ipc/native/src/core:ipc_common",
]
} else {
......
......@@ -77,7 +77,15 @@ macro_rules! define_remote_object {
fn on_remote_request(&self, code: u32, data: &$crate::BorrowedMsgParcel,
reply: &mut $crate::BorrowedMsgParcel) -> i32 {
// For example, "self.0" is "Box<dyn ITest>", "*self.0" is "dyn ITest"
$on_remote_request(&*self.0, code, data, reply)
let result = $on_remote_request(&*self.0, code, data, reply);
match result {
Ok(_) => 0,
Err(error) => {
println!("stub: {} deal fail: {} for code: {}", $descriptor,
error, code);
error
}
}
}
}
......
......@@ -19,6 +19,7 @@ pub mod macros;
use crate::{BorrowedMsgParcel, MsgParcel, Result, DeathRecipient};
use std::ops::{Deref};
use std::cmp::Ordering;
// Export types of this module
pub use crate::RemoteObj;
......@@ -76,4 +77,24 @@ impl<I: FromRemoteObj + ?Sized> Clone for RemoteObjRef<I> {
// non None
FromRemoteObj::from(self.0.as_object().unwrap()).unwrap()
}
}
\ No newline at end of file
}
impl<I: FromRemoteObj + ?Sized> Ord for RemoteObjRef<I> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.as_object().cmp(&other.0.as_object())
}
}
impl<I: FromRemoteObj + ?Sized> PartialOrd for RemoteObjRef<I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.as_object().partial_cmp(&other.0.as_object())
}
}
impl<I: FromRemoteObj + ?Sized> PartialEq for RemoteObjRef<I> {
fn eq(&self, other: &Self) -> bool {
self.0.as_object().eq(&other.0.as_object())
}
}
impl<I: FromRemoteObj + ?Sized> Eq for RemoteObjRef<I> {}
......@@ -14,11 +14,17 @@
*/
use std::ptr;
use crate::{ipc_binding, IRemoteObj, Result, MsgParcel, BorrowedMsgParcel, AsRawPtr};
use crate::{
ipc_binding, IRemoteObj, DeathRecipient, Result,
MsgParcel, BorrowedMsgParcel, AsRawPtr
};
use crate::ipc_binding::{CRemoteObject, CDeathRecipient};
use crate::parcel::parcelable::{Serialize, Deserialize};
use std::ffi::{c_void};
pub mod death_recipient;
pub mod cmp;
/// RemoteObject can be used as proxy or stub object.
/// It always contained a native CRemoteObject pointer.
/// # Invariant
......@@ -132,86 +138,3 @@ impl Drop for RemoteObj {
}
}
}
#[repr(C)]
pub struct DeathRecipient {
native: *mut CDeathRecipient,
callback: *mut c_void,
}
impl DeathRecipient {
pub fn new<F>(callback: F) -> Option<DeathRecipient>
where
F: Fn() + Send + Sync + 'static,
{
let callback = Box::into_raw(Box::new(callback));
let native = unsafe {
// set callback pointer to native, so we can find call which fuction
// when remote service died.
ipc_binding::CreateDeathRecipient(Self::on_remote_died::<F>,
Self::on_destroy::<F>, callback as *mut c_void)
};
if native.is_null() {
None
} else {
Some(DeathRecipient {
native,
callback: callback as *mut c_void,
})
}
}
/// Callback when remote service died by native.
///
/// # Safety
///
/// The callback parameter will be kept valid during native
/// CDeathRecipient object lifetime.
unsafe extern "C" fn on_remote_died<F>(callback: *mut c_void)
where
F: Fn() + Send + Sync + 'static,
{
let callback = (callback as *const F).as_ref().unwrap();
callback();
}
/// Callback when native CDeathRecipient destroyed
///
/// # Safety
///
/// The callback parameter will be kept valid during native
/// CDeathRecipient object lifetime.
unsafe extern "C" fn on_destroy<F>(callback: *mut c_void)
where
F: Fn() + Send + Sync + 'static,
{
if !callback.is_null() {
println!("death recipient on destroy");
Box::from_raw(callback as *mut F);
}
}
}
/// # Safety
///
/// A `DeathRecipient` is always constructed with a valid raw pointer
/// to a `CDeathRecipient`.
unsafe impl AsRawPtr<CDeathRecipient> for DeathRecipient {
fn as_raw(&self) -> *const CDeathRecipient {
self.native
}
fn as_mut_raw(&mut self) -> *mut CDeathRecipient {
self.native
}
}
impl Drop for DeathRecipient {
fn drop(&mut self) {
unsafe {
// Safety: DeathRecipient will always hold a reference for
// native CDeathRecipient.
ipc_binding::DeathRecipientDecStrongRef(self.native);
}
}
}
\ No newline at end of file
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* 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.
*/
use super::*;
use std::cmp::Ordering;
impl Ord for RemoteObj {
fn cmp(&self, other: &Self) -> Ordering {
let less_than = unsafe {
// SAFETY: RemoteObj always holds a valid `CRemoteObject` pointer\
// (null is also safe to pass to this function, but we should never do that).
ipc_binding::RemoteObjectLessThan(self.0.as_ptr(), other.0.as_ptr())
};
let greater_than = unsafe {
// SAFETY: RemoteObj always holds a valid `CRemoteObject` pointer\
// (null is also safe to pass to this function, but we should never do that).
ipc_binding::RemoteObjectLessThan(other.0.as_ptr(), self.0.as_ptr())
};
if !less_than && !greater_than {
Ordering::Equal
} else if less_than {
Ordering::Less
} else {
Ordering::Greater
}
}
}
impl PartialOrd for RemoteObj {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for RemoteObj {
fn eq(&self, other: &Self) -> bool {
ptr::eq(self.0.as_ptr(), other.0.as_ptr())
}
}
impl Eq for RemoteObj {}
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* 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.
*/
use super::*;
#[repr(C)]
pub struct DeathRecipient {
native: *mut CDeathRecipient,
callback: *mut c_void,
}
impl DeathRecipient {
pub fn new<F>(callback: F) -> Option<DeathRecipient>
where
F: Fn() + Send + Sync + 'static,
{
let callback = Box::into_raw(Box::new(callback));
let native = unsafe {
// set callback pointer to native, so we can find call which fuction
// when remote service died.
ipc_binding::CreateDeathRecipient(Self::on_remote_died::<F>,
Self::on_destroy::<F>, callback as *mut c_void)
};
if native.is_null() {
None
} else {
Some(DeathRecipient {
native,
callback: callback as *mut c_void,
})
}
}
/// Callback when remote service died by native.
///
/// # Safety
///
/// The callback parameter will be kept valid during native
/// CDeathRecipient object lifetime.
unsafe extern "C" fn on_remote_died<F>(callback: *mut c_void)
where
F: Fn() + Send + Sync + 'static,
{
let callback = (callback as *const F).as_ref().unwrap();
callback();
}
/// Callback when native CDeathRecipient destroyed
///
/// # Safety
///
/// The callback parameter will be kept valid during native
/// CDeathRecipient object lifetime.
unsafe extern "C" fn on_destroy<F>(callback: *mut c_void)
where
F: Fn() + Send + Sync + 'static,
{
if !callback.is_null() {
println!("death recipient on destroy");
Box::from_raw(callback as *mut F);
}
}
}
/// # Safety
///
/// A `DeathRecipient` is always constructed with a valid raw pointer
/// to a `CDeathRecipient`.
unsafe impl AsRawPtr<CDeathRecipient> for DeathRecipient {
fn as_raw(&self) -> *const CDeathRecipient {
self.native
}
fn as_mut_raw(&mut self) -> *mut CDeathRecipient {
self.native
}
}
impl Drop for DeathRecipient {
fn drop(&mut self) {
unsafe {
// Safety: DeathRecipient will always hold a reference for
// native CDeathRecipient.
ipc_binding::DeathRecipientDecStrongRef(self.native);
}
}
}
\ No newline at end of file
......@@ -76,6 +76,8 @@ extern "C" {
pub fn RemoteObjectGetUserData(object: *mut CRemoteObject) -> *const c_void;
pub fn RemoteObjectSendRequest(object: *mut CRemoteObject, code: u32, data: *const CParcel,
reply: *mut CParcel, is_async: bool) -> i32;
// Compare CRemoteObject
pub fn RemoteObjectLessThan(object: *const CRemoteObject, other: *const CRemoteObject) -> bool;
pub fn CreateDeathRecipient(onDeathRecipient: OnDeathRecipientCb, onDestroy: OnDeathRecipientDestroyCb,
userData: *const c_void) -> *mut CDeathRecipient;
......@@ -112,11 +114,30 @@ extern "C" {
allocator: OnCParcelBytesAllocator) -> bool;
pub fn CParcelWriteRemoteObject(parcel: *mut CParcel, object: *mut CRemoteObject) -> bool;
pub fn CParcelReadRemoteObject(parcel: *const CParcel) -> *mut CRemoteObject;
pub fn CParcelWriteBuffer(parcel: *mut CParcel, value: *const c_void, len: i32) -> bool;
pub fn CParcelReadBuffer(parcel: *const CParcel, value: *mut c_void, allocator: OnCParcelBytesAllocator) -> bool;
pub fn CParcelWriteFileDescriptor(parcel: *mut CParcel, fd: i32) -> bool;
pub fn CParcelReadFileDescriptor(parcel: *const CParcel, fd: *mut i32) -> bool;
pub fn CParcelGetDataSize(parcel: *const CParcel) -> u32;
pub fn CParcelSetDataSize(parcel: *mut CParcel, new_size: u32) -> bool;
pub fn CParcelGetDataCapacity(parcel: *const CParcel) -> u32;
pub fn CParcelSetDataCapacity(parcel: *mut CParcel, new_size: u32) -> bool;
pub fn CParcelGetMaxCapacity(parcel: *const CParcel) -> u32;
pub fn CParcelSetMaxCapacity(parcel: *mut CParcel, new_size: u32) -> bool;
pub fn CParcelGetWritableBytes(parcel: *const CParcel) -> u32;
pub fn CParcelGetReadableBytes(parcel: *const CParcel) -> u32;
pub fn CParcelGetReadPosition(parcel: *const CParcel) -> u32;
pub fn CParcelGetWritePosition(parcel: *const CParcel) -> u32;
pub fn CParcelRewindRead(parcel: *mut CParcel, new_pos: u32) -> bool;
pub fn CParcelRewindWrite(parcel: *mut CParcel, new_pos: u32) -> bool;
pub fn GetContextManager() -> *mut CRemoteObject;
pub fn JoinWorkThread();
pub fn StopWorkThread();
pub fn InitTokenId();
pub fn GetCallingTokenId() -> u64;
pub fn GetFirstToekenId() -> u64;
pub fn GetSelfToekenId() -> u64;
pub fn GetCallingPid() -> u64;
pub fn GetCallingUid() -> u64;
}
\ No newline at end of file
......@@ -23,16 +23,21 @@ pub mod process;
pub use crate::errors::{Result, result_status};
pub use crate::ipc::{
IRemoteBroker, IRemoteObj, IRemoteStub, FromRemoteObj, RemoteObjRef,
remote_obj::RemoteObj, remote_obj::DeathRecipient, remote_stub::RemoteStub,
remote_obj::RemoteObj, remote_obj::death_recipient::DeathRecipient, remote_stub::RemoteStub,
};
pub use crate::parcel::{MsgParcel, BorrowedMsgParcel,
pub use crate::parcel::{MsgParcel, BorrowedMsgParcel, IMsgParcel,
parcelable::{Serialize, Deserialize, SerOption, DeSerOption, SerArray, DeArray},
};
pub use crate::parcel::types::{
interface_token::InterFaceToken,
interface_token::InterfaceToken, file_desc::FileDesc,
string16::String16
};
pub use crate::process::{add_service, get_service, init_access_token, join_work_thread};
pub use crate::process::{
add_service, get_service, init_access_token, join_work_thread, stop_work_thread,
get_calling_token_id, get_first_token_id, get_self_token_id, get_calling_pid,
get_calling_uid,
};
/// First request code available for user IPC request(inclusive)
pub const FIRST_CALL_TRANSACTION: isize = 0x00000001;
......
......@@ -25,6 +25,82 @@ use std::ptr::{NonNull};
use crate::AsRawPtr;
use crate::parcel::parcelable::{Serialize, Deserialize};
/// This trait implements the common function for MsgParcel
/// and BorrowedMsgParcel
pub trait IMsgParcel: AsRawPtr<CParcel> {
fn get_data_size(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetDataSize(self.as_raw())
}
}
fn set_data_size(&mut self, new_size: u32) -> bool {
unsafe {
ipc_binding::CParcelSetDataSize(self.as_mut_raw(), new_size)
}
}
fn get_data_capacity(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetDataCapacity(self.as_raw())
}
}
fn set_data_capacity(&mut self, new_size: u32) -> bool {
unsafe {
ipc_binding::CParcelSetDataCapacity(self.as_mut_raw(), new_size)
}
}
fn get_max_capacity(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetMaxCapacity(self.as_raw())
}
}
fn set_max_capacity(&mut self, new_size: u32) -> bool {
unsafe {
ipc_binding::CParcelSetMaxCapacity(self.as_mut_raw(), new_size)
}
}
fn get_writable_bytes(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetWritableBytes(self.as_raw())
}
}
fn get_readable_bytes(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetReadableBytes(self.as_raw())
}
}
fn get_read_position(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetReadPosition(self.as_raw())
}
}
fn get_write_position(&self) -> u32 {
unsafe {
ipc_binding::CParcelGetWritePosition(self.as_raw())
}
}
fn rewind_read(&mut self, new_pos: u32) -> bool {
unsafe {
ipc_binding::CParcelRewindRead(self.as_mut_raw(), new_pos)
}
}
fn rewind_write(&mut self, new_pos: u32) -> bool {
unsafe {
ipc_binding::CParcelRewindWrite(self.as_mut_raw(), new_pos)
}
}
}
/// Container for a message (data and object references) that can be sent
/// through Binder.
///
......@@ -36,6 +112,8 @@ pub struct MsgParcel {
unsafe impl Send for MsgParcel {}
impl IMsgParcel for MsgParcel {}
impl MsgParcel {
pub fn new() -> Option<Self> {
let cparcel: *mut CParcel = unsafe {
......@@ -63,6 +141,16 @@ impl MsgParcel {
_mark: PhantomData,
}
}
/// Get an immutable borrowed view into the contents of this `MsgParcel`.
pub fn borrowed_ref(&self) -> &BorrowedMsgParcel<'_> {
// Safety: MsgParcel and BorrowedParcel are both represented in the same
// way as a NonNull<CParcel> due to their use of repr(transparent),
// so casting references as done here is valid.
unsafe {
&*(self as *const MsgParcel as *const BorrowedMsgParcel<'_>)
}
}
}
/// # Safety
......@@ -97,6 +185,8 @@ pub struct BorrowedMsgParcel<'a> {
_mark: PhantomData<&'a mut MsgParcel>,
}
impl<'a> IMsgParcel for BorrowedMsgParcel<'a> {}
impl<'a> BorrowedMsgParcel<'a> {
/// # Safety:
......@@ -132,7 +222,6 @@ unsafe impl<'a> AsRawPtr<CParcel> for BorrowedMsgParcel<'a> {
}
}
impl MsgParcel {
pub fn read<D: Deserialize>(&self) -> Result<D> {
self.borrowed_ref().read()
......@@ -141,16 +230,6 @@ impl MsgParcel {
pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
self.borrowed().write(parcelable)
}
/// Get an immutable borrowed view into the contents of this `MsgParcel`.
pub fn borrowed_ref(&self) -> &BorrowedMsgParcel<'_> {
// Safety: MsgParcel and BorrowedParcel are both represented in the same
// way as a NonNull<CParcel> due to their use of repr(transparent),
// so casting references as done here is valid.
unsafe {
&*(self as *const MsgParcel as *const BorrowedMsgParcel<'_>)
}
}
}
impl<'a> BorrowedMsgParcel<'a> {
......
......@@ -65,7 +65,6 @@ pub const NON_NULL_FLAG : i32 = 1;
// DOC TODO
pub trait SerOption: Serialize {
fn ser_option(this: Option<&Self>, parcel: &mut BorrowedMsgParcel<'_>) -> Result<(), > {
if let Some(inner) = this {
parcel.write(&NON_NULL_FLAG)?;
......@@ -78,7 +77,6 @@ pub trait SerOption: Serialize {
// DOC TODO
pub trait DeSerOption: Deserialize {
fn de_option(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Self>> {
let null: i32 = parcel.read()?;
if null == NULL_FLAG {
......
......@@ -20,5 +20,6 @@ pub mod reference;
pub mod strings;
pub mod interface_token;
pub mod string16;
pub mod file_desc;
use crate::parcel::parcelable::*;
\ No newline at end of file
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* 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.
*/
use super::*;
use crate::{ipc_binding, BorrowedMsgParcel, AsRawPtr, result_status, Result};
use std::fs::File;
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
/// Rust version of the Java class android.os.ParcelFileDescriptor
#[derive(Debug)]
pub struct FileDesc(File);
impl FileDesc {
pub fn new(file: File) -> Self {
Self(file)
}
}
impl AsRef<File> for FileDesc {
fn as_ref(&self) -> &File {
&self.0
}
}
impl From<FileDesc> for File {
fn from(file: FileDesc) -> File {
file.0
}
}
impl AsRawFd for FileDesc {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl IntoRawFd for FileDesc {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
impl PartialEq for FileDesc {
// Since ParcelFileDescriptors own the FD, if this function ever returns true (and it is used to
// compare two different objects), then it would imply that an FD is double-owned.
fn eq(&self, other: &Self) -> bool {
self.as_raw_fd() == other.as_raw_fd()
}
}
impl Eq for FileDesc {}
impl Serialize for FileDesc {
fn serialize(&self, parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
let fd = self.0.as_raw_fd();
let ret = unsafe {
// SAFETY: `parcel` always contains a valid pointer to an `CParcel`.
ipc_binding::CParcelWriteFileDescriptor(parcel.as_mut_raw(), fd)
};
result_status::<()>(ret, ())
}
}
impl SerOption for FileDesc {
fn ser_option(this: Option<&Self>, parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
if let Some(f) = this {
f.serialize(parcel)
} else {
let ret = unsafe {
// 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.
ipc_binding::CParcelWriteFileDescriptor(parcel.as_mut_raw(), -1i32)
};
result_status::<()>(ret, ())
}
}
}
impl DeSerOption for FileDesc {
fn de_option(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Self>> {
let mut fd = -1i32;
let ok_status = unsafe {
// 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.
ipc_binding::CParcelReadFileDescriptor(
parcel.as_raw(),
&mut fd,
)
};
if ok_status{
if fd < 0 {
println!("file descriptor is invalid from native");
Err(-1)
} else {
let file = unsafe {
// 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`.
File::from_raw_fd(fd)
};
Ok(Some(FileDesc::new(file)))
}
} else {
println!("read file descriptor failed from native");
Err(-1)
}
}
}
impl Deserialize for FileDesc {
fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel)
.transpose()
.unwrap_or(Err(-1))
}
}
\ No newline at end of file
......@@ -18,15 +18,19 @@ use crate::{ipc_binding, BorrowedMsgParcel, Result, AsRawPtr, result_status};
use std::ffi::{c_char, c_void};
use std::convert::TryInto;
pub struct InterFaceToken(String);
pub struct InterfaceToken(String);
impl InterFaceToken {
impl InterfaceToken {
pub fn new(value: &str) -> Self {
Self(String::from(value))
}
pub fn get_token(&self) -> String {
String::from(&self.0)
}
}
impl Serialize for InterFaceToken {
impl Serialize for InterfaceToken {
fn serialize(&self, parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
let token = &self.0;
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
......@@ -40,7 +44,7 @@ impl Serialize for InterFaceToken {
}
}
impl Deserialize for InterFaceToken {
impl Deserialize for InterfaceToken {
fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> Result<Self> {
let mut vec: Option<Vec<u8>> = None;
let ok_status = unsafe {
......@@ -54,7 +58,6 @@ impl Deserialize for InterFaceToken {
if ok_status {
let result = vec.map(|s| {
println!("read interface token from native success, s: {:?}", s);
match String::from_utf8(s) {
Ok(val) => val,
Err(_) => String::from("")
......@@ -72,4 +75,3 @@ impl Deserialize for InterFaceToken {
}
}
}
......@@ -24,6 +24,10 @@ impl String16 {
pub fn new(value: &str) -> Self {
Self(String::from(value))
}
pub fn get_string(&self) -> String {
String::from(&self.0)
}
}
impl Serialize for String16 {
......@@ -66,10 +70,9 @@ impl Deserialize for String16 {
println!("convert native string16 to String fail");
Err(-1)
}
}else{
} else {
println!("read string16 from native fail");
Err(-1)
}
}
}
......@@ -13,7 +13,10 @@
* limitations under the License.
*/
use crate::{ipc_binding, MsgParcel, RemoteObj, IRemoteObj, InterFaceToken, String16};
use crate::{
ipc_binding, MsgParcel, RemoteObj, IRemoteObj, InterfaceToken, String16,
Result,
};
fn get_samgr() -> Option<RemoteObj>
{
......@@ -23,64 +26,47 @@ fn get_samgr() -> Option<RemoteObj>
}
}
pub fn add_service(service: &RemoteObj, said: i32)
pub fn add_service(service: &RemoteObj, said: i32) -> Result<()>
{
let samgr = get_samgr().expect("samgr is not null");
let mut data = MsgParcel::new().expect("MsgParcel is not null");
match data.write(&InterFaceToken::new("ohos.samgr.accessToken")) {
Ok(()) => { println!("write token success") }
Err(val) => { println!("write token fail: {}", val) }
}
match data.write(&said) {
Ok(()) => { println!("write said success") }
Err(val) => { println!("write said fail: {}", val) }
}
match data.write(service) {
Ok(()) => { println!("write service success") }
Err(val) => { println!("write service fail: {}", val) }
}
match data.write(&false) {
Ok(()) => { println!("write bool success") }
Err(val) => { println!("write bool fail: {}", val) }
}
match data.write(&0) {
Ok(()) => { println!("write 0 success") }
Err(val) => { println!("write 0 fail: {}", val) }
}
match data.write(&String16::new("")) {
Ok(()) => { println!("write string16 111 success") }
Err(val) => { println!("write string16 111 fail: {}", val) }
}
match data.write(&String16::new("")) {
Ok(()) => { println!("write string16 222 success") }
Err(val) => { println!("write string16 222 fail: {}", val) }
}
let reply = samgr.send_request(3, &data, false).expect("failed to register service");
let replyValue: i32 = reply.read().expect("register service reply should 0");
let _ = data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
let _ = data.write(&said)?;
let _ = data.write(service)?;
let _ = data.write(&false)?;
let _ = data.write(&0)?;
let _ = data.write(&String16::new(""))?;
let _ = data.write(&String16::new(""))?;
let reply = samgr.send_request(3, &data, false)?;
let replyValue: i32 = reply.read()?;
println!("register service result: {}", replyValue);
if replyValue == 0 { Ok(())} else { Err(replyValue) }
}
pub fn get_service(said: i32) -> RemoteObj
pub fn get_service(said: i32) -> Result<RemoteObj>
{
let samgr = get_samgr().expect("samgr is not null");
let mut data = MsgParcel::new().expect("MsgParcel is not null");
match data.write(&InterFaceToken::new("ohos.samgr.accessToken")) {
Ok(()) => { println!("write token success") }
Err(val) => { println!("write token fail: {}", val) }
}
match data.write(&said) {
Ok(()) => { println!("write said success") }
Err(val) => { println!("write said fail: {}", val) }
}
let reply = samgr.send_request(2, &data, false).expect("Failed to get service");
let remote: RemoteObj = reply.read().expect("Failed to read remote object");
println!("register service result");
return remote;
let _ = data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
let _ = data.write(&said)?;
let reply = samgr.send_request(2, &data, false)?;
let remote: RemoteObj = reply.read()?;
println!("get service success");
Ok(remote)
}
pub fn join_work_thread()
{
unsafe { ipc_binding::JoinWorkThread(); }
unsafe {
ipc_binding::JoinWorkThread();
}
}
pub fn stop_work_thread()
{
unsafe {
ipc_binding::StopWorkThread()
}
}
pub fn init_access_token()
......@@ -89,3 +75,38 @@ pub fn init_access_token()
ipc_binding::InitTokenId();
}
}
pub fn get_calling_token_id() -> u64
{
unsafe {
ipc_binding::GetCallingTokenId()
}
}
pub fn get_first_token_id() -> u64
{
unsafe {
ipc_binding::GetFirstToekenId()
}
}
pub fn get_self_token_id() -> u64
{
unsafe {
ipc_binding::GetSelfToekenId()
}
}
pub fn get_calling_pid() -> u64
{
unsafe {
ipc_binding::GetCallingPid()
}
}
pub fn get_calling_uid() -> u64
{
unsafe {
ipc_binding::GetCallingUid()
}
}
\ No newline at end of file
......@@ -18,20 +18,19 @@ extern crate test_ipc_service;
use std::thread;
use std::time::Duration;
use std::io::Write;
use ipc_rust::{
FromRemoteObj, DeathRecipient, IRemoteObj,
get_service, init_access_token
FromRemoteObj, DeathRecipient, IRemoteObj, FileDesc, RemoteObjRef,
MsgParcel, String16, InterfaceToken, get_service, init_access_token,
get_first_token_id, get_self_token_id, get_calling_pid, get_calling_uid,
IMsgParcel,
};
use test_ipc_service::{ITest, IPC_TEST_SERVICE_ID};
use std::fs::OpenOptions;
#[test]
fn test_add_access_token() {
init_access_token();
}
#[test]
fn test_ipc_request() {
let object = get_service(IPC_TEST_SERVICE_ID);
fn get_test_service() -> RemoteObjRef<dyn ITest>
{
let object = get_service(IPC_TEST_SERVICE_ID).expect("get itest service failed");
let remote = <dyn ITest as FromRemoteObj>::from(object);
let remote = match remote {
Ok(x) => x,
......@@ -40,29 +39,32 @@ fn test_ipc_request() {
panic!();
}
};
return remote;
}
#[test]
fn test_add_access_token() {
init_access_token();
}
#[test]
fn test_ipc_request() {
let remote = get_test_service();
assert_eq!(remote.echo_str("hello"), "hello");
}
#[test]
fn test_request_concurrent() {
let object = get_service(IPC_TEST_SERVICE_ID);
let remote = <dyn ITest as FromRemoteObj>::from(object);
let remote = match remote {
Ok(x) => x,
Err(error) => {
println!("convert RemoteObj to TestProxy failed: {}", error);
panic!();
}
};
for i in 1..=5 {
assert_eq!(remote.request_concurent(false), true);
assert_eq!(remote.request_concurent(true), true);
let remote = get_test_service();
for _i in 1..=5 {
assert!(remote.request_concurent(false));
assert!(remote.request_concurent(true));
}
}
#[test]
fn test_death_recipient_001() {
let object = get_service(IPC_TEST_SERVICE_ID);
let object = get_service(IPC_TEST_SERVICE_ID).expect("get itest service failed");
let mut death_recipient = DeathRecipient::new(|| {
println!("recv death recipient in rust");
}).expect("new death recipient failed");
......@@ -74,11 +76,164 @@ fn test_death_recipient_001() {
#[test]
fn test_death_recipient_002() {
let object = get_service(IPC_TEST_SERVICE_ID);
let object = get_service(IPC_TEST_SERVICE_ID).expect("get itest service failed");
let mut death_recipient = DeathRecipient::new(|| {
println!("recv death recipient in rust");
}).expect("new death recipient failed");
assert_eq!(object.add_death_recipient(&mut death_recipient), true);
println!("please kill remote ITest service");
thread::sleep(Duration::from_secs(10));
}
#[test]
fn test_parcel_interface_token() {
let remote = get_test_service();
let token = InterfaceToken::new("Hello, Rust");
let echo_token = remote.echo_interface_token(&token).expect("echo normal interface token failed");
assert_eq!(token.get_token(), echo_token.get_token());
let token = InterfaceToken::new("");
let echo_token = remote.echo_interface_token(&token).expect("echo empty interface token failed");
assert_eq!(token.get_token(), echo_token.get_token());
}
#[test]
fn test_parcel_string() {
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
parcel.write("Hello").expect("write str failed");
parcel.write("").expect("write empty str failed");
parcel.write(&String::from("Hello")).expect("write String failed");
parcel.write(&String::from("")).expect("write empty String failed");
let hello_str: String = parcel.read().expect("read str failed");
assert_eq!(hello_str, "Hello");
let empty_str: String = parcel.read().expect("read empty str failed");
assert_eq!(empty_str, "");
let hello_str: String = parcel.read().expect("read String failed");
assert_eq!(hello_str, String::from("Hello"));
let empty_str: String = parcel.read().expect("read empty String failed");
assert_eq!(empty_str, String::from(""));
}
#[test]
fn test_parcel_string16() {
let hello_str = String16::new("Hello");
let empty_str = String16::new("");
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
parcel.write(&hello_str).expect("write String16 failed");
parcel.write("").expect("write empty String16 failed");
let read_hello_str: String16 = parcel.read().expect("read String16 failed");
assert_eq!(hello_str.get_string(), read_hello_str.get_string());
let read_empty_str: String16 = parcel.read().expect("read empty String16 failed");
assert_eq!(empty_str.get_string(), read_empty_str.get_string());
}
#[test]
fn test_parcel_basic_data_type() {
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
parcel.write(&false).expect("write false failed");
parcel.write(&true).expect("write true failed");
parcel.write(&1_u8).expect("write u8 failed");
parcel.write(&2_i8).expect("write i8 failed");
parcel.write(&3_u16).expect("write u16 failed");
parcel.write(&4_i16).expect("write i16 failed");
parcel.write(&5_u32).expect("write u32 failed");
parcel.write(&6_i32).expect("write i32 failed");
parcel.write(&7_u64).expect("write u64 failed");
parcel.write(&8_i64).expect("write i64 failed");
parcel.write(&1.1_f32).expect("write f32 failed");
parcel.write(&2.2_f64).expect("write f64 failed");
let value: bool = parcel.read().expect("read false failed");
assert_eq!(value, false);
let value: bool = parcel.read().expect("read true failed");
assert_eq!(value, true);
let value: u8 = parcel.read().expect("read u8 failed");
assert_eq!(value, 1_u8);
let value: i8 = parcel.read().expect("read i8 failed");
assert_eq!(value, 2_i8);
let value: u16 = parcel.read().expect("read u16 failed");
assert_eq!(value, 3_u16);
let value: i16 = parcel.read().expect("read i16 failed");
assert_eq!(value, 4_i16);
let value: u32 = parcel.read().expect("read u32 failed");
assert_eq!(value, 5_u32);
let value: i32 = parcel.read().expect("read i32 failed");
assert_eq!(value, 6_i32);
let value: u64 = parcel.read().expect("read u64 failed");
assert_eq!(value, 7_u64);
let value: i64 = parcel.read().expect("read i64 failed");
assert_eq!(value, 8_i64);
let value: f32 = parcel.read().expect("read f32 failed");
assert!((value - 1.1_f32).abs() < 0.00001);
let value: f64 = parcel.read().expect("read f64 failed");
assert!((value - 2.2_f64).abs() < 0.00001);
}
#[test]
fn test_parcel_info() {
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
let max_capacity = parcel.get_max_capacity();
assert!(max_capacity > 0);
assert!(parcel.set_max_capacity(max_capacity + 1));
assert_eq!(parcel.get_max_capacity(), max_capacity + 1);
assert_eq!(parcel.get_data_size(), 0);
assert_eq!(parcel.get_data_capacity(), 0);
assert_eq!(parcel.get_writable_bytes(), 0);
assert_eq!(parcel.get_readable_bytes(), 0);
assert_eq!(parcel.get_read_position(), 0);
assert_eq!(parcel.get_write_position(), 0);
parcel.write("Hello").expect("write hello failed");
let data_size = parcel.get_data_size();
assert!(data_size > 0);
assert!(parcel.get_data_capacity() > 0);
assert!(parcel.get_writable_bytes() > 0);
assert!(parcel.get_readable_bytes() > 0);
assert_eq!(parcel.get_read_position(), 0);
assert!(parcel.get_write_position() > 0);
let _: String = parcel.read().expect("read String failed");
assert_eq!(parcel.get_readable_bytes(), 0);
assert!(parcel.get_read_position() > 0);
assert!(parcel.set_data_size(data_size - 1));
assert!(parcel.set_data_capacity(data_size + 1));
assert!(parcel.rewind_read(0));
assert!(parcel.rewind_write(0));
assert_eq!(parcel.get_data_size(), 0);
assert!(parcel.get_data_capacity() > 0);
assert!(parcel.get_writable_bytes() > 0);
assert_eq!(parcel.get_readable_bytes(), 0);
assert_eq!(parcel.get_read_position(), 0);
assert_eq!(parcel.get_write_position(), 0);
}
#[test]
fn test_calling_info() {
let remote = get_test_service();
let (token_id, first_token_id, pid, uid) =
remote.echo_calling_info().expect("echo calling info failed");
assert_eq!(token_id, get_self_token_id());
assert_eq!(first_token_id, get_first_token_id());
assert_eq!(pid, get_calling_pid());
assert_eq!(uid, get_calling_uid());
}
#[test]
fn test_parcel_fd() {
let remote = get_test_service();
let path = "/data/test_fd";
let mut value = OpenOptions::new().read(true)
.write(true)
.create(true)
.open(path).expect("create data failed");
let file_content = "Rust IPC Pass FD";
write!(value, "{}", file_content);
assert_eq!(remote.pass_file(FileDesc::new(value)), file_content);
}
\ No newline at end of file
......@@ -17,10 +17,13 @@ extern crate ipc_rust;
extern crate test_ipc_service;
use ipc_rust::{
IRemoteBroker, join_work_thread,
add_service, init_access_token
IRemoteBroker, join_work_thread, FileDesc, InterfaceToken, Result,
add_service, init_access_token, get_calling_token_id, get_first_token_id,
get_calling_pid, get_calling_uid,
};
use test_ipc_service::{ITest, TestStub, IPC_TEST_SERVICE_ID};
use std::io::{Read, Seek, SeekFrom};
use std::fs::File;
pub struct TestService;
......@@ -34,6 +37,28 @@ impl ITest for TestService {
println!("TestService request_concurent: {}", is_async);
true
}
fn pass_file(&self, fd: FileDesc) -> String {
let mut info = String::new();
let mut file = File::from(fd);
file.seek(SeekFrom::Start(0));
file.read_to_string(&mut info).expect("The string cannot be read");
println!("file content: {}", info);
info
}
fn echo_interface_token(&self, token: &InterfaceToken) -> Result<InterfaceToken> {
Ok(InterfaceToken::new(&token.get_token()))
}
fn echo_calling_info(&self) -> Result<(u64, u64, u64, u64)> {
let token_id = get_calling_token_id();
let first_token_id = get_first_token_id();
let pid = get_calling_pid();
let uid = get_calling_uid();
println!("{}, {}, {}, {}", token_id, first_token_id, pid, uid);
Ok((token_id, first_token_id, pid, uid))
}
}
impl IRemoteBroker for TestService {}
......@@ -42,7 +67,8 @@ fn main() {
init_access_token();
// create stub
let service = TestStub::new_remote_stub(TestService).expect("create TestService success");
add_service(&service.as_object().unwrap(), IPC_TEST_SERVICE_ID);
add_service(&service.as_object().expect("get ITest service failed"),
IPC_TEST_SERVICE_ID);
println!("join to ipc work thread");
join_work_thread();
}
\ No newline at end of file
......@@ -18,44 +18,66 @@ extern crate ipc_rust;
// Import types
// use std::convert::{TryFrom, TryInto};
use ipc_rust::{
IRemoteBroker, IRemoteObj, RemoteStub,
IRemoteBroker, IRemoteObj, RemoteStub, Result,
RemoteObj, define_remote_object, FIRST_CALL_TRANSACTION
};
use ipc_rust::{MsgParcel, BorrowedMsgParcel};
use ipc_rust::{
MsgParcel, BorrowedMsgParcel, FileDesc, InterfaceToken,
};
pub const IPC_TEST_SERVICE_ID: i32 = 1118;
pub enum ITestCode {
CodeEchoStr = FIRST_CALL_TRANSACTION,
CodeRequestConcurrent,
}
impl ITestCode {
fn to_u32(self) -> u32 {
self as u32
}
CodeRequestConcurrent = 2,
CodePassFd = 3,
CodeInterfaceToekn = 4,
CodeCallingInfo = 5,
}
pub trait ITest: IRemoteBroker {
fn echo_str(&self, value: &str) -> String;
fn request_concurent(&self, is_async: bool) -> bool;
fn pass_file(&self, fd: FileDesc) -> String;
fn echo_interface_token(&self, token: &InterfaceToken) -> Result<InterfaceToken>;
fn echo_calling_info(&self) -> Result<(u64, u64, u64, u64)>;
}
fn on_remote_request(stub: &dyn ITest, code: u32, data: &BorrowedMsgParcel,
reply: &mut BorrowedMsgParcel) -> i32 {
reply: &mut BorrowedMsgParcel) -> Result<()> {
println!("on_remote_reuqest in Rust TestStub, code: {}", code);
match code {
1 => {
let value: String = data.read().expect("should have a string");
let value = stub.echo_str(&value);
reply.write(&value);
0
Ok(())
}
2 => {
stub.request_concurent(true);
0
Ok(())
}
3 => {
let fd: FileDesc = data.read().expect("should have a fd");
let value = stub.pass_file(fd);
reply.write(&value);
Ok(())
}
4 => {
let token: InterfaceToken = data.read().expect("should have a interface token");
let value = stub.echo_interface_token(&token).expect("service deal echo token failed");
reply.write(&value).expect("write echo token result failed");
Ok(())
}
5 => {
let (token_id, first_token_id, pid, uid) = stub.echo_calling_info()?;
reply.write(&token_id).expect("write token id failed");
reply.write(&first_token_id).expect("write first token id failed");
reply.write(&pid).expect("write pid failed");
reply.write(&uid).expect("write uid failed");
Ok(())
}
_ => -1
_ => Err(-1)
}
}
......@@ -77,6 +99,18 @@ impl ITest for RemoteStub<TestStub> {
fn request_concurent(&self, is_async: bool) -> bool {
self.0.request_concurent(is_async)
}
fn pass_file(&self, fd: FileDesc) -> String {
self.0.pass_file(fd)
}
fn echo_interface_token(&self, token: &InterfaceToken) -> Result<InterfaceToken> {
self.0.echo_interface_token(token)
}
fn echo_calling_info(&self) -> Result<(u64, u64, u64, u64)> {
self.0.echo_calling_info()
}
}
impl ITest for TestProxy {
......@@ -90,7 +124,7 @@ impl ITest for TestProxy {
let echo_value: String = reply.read().expect("need reply value");
echo_value
}
Err(error) => {
Err(_) => {
String::from("Error")
}
}
......@@ -105,4 +139,40 @@ impl ITest for TestProxy {
Err(_) => false
}
}
fn pass_file(&self, fd: FileDesc) -> String {
let mut data = MsgParcel::new().expect("MsgParcel should success");
data.write(&fd).expect("write fd should success");
let reply =
self.remote.send_request(ITestCode::CodePassFd as u32, &data, false);
match reply {
Ok(reply) => {
let echo_value: String = reply.read().expect("need reply value");
echo_value
}
Err(_) => {
String::from("Error")
}
}
}
fn echo_interface_token(&self, token: &InterfaceToken) -> Result<InterfaceToken> {
let mut data = MsgParcel::new().expect("MsgParcel should success");
data.write(token).expect("write token should success");
let reply = self.remote.send_request(ITestCode::CodeInterfaceToekn as u32,
&data, false)?;
let echo_value: InterfaceToken = reply.read().expect("need reply token");
Ok(echo_value)
}
fn echo_calling_info(&self) -> Result<(u64, u64, u64, u64)> {
let mut data = MsgParcel::new().expect("MsgParcel should success");
let reply = self.remote.send_request(ITestCode::CodeCallingInfo as u32,
&data, false)?;
let token_id: u64 = reply.read().expect("need reply calling token id");
let first_token_id: u64 = reply.read().expect("need reply first calling token id");
let pid: u64 = reply.read().expect("need reply calling pid");
let uid: u64 = reply.read().expect("need reply calling uid");
Ok((token_id, first_token_id, pid, uid))
}
}
\ No newline at end of file
......@@ -57,6 +57,21 @@ bool CParcelWriteInterfaceToken(CParcel *parcel, const char *token, int32_t toke
bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelBytesAllocator allocator);
bool CParcelWriteRemoteObject(CParcel *parcel, const CRemoteObject *object);
CRemoteObject *CParcelReadRemoteObject(const CParcel *parcel);
bool CParcelWriteFileDescriptor(CParcel *parcel, int32_t fd);
bool CParcelReadFileDescriptor(const CParcel *parcel, int32_t *fd);
uint32_t CParcelGetDataSize(const CParcel *parcel);
bool CParcelSetDataSize(CParcel *parcel, uint32_t new_size);
uint32_t CParcelGetDataCapacity(const CParcel *parcel);
bool CParcelSetDataCapacity(CParcel *parcel, uint32_t new_size);
uint32_t CParcelGetMaxCapacity(const CParcel *parcel);
bool CParcelSetMaxCapacity(CParcel *parcel, uint32_t new_size);
uint32_t CParcelGetWritableBytes(const CParcel *parcel);
uint32_t CParcelGetReadableBytes(const CParcel *parcel);
uint32_t CParcelGetReadPosition(const CParcel *parcel);
uint32_t CParcelGetWritePosition(const CParcel *parcel);
bool CParcelRewindRead(CParcel *parcel, uint32_t new_pos);
bool CParcelRewindWrite(CParcel *parcel, uint32_t new_pos);
#ifdef __cplusplus
}
......
......@@ -20,12 +20,19 @@
extern "C" {
#endif
#include <stdint.h>
#include "c_remote_object.h"
CRemoteObject *GetContextManager(void);
void JoinWorkThread(void);
void StopWorkThread(void);
void InitTokenId(void);
uint64_t GetCallingTokenId(void);
uint64_t GetFirstToekenId(void);
uint64_t GetSelfToekenId(void);
uint64_t GetCallingPid(void);
uint64_t GetCallingUid(void);
#ifdef __cplusplus
}
......
......@@ -44,7 +44,7 @@ void RemoteObjectIncStrongRef(CRemoteObject *object);
void RemoteObjectDecStrongRef(CRemoteObject *object);
const void *RemoteObjectGetUserData(CRemoteObject *object);
bool RemoteObjectLessThan(const CRemoteObject *lhs, const CRemoteObject *rhs);
int RemoteObjectSendRequest(const CRemoteObject *object, uint32_t code,
const CParcel *data, CParcel *reply, bool isAsync);
......
......@@ -15,6 +15,7 @@
#include "c_parcel_internal.h"
#include <securec.h>
#include <string_ex.h>
#include "c_remote_object_internal.h"
......@@ -218,14 +219,21 @@ bool CParcelReadString(const CParcel *parcel, void *stringData, OnCParcelBytesAl
if (!IsValidParcel(parcel, __func__) || allocator == nullptr) {
return false;
}
std::string value = parcel->parcel_->ReadString();
std::string value;
if (!parcel->parcel_->ReadString(value)) {
printf("%s: read string from parcel failed\n", __func__);
return false;
}
char *buffer = nullptr;
bool isSuccess = allocator(stringData, &buffer, value.length());
if (!isSuccess) {
printf("%s: allocate string buffer is null\n", __func__);
return false;
}
memcpy(buffer, value.data(), value.length());
if (value.length() > 0 && memcpy_s(buffer, value.length(), value.data(), value.length()) != EOK) {
printf("%s: memcpy string failed\n", __func__);
return false;
}
return true;
}
......@@ -259,9 +267,13 @@ bool CParcelReadString16(const CParcel *parcel, void *stringData, OnCParcelBytes
if (!IsValidParcel(parcel, __func__) || allocator == nullptr) {
return false;
}
std::u16string u16string = parcel->parcel_->ReadString16();
std::u16string u16string;
if (!parcel->parcel_->ReadString16(u16string)) {
printf("%s: read u16string from parcel failed\n", __func__);
return false;
}
std::string value = Str16ToStr8(u16string);
if (u16string.length() <= 0 || value.length() <= 0) {
if (u16string.length() != 0 && value.length() == 0) {
printf("%s: u16string len: %u, string len: %u\n", __func__, u16string.length(), value.length());
return false;
}
......@@ -271,7 +283,10 @@ bool CParcelReadString16(const CParcel *parcel, void *stringData, OnCParcelBytes
printf("%s: allocate string buffer is null\n", __func__);
return false;
}
memcpy(buffer, value.data(), value.length());
if (value.length() > 0 && memcpy_s(buffer, value.length(), value.data(), value.length()) != EOK) {
printf("%s: memcpy string16 failed\n", __func__);
return false;
}
return true;
}
......@@ -280,12 +295,12 @@ bool CParcelWriteInterfaceToken(CParcel *parcel, const char *token, int32_t toke
if (!IsValidParcel(parcel, __func__)) {
return false;
}
if (token == nullptr || tokenLen <= 0) {
if (token == nullptr || tokenLen < 0) {
printf("%s: token len is invalid: %d\n", __func__, tokenLen);
return false;
}
std::u16string u16string = Str8ToStr16(std::string(token, tokenLen));
if (u16string.length() == 0) {
if (u16string.length() == 0 && tokenLen != 0) {
printf("%s: convert token to u16string failed: %d\n", __func__, tokenLen);
return false;
}
......@@ -299,7 +314,7 @@ bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelByte
}
std::u16string u16string = parcel->parcel_->ReadInterfaceToken();
std::string value = Str16ToStr8(u16string);
if (u16string.length() <= 0 || value.length() <= 0) {
if (u16string.length() != 0 && value.length() == 0) {
printf("%s: u16string len: %u, string len: %u\n", __func__, u16string.length(), value.length());
return false;
}
......@@ -310,7 +325,10 @@ bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelByte
printf("%s: allocate interface token buffer failed\n", __func__);
return false;
}
memcpy(buffer, value.data(), value.length());
if (value.length() > 0 && memcpy_s(buffer, value.length(), value.data(), value.length()) != EOK) {
printf("%s: memcpy interface token failed\n", __func__);
return false;
}
return true;
}
......@@ -346,3 +364,120 @@ CRemoteObject *CParcelReadRemoteObject(const CParcel *parcel)
holder->IncStrongRef(nullptr);
return holder;
}
bool CParcelWriteFileDescriptor(CParcel *parcel, int32_t fd)
{
if (!IsValidParcel(parcel, __func__)) {
return false;
}
return parcel->parcel_->WriteFileDescriptor(fd);
}
bool CParcelReadFileDescriptor(const CParcel *parcel, int32_t *fd)
{
if (!IsValidParcel(parcel, __func__)) {
return false;
}
if (fd == nullptr) {
printf("%s: fd is null\n", __func__);
return false;
}
*fd = parcel->parcel_->ReadFileDescriptor();
return (*fd < 0) ? false : true;
}
uint32_t CParcelGetDataSize(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetDataSize();
}
bool CParcelSetDataSize(CParcel *parcel, uint32_t new_size)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->SetDataSize(new_size);
}
uint32_t CParcelGetDataCapacity(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetDataCapacity();
}
bool CParcelSetDataCapacity(CParcel *parcel, uint32_t new_size)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->SetDataCapacity(new_size);
}
uint32_t CParcelGetMaxCapacity(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetMaxCapacity();
}
bool CParcelSetMaxCapacity(CParcel *parcel, uint32_t new_size)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->SetMaxCapacity(new_size);
}
uint32_t CParcelGetWritableBytes(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetWritableBytes();
}
uint32_t CParcelGetReadableBytes(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetReadableBytes();
}
uint32_t CParcelGetReadPosition(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetReadPosition();
}
uint32_t CParcelGetWritePosition(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->GetWritePosition();
}
bool CParcelRewindRead(CParcel *parcel, uint32_t new_pos)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->RewindRead(new_pos);
}
bool CParcelRewindWrite(CParcel *parcel, uint32_t new_pos)
{
if (!IsValidParcel(parcel, __func__)) {
return 0;
}
return parcel->parcel_->RewindWrite(new_pos);
}
......@@ -43,6 +43,11 @@ void JoinWorkThread(void)
IPCSkeleton::JoinWorkThread();
}
void StopWorkThread(void)
{
IPCSkeleton::StopWorkThread();
}
void InitTokenId(void)
{
uint64_t tokenId;
......@@ -59,3 +64,28 @@ void InitTokenId(void)
tokenId = GetAccessTokenId(&infoInstance);
SetSelfTokenID(tokenId);
}
uint64_t GetCallingTokenId(void)
{
return IPCSkeleton::GetCallingFullTokenID();
}
uint64_t GetFirstToekenId(void)
{
return IPCSkeleton::GetFirstFullTokenID();
}
uint64_t GetSelfToekenId(void)
{
return IPCSkeleton::GetSelfTokenID();
}
uint64_t GetCallingPid(void)
{
return static_cast<uint64_t>(IPCSkeleton::GetCallingPid());
}
uint64_t GetCallingUid(void)
{
return static_cast<uint64_t>(IPCSkeleton::GetCallingUid());
}
\ No newline at end of file
......@@ -152,6 +152,14 @@ const void *RemoteObjectGetUserData(CRemoteObject *object)
return object->GetUserData();
}
bool RemoteObjectLessThan(const CRemoteObject *lhs, const CRemoteObject *rhs)
{
if (!IsValidRemoteObject(lhs, __func__) || !IsValidRemoteObject(rhs, __func__)) {
return false;
}
return lhs->remote_.GetRefPtr() < rhs->remote_.GetRefPtr();
}
int RemoteObjectSendRequest(const CRemoteObject *object, uint32_t code,
const CParcel *data, CParcel *reply, bool isAsync)
{
......
......@@ -376,7 +376,7 @@ bool IPCObjectProxy::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
#endif
return status && dbinderStatus;
}
return false;
return recipientErased;
}
void IPCObjectProxy::SendObituary()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册