Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
communication_ipc
提交
268e9ce6
C
communication_ipc
项目概览
OpenHarmony
/
communication_ipc
大约 1 年 前同步成功
通知
20
Star
3
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
communication_ipc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
268e9ce6
编写于
12月 29, 2022
作者:
F
fanxiaoyu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Adjust rust ipc implements.
Signed-off-by:
N
fanxiaoyu
<
fanxiaoyu3@huawei.com
>
上级
fa0668cf
变更
46
显示空白变更内容
内联
并排
Showing
46 changed file
with
2285 addition
and
153 deletion
+2285
-153
BUILD.gn
BUILD.gn
+3
-0
interfaces/innerkits/rust/BUILD.gn
interfaces/innerkits/rust/BUILD.gn
+3
-10
interfaces/innerkits/rust/src/errors.rs
interfaces/innerkits/rust/src/errors.rs
+1
-0
interfaces/innerkits/rust/src/ipc/macros.rs
interfaces/innerkits/rust/src/ipc/macros.rs
+11
-3
interfaces/innerkits/rust/src/ipc/mod.rs
interfaces/innerkits/rust/src/ipc/mod.rs
+14
-8
interfaces/innerkits/rust/src/ipc/remote_obj.rs
interfaces/innerkits/rust/src/ipc/remote_obj.rs
+5
-3
interfaces/innerkits/rust/src/ipc/remote_obj/death_recipient.rs
...aces/innerkits/rust/src/ipc/remote_obj/death_recipient.rs
+3
-1
interfaces/innerkits/rust/src/ipc/remote_stub.rs
interfaces/innerkits/rust/src/ipc/remote_stub.rs
+2
-2
interfaces/innerkits/rust/src/ipc_binding.rs
interfaces/innerkits/rust/src/ipc_binding.rs
+2
-4
interfaces/innerkits/rust/src/lib.rs
interfaces/innerkits/rust/src/lib.rs
+11
-7
interfaces/innerkits/rust/src/parcel/mod.rs
interfaces/innerkits/rust/src/parcel/mod.rs
+55
-2
interfaces/innerkits/rust/src/parcel/parcelable.rs
interfaces/innerkits/rust/src/parcel/parcelable.rs
+135
-17
interfaces/innerkits/rust/src/parcel/types.rs
interfaces/innerkits/rust/src/parcel/types.rs
+7
-1
interfaces/innerkits/rust/src/parcel/types/bool.rs
interfaces/innerkits/rust/src/parcel/types/bool.rs
+0
-1
interfaces/innerkits/rust/src/parcel/types/boxt.rs
interfaces/innerkits/rust/src/parcel/types/boxt.rs
+40
-0
interfaces/innerkits/rust/src/parcel/types/const_array.rs
interfaces/innerkits/rust/src/parcel/types/const_array.rs
+49
-0
interfaces/innerkits/rust/src/parcel/types/file_desc.rs
interfaces/innerkits/rust/src/parcel/types/file_desc.rs
+2
-1
interfaces/innerkits/rust/src/parcel/types/integer.rs
interfaces/innerkits/rust/src/parcel/types/integer.rs
+386
-1
interfaces/innerkits/rust/src/parcel/types/interface_token.rs
...rfaces/innerkits/rust/src/parcel/types/interface_token.rs
+3
-1
interfaces/innerkits/rust/src/parcel/types/option.rs
interfaces/innerkits/rust/src/parcel/types/option.rs
+5
-3
interfaces/innerkits/rust/src/parcel/types/slices.rs
interfaces/innerkits/rust/src/parcel/types/slices.rs
+19
-1
interfaces/innerkits/rust/src/parcel/types/string16.rs
interfaces/innerkits/rust/src/parcel/types/string16.rs
+3
-1
interfaces/innerkits/rust/src/parcel/types/strings.rs
interfaces/innerkits/rust/src/parcel/types/strings.rs
+0
-1
interfaces/innerkits/rust/src/parcel/types/vector.rs
interfaces/innerkits/rust/src/parcel/types/vector.rs
+26
-1
interfaces/innerkits/rust/src/process.rs
interfaces/innerkits/rust/src/process.rs
+21
-19
ipc/native/src/c_wrapper/include/c_parcel.h
ipc/native/src/c_wrapper/include/c_parcel.h
+2
-0
ipc/native/src/c_wrapper/include/c_process.h
ipc/native/src/c_wrapper/include/c_process.h
+0
-1
ipc/native/src/c_wrapper/source/c_parcel.cpp
ipc/native/src/c_wrapper/source/c_parcel.cpp
+31
-2
ipc/native/src/c_wrapper/source/c_process.cpp
ipc/native/src/c_wrapper/source/c_process.cpp
+0
-19
ipc/native/src/c_wrapper/source/c_remote_object.cpp
ipc/native/src/c_wrapper/source/c_remote_object.cpp
+2
-2
ipc/native/test/BUILD.gn
ipc/native/test/BUILD.gn
+3
-0
ipc/native/test/unittest/common/BUILD.gn
ipc/native/test/unittest/common/BUILD.gn
+39
-0
ipc/native/test/unittest/common/ipc_c_message_parcel_unittest.cpp
...ve/test/unittest/common/ipc_c_message_parcel_unittest.cpp
+460
-0
ipc/native/test/unittest/common/ipc_c_process_unittest.cpp
ipc/native/test/unittest/common/ipc_c_process_unittest.cpp
+75
-0
ipc/native/test/unittest/common/ipc_c_remote_object_unittest.cpp
...ive/test/unittest/common/ipc_c_remote_object_unittest.cpp
+238
-0
ipc/native/test/unittest/rust/BUILD.gn
ipc/native/test/unittest/rust/BUILD.gn
+25
-0
ipc/native/test/unittest/rust/client/BUILD.gn
ipc/native/test/unittest/rust/client/BUILD.gn
+9
-4
ipc/native/test/unittest/rust/client/src/main.rs
ipc/native/test/unittest/rust/client/src/main.rs
+83
-30
ipc/native/test/unittest/rust/server/BUILD.gn
ipc/native/test/unittest/rust/server/BUILD.gn
+2
-2
ipc/native/test/unittest/rust/server/src/main.rs
ipc/native/test/unittest/rust/server/src/main.rs
+112
-0
ipc/native/test/unittest/rust/service/BUILD.gn
ipc/native/test/unittest/rust/service/BUILD.gn
+9
-2
ipc/native/test/unittest/rust/service/src/access_token.rs
ipc/native/test/unittest/rust/service/src/access_token.rs
+56
-0
ipc/native/test/unittest/rust/service/src/lib.rs
ipc/native/test/unittest/rust/service/src/lib.rs
+278
-0
ipc/test/auxiliary/native/BUILD.gn
ipc/test/auxiliary/native/BUILD.gn
+15
-3
ipc/test/auxiliary/native/src/main_client.cpp
ipc/test/auxiliary/native/src/main_client.cpp
+20
-0
ipc/test/auxiliary/native/src/main_server.cpp
ipc/test/auxiliary/native/src/main_server.cpp
+20
-0
未找到文件。
BUILD.gn
浏览文件 @
268e9ce6
...
@@ -47,6 +47,9 @@ group("ipc_components") {
...
@@ -47,6 +47,9 @@ group("ipc_components") {
"//foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder",
"//foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder",
"//foundation/communication/ipc/ipc/native/src/core:ipc_common",
"//foundation/communication/ipc/ipc/native/src/core:ipc_common",
]
]
if (target_cpu == "arm64") {
deps += [ "//foundation/communication/ipc/interfaces/innerkits/rust:rust_ipc_component" ]
}
} else {
} else {
deps = [ "//foundation/communication/ipc/interfaces/innerkits/c:rpc" ]
deps = [ "//foundation/communication/ipc/interfaces/innerkits/c:rpc" ]
}
}
...
...
interfaces/innerkits/rust/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -27,6 +27,7 @@ ohos_rust_shared_library("ipc_rust") {
...
@@ -27,6 +27,7 @@ ohos_rust_shared_library("ipc_rust") {
"src/lib.rs",
"src/lib.rs",
"src/parcel/mod.rs",
"src/parcel/mod.rs",
"src/parcel/parcelable.rs",
"src/parcel/parcelable.rs",
"src/parcel/types.rs",
]
]
deps = [ ":ipc_c" ]
deps = [ ":ipc_c" ]
...
@@ -54,11 +55,7 @@ ohos_shared_library("ipc_c") {
...
@@ -54,11 +55,7 @@ ohos_shared_library("ipc_c") {
configs = [ ":libipc_c_private_config" ]
configs = [ ":libipc_c_private_config" ]
deps = [
deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/ipc_single:ipc_single" ]
"$SUBSYSTEM_DIR/interfaces/innerkits/ipc_single:ipc_single",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
]
external_deps = [
external_deps = [
"c_utils:utils",
"c_utils:utils",
...
@@ -73,9 +70,5 @@ ohos_shared_library("ipc_c") {
...
@@ -73,9 +70,5 @@ ohos_shared_library("ipc_c") {
}
}
group("rust_ipc_component") {
group("rust_ipc_component") {
deps = [
deps = [ ":ipc_rust" ]
":ipc_rust",
"$SUBSYSTEM_DIR/interfaces/innerkits/rust/tests/client:rust_ipc_test_client",
"$SUBSYSTEM_DIR/interfaces/innerkits/rust/tests/server:rust_ipc_test_server",
]
}
}
interfaces/innerkits/rust/src/errors.rs
浏览文件 @
268e9ce6
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
/// IPC specific Result, error is i32 type
/// IPC specific Result, error is i32 type
pub
type
Result
<
T
>
=
std
::
result
::
Result
<
T
,
i32
>
;
pub
type
Result
<
T
>
=
std
::
result
::
Result
<
T
,
i32
>
;
/// Generate a rust ipc Result by ret and val arguments.
pub
fn
result_status
<
T
>
(
ret
:
bool
,
val
:
T
)
->
Result
<
T
>
{
pub
fn
result_status
<
T
>
(
ret
:
bool
,
val
:
T
)
->
Result
<
T
>
{
if
ret
{
if
ret
{
Ok
(
val
)
Ok
(
val
)
...
...
interfaces/innerkits/rust/src/ipc/macros.rs
浏览文件 @
268e9ce6
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
* limitations under the License.
* limitations under the License.
*/
*/
/// This macro can define a rust IPC proxy and stub releations.
#[macro_export]
#[macro_export]
macro_rules!
define_remote_object
{
macro_rules!
define_remote_object
{
{
{
...
@@ -37,28 +38,33 @@ macro_rules! define_remote_object {
...
@@ -37,28 +38,33 @@ macro_rules! define_remote_object {
},
},
}
}
}
=>
{
}
=>
{
/// IPC proxy type
pub
struct
$proxy
{
pub
struct
$proxy
{
remote
:
$crate
::
RemoteObj
,
remote
:
$crate
::
RemoteObj
,
$
(
$item_name
:
$item_type
,)
*
$
(
$item_name
:
$item_type
,)
*
}
}
impl
$proxy
{
impl
$proxy
{
/// Create proxy object by RemoteObj
fn
from_remote_object
(
remote
:
RemoteObj
)
->
$crate
::
Result
<
Self
>
{
fn
from_remote_object
(
remote
:
RemoteObj
)
->
$crate
::
Result
<
Self
>
{
Ok
(
Self
{
remote
,
$
(
$item_name
:
$item_init
),
*
})
Ok
(
Self
{
remote
,
$
(
$item_name
:
$item_init
),
*
})
}
}
/// Get proxy object descriptor
#[allow(dead_code)]
#[allow(dead_code)]
fn
get_descriptor
()
->
&
'static
str
{
pub
fn
get_descriptor
()
->
&
'static
str
{
$descriptor
$descriptor
}
}
}
}
impl
$crate
::
IRemoteBroker
for
$proxy
{
impl
$crate
::
IRemoteBroker
for
$proxy
{
/// Get RemoteObje object from proxy
fn
as_object
(
&
self
)
->
Option
<
$crate
::
RemoteObj
>
{
fn
as_object
(
&
self
)
->
Option
<
$crate
::
RemoteObj
>
{
Some
(
self
.remote
.clone
())
Some
(
self
.remote
.clone
())
}
}
}
}
/// IPC stub type
pub
struct
$stub
(
Box
<
dyn
$remote_broker
+
Sync
+
Send
>
);
pub
struct
$stub
(
Box
<
dyn
$remote_broker
+
Sync
+
Send
>
);
impl
$stub
{
impl
$stub
{
...
@@ -70,10 +76,12 @@ macro_rules! define_remote_object {
...
@@ -70,10 +76,12 @@ macro_rules! define_remote_object {
}
}
impl
$crate
::
IRemoteStub
for
$stub
{
impl
$crate
::
IRemoteStub
for
$stub
{
/// Get stub object descriptor
fn
get_descriptor
()
->
&
'static
str
{
fn
get_descriptor
()
->
&
'static
str
{
$descriptor
$descriptor
}
}
/// Callback to deal IPC request for this stub
fn
on_remote_request
(
&
self
,
code
:
u32
,
data
:
&
$crate
::
BorrowedMsgParcel
,
fn
on_remote_request
(
&
self
,
code
:
u32
,
data
:
&
$crate
::
BorrowedMsgParcel
,
reply
:
&
mut
$crate
::
BorrowedMsgParcel
)
->
i32
{
reply
:
&
mut
$crate
::
BorrowedMsgParcel
)
->
i32
{
// For example, "self.0" is "Box<dyn ITest>", "*self.0" is "dyn ITest"
// For example, "self.0" is "Box<dyn ITest>", "*self.0" is "dyn ITest"
...
@@ -90,7 +98,7 @@ macro_rules! define_remote_object {
...
@@ -90,7 +98,7 @@ macro_rules! define_remote_object {
}
}
impl
$crate
::
FromRemoteObj
for
dyn
$remote_broker
{
impl
$crate
::
FromRemoteObj
for
dyn
$remote_broker
{
// For example, convert RemoteObj to RemoteObjRef<dyn ITest>
//
/
For example, convert RemoteObj to RemoteObjRef<dyn ITest>
fn
from
(
object
:
$crate
::
RemoteObj
)
->
$crate
::
Result
<
$crate
::
RemoteObjRef
<
dyn
$remote_broker
>>
{
fn
from
(
object
:
$crate
::
RemoteObj
)
->
$crate
::
Result
<
$crate
::
RemoteObjRef
<
dyn
$remote_broker
>>
{
Ok
(
$crate
::
RemoteObjRef
::
new
(
Box
::
new
(
$proxy
::
from_remote_object
(
object
)
?
)))
Ok
(
$crate
::
RemoteObjRef
::
new
(
Box
::
new
(
$proxy
::
from_remote_object
(
object
)
?
)))
}
}
...
...
interfaces/innerkits/rust/src/ipc/mod.rs
浏览文件 @
268e9ce6
...
@@ -26,39 +26,45 @@ pub use crate::RemoteObj;
...
@@ -26,39 +26,45 @@ pub use crate::RemoteObj;
/// Like C++ IRemoteObject class, define function for both proxy and stub object
/// Like C++ IRemoteObject class, define function for both proxy and stub object
pub
trait
IRemoteObj
{
pub
trait
IRemoteObj
{
//
IPC request
//
/ Send a IPC request to remote service
fn
send_request
(
&
self
,
code
:
u32
,
data
:
&
MsgParcel
,
is_async
:
bool
)
->
Result
<
MsgParcel
>
;
fn
send_request
(
&
self
,
code
:
u32
,
data
:
&
MsgParcel
,
is_async
:
bool
)
->
Result
<
MsgParcel
>
;
//
Death R
ecipient
//
/ Add a death r
ecipient
fn
add_death_recipient
(
&
self
,
recipient
:
&
mut
DeathRecipient
)
->
bool
;
fn
add_death_recipient
(
&
self
,
recipient
:
&
mut
DeathRecipient
)
->
bool
;
/// Remove a death recipient
fn
remove_death_recipient
(
&
self
,
recipient
:
&
mut
DeathRecipient
)
->
bool
;
fn
remove_death_recipient
(
&
self
,
recipient
:
&
mut
DeathRecipient
)
->
bool
;
}
}
// Like C++ IPCObjectStub class, define function for stub object only, like on_remote_request().
//
/
Like C++ IPCObjectStub class, define function for stub object only, like on_remote_request().
pub
trait
IRemoteStub
:
Send
+
Sync
{
pub
trait
IRemoteStub
:
Send
+
Sync
{
/// Get object descriptor of this stub
fn
get_descriptor
()
->
&
'static
str
;
fn
get_descriptor
()
->
&
'static
str
;
/// Callback for deal IPC request
fn
on_remote_request
(
&
self
,
code
:
u32
,
data
:
&
BorrowedMsgParcel
,
reply
:
&
mut
BorrowedMsgParcel
)
->
i32
;
fn
on_remote_request
(
&
self
,
code
:
u32
,
data
:
&
BorrowedMsgParcel
,
reply
:
&
mut
BorrowedMsgParcel
)
->
i32
;
}
}
// Like C++ IRemoteBroker class
//
/
Like C++ IRemoteBroker class
pub
trait
IRemoteBroker
:
Send
+
Sync
{
pub
trait
IRemoteBroker
:
Send
+
Sync
{
// Convert self to RemoteObject
//
/
Convert self to RemoteObject
fn
as_object
(
&
self
)
->
Option
<
RemoteObj
>
{
fn
as_object
(
&
self
)
->
Option
<
RemoteObj
>
{
panic!
(
"This is not a RemoteObject."
)
panic!
(
"This is not a RemoteObject."
)
}
}
}
}
// Define function which how to convert a RemoteObj to RemoteObjRef, the later contains a
//
/
Define function which how to convert a RemoteObj to RemoteObjRef, the later contains a
// dynamic trait object: IRemoteObject. For example, "dyn ITest" should implements this trait
//
/
dynamic trait object: IRemoteObject. For example, "dyn ITest" should implements this trait
pub
trait
FromRemoteObj
:
IRemoteBroker
{
pub
trait
FromRemoteObj
:
IRemoteBroker
{
/// Convert a RemoteObj to RemoteObjeRef
fn
from
(
object
:
RemoteObj
)
->
Result
<
RemoteObjRef
<
Self
>>
;
fn
from
(
object
:
RemoteObj
)
->
Result
<
RemoteObjRef
<
Self
>>
;
}
}
// Strong reference for "dyn IRemoteBroker" object, for example T is "dyn ITest"
//
/
Strong reference for "dyn IRemoteBroker" object, for example T is "dyn ITest"
pub
struct
RemoteObjRef
<
T
:
FromRemoteObj
+
?
Sized
>
(
Box
<
T
>
);
pub
struct
RemoteObjRef
<
T
:
FromRemoteObj
+
?
Sized
>
(
Box
<
T
>
);
impl
<
T
:
FromRemoteObj
+
?
Sized
>
RemoteObjRef
<
T
>
{
impl
<
T
:
FromRemoteObj
+
?
Sized
>
RemoteObjRef
<
T
>
{
/// Create a RemoteObjRef object
pub
fn
new
(
object
:
Box
<
T
>
)
->
Self
{
pub
fn
new
(
object
:
Box
<
T
>
)
->
Self
{
Self
(
object
)
Self
(
object
)
}
}
...
...
interfaces/innerkits/rust/src/ipc/remote_obj.rs
浏览文件 @
268e9ce6
...
@@ -13,6 +13,8 @@
...
@@ -13,6 +13,8 @@
* limitations under the License.
* limitations under the License.
*/
*/
//! Implement of RemoteObj type, which represent a C++ IRemoteObject.
use
std
::
ptr
;
use
std
::
ptr
;
use
crate
::{
use
crate
::{
ipc_binding
,
IRemoteObj
,
DeathRecipient
,
Result
,
ipc_binding
,
IRemoteObj
,
DeathRecipient
,
Result
,
...
@@ -34,6 +36,7 @@ pub struct RemoteObj(ptr::NonNull<CRemoteObject>);
...
@@ -34,6 +36,7 @@ pub struct RemoteObj(ptr::NonNull<CRemoteObject>);
impl
RemoteObj
{
impl
RemoteObj
{
/// Create an `RemoteObj` wrapper object from a raw `CRemoteObject` pointer.
/// Create an `RemoteObj` wrapper object from a raw `CRemoteObject` pointer.
/// # Safety
pub
unsafe
fn
from_raw
(
obj
:
*
mut
CRemoteObject
)
->
Option
<
RemoteObj
>
{
pub
unsafe
fn
from_raw
(
obj
:
*
mut
CRemoteObject
)
->
Option
<
RemoteObj
>
{
if
obj
.is_null
()
{
if
obj
.is_null
()
{
None
None
...
@@ -44,7 +47,6 @@ impl RemoteObj {
...
@@ -44,7 +47,6 @@ impl RemoteObj {
/// Extract a raw `CRemoteObject` pointer from this wrapper.
/// Extract a raw `CRemoteObject` pointer from this wrapper.
/// # Safety
/// # Safety
/// TODO
pub
unsafe
fn
as_inner
(
&
self
)
->
*
mut
CRemoteObject
{
pub
unsafe
fn
as_inner
(
&
self
)
->
*
mut
CRemoteObject
{
self
.0
.as_ptr
()
self
.0
.as_ptr
()
}
}
...
@@ -52,7 +54,7 @@ impl RemoteObj {
...
@@ -52,7 +54,7 @@ impl RemoteObj {
impl
IRemoteObj
for
RemoteObj
{
impl
IRemoteObj
for
RemoteObj
{
fn
send_request
(
&
self
,
code
:
u32
,
data
:
&
MsgParcel
,
is_async
:
bool
)
->
Result
<
MsgParcel
>
{
fn
send_request
(
&
self
,
code
:
u32
,
data
:
&
MsgParcel
,
is_async
:
bool
)
->
Result
<
MsgParcel
>
{
// SAFETY:
TODO
// SAFETY:
unsafe
{
unsafe
{
let
mut
reply
=
MsgParcel
::
new
()
.expect
(
"create reply MsgParcel not success"
);
let
mut
reply
=
MsgParcel
::
new
()
.expect
(
"create reply MsgParcel not success"
);
let
result
=
ipc_binding
::
RemoteObjectSendRequest
(
self
.as_inner
(),
code
,
data
.as_raw
(),
let
result
=
ipc_binding
::
RemoteObjectSendRequest
(
self
.as_inner
(),
code
,
data
.as_raw
(),
...
@@ -85,7 +87,7 @@ impl Serialize for RemoteObj {
...
@@ -85,7 +87,7 @@ impl Serialize for RemoteObj {
let
ret
=
unsafe
{
let
ret
=
unsafe
{
ipc_binding
::
CParcelWriteRemoteObject
(
parcel
.as_mut_raw
(),
self
.as_inner
())
ipc_binding
::
CParcelWriteRemoteObject
(
parcel
.as_mut_raw
(),
self
.as_inner
())
};
};
if
ret
==
true
{
if
ret
{
Ok
(())
Ok
(())
}
else
{
}
else
{
Err
(
-
1
)
Err
(
-
1
)
...
...
interfaces/innerkits/rust/src/ipc/remote_obj/death_recipient.rs
浏览文件 @
268e9ce6
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
use
super
::
*
;
use
super
::
*
;
/// This type represent a rust DeathRecipient which like C++ DethRecipient.
#[repr(C)]
#[repr(C)]
pub
struct
DeathRecipient
{
pub
struct
DeathRecipient
{
native
:
*
mut
CDeathRecipient
,
native
:
*
mut
CDeathRecipient
,
...
@@ -22,6 +23,7 @@ pub struct DeathRecipient {
...
@@ -22,6 +23,7 @@ pub struct DeathRecipient {
}
}
impl
DeathRecipient
{
impl
DeathRecipient
{
/// Create a rust DeathRecipient object with a death recipient callback.
pub
fn
new
<
F
>
(
callback
:
F
)
->
Option
<
DeathRecipient
>
pub
fn
new
<
F
>
(
callback
:
F
)
->
Option
<
DeathRecipient
>
where
where
F
:
Fn
()
+
Send
+
Sync
+
'static
,
F
:
Fn
()
+
Send
+
Sync
+
'static
,
...
@@ -69,7 +71,7 @@ impl DeathRecipient {
...
@@ -69,7 +71,7 @@ impl DeathRecipient {
{
{
if
!
callback
.is_null
()
{
if
!
callback
.is_null
()
{
println!
(
"death recipient on destroy"
);
println!
(
"death recipient on destroy"
);
Box
::
from_raw
(
callback
as
*
mut
F
);
drop
(
Box
::
from_raw
(
callback
as
*
mut
F
)
);
}
}
}
}
}
}
...
...
interfaces/innerkits/rust/src/ipc/remote_stub.rs
浏览文件 @
268e9ce6
...
@@ -27,7 +27,7 @@ pub struct RemoteStub<T: IRemoteStub> {
...
@@ -27,7 +27,7 @@ pub struct RemoteStub<T: IRemoteStub> {
}
}
impl
<
T
:
IRemoteStub
>
RemoteStub
<
T
>
{
impl
<
T
:
IRemoteStub
>
RemoteStub
<
T
>
{
//
c
reate a RemoteStub object
//
/ C
reate a RemoteStub object
pub
fn
new
(
rust
:
T
)
->
Option
<
Self
>
{
pub
fn
new
(
rust
:
T
)
->
Option
<
Self
>
{
let
rust
=
Box
::
into_raw
(
Box
::
new
(
rust
));
let
rust
=
Box
::
into_raw
(
Box
::
new
(
rust
));
let
descripor
=
CString
::
new
(
T
::
get_descriptor
())
.expect
(
"descripor must be valid!"
);
let
descripor
=
CString
::
new
(
T
::
get_descriptor
())
.expect
(
"descripor must be valid!"
);
...
@@ -91,7 +91,7 @@ impl<T: IRemoteStub> RemoteStub<T> {
...
@@ -91,7 +91,7 @@ impl<T: IRemoteStub> RemoteStub<T> {
let
rust_object
:
&
T
=
&*
(
object
as
*
const
T
);
let
rust_object
:
&
T
=
&*
(
object
as
*
const
T
);
rust_object
.on_remote_request
(
code
,
&
data
,
&
mut
reply
)
rust_object
.on_remote_request
(
code
,
&
data
,
&
mut
reply
)
};
};
re
turn
res
;
re
s
}
}
unsafe
extern
"C"
fn
on_destroy
(
user_data
:
*
mut
c_void
)
{
unsafe
extern
"C"
fn
on_destroy
(
user_data
:
*
mut
c_void
)
{
...
...
interfaces/innerkits/rust/src/ipc_binding.rs
浏览文件 @
268e9ce6
...
@@ -81,7 +81,6 @@ extern "C" {
...
@@ -81,7 +81,6 @@ extern "C" {
pub
fn
CreateDeathRecipient
(
onDeathRecipient
:
OnDeathRecipientCb
,
onDestroy
:
OnDeathRecipientDestroyCb
,
pub
fn
CreateDeathRecipient
(
onDeathRecipient
:
OnDeathRecipientCb
,
onDestroy
:
OnDeathRecipientDestroyCb
,
userData
:
*
const
c_void
)
->
*
mut
CDeathRecipient
;
userData
:
*
const
c_void
)
->
*
mut
CDeathRecipient
;
pub
fn
DeathRecipientIncStrongRef
(
recipient
:
*
mut
CDeathRecipient
);
pub
fn
DeathRecipientDecStrongRef
(
recipient
:
*
mut
CDeathRecipient
);
pub
fn
DeathRecipientDecStrongRef
(
recipient
:
*
mut
CDeathRecipient
);
pub
fn
AddDeathRecipient
(
object
:
*
mut
CRemoteObject
,
recipient
:
*
mut
CDeathRecipient
)
->
bool
;
pub
fn
AddDeathRecipient
(
object
:
*
mut
CRemoteObject
,
recipient
:
*
mut
CDeathRecipient
)
->
bool
;
pub
fn
RemoveDeathRecipient
(
object
:
*
mut
CRemoteObject
,
recipient
:
*
mut
CDeathRecipient
)
->
bool
;
pub
fn
RemoveDeathRecipient
(
object
:
*
mut
CRemoteObject
,
recipient
:
*
mut
CDeathRecipient
)
->
bool
;
...
@@ -114,8 +113,8 @@ extern "C" {
...
@@ -114,8 +113,8 @@ extern "C" {
allocator
:
OnCParcelBytesAllocator
)
->
bool
;
allocator
:
OnCParcelBytesAllocator
)
->
bool
;
pub
fn
CParcelWriteRemoteObject
(
parcel
:
*
mut
CParcel
,
object
:
*
mut
CRemoteObject
)
->
bool
;
pub
fn
CParcelWriteRemoteObject
(
parcel
:
*
mut
CParcel
,
object
:
*
mut
CRemoteObject
)
->
bool
;
pub
fn
CParcelReadRemoteObject
(
parcel
:
*
const
CParcel
)
->
*
mut
CRemoteObject
;
pub
fn
CParcelReadRemoteObject
(
parcel
:
*
const
CParcel
)
->
*
mut
CRemoteObject
;
pub
fn
CParcelWriteBuffer
(
parcel
:
*
mut
CParcel
,
value
:
*
const
c_void
,
len
:
i
32
)
->
bool
;
pub
fn
CParcelWriteBuffer
(
parcel
:
*
mut
CParcel
,
value
:
*
const
u8
,
len
:
u
32
)
->
bool
;
pub
fn
CParcelReadBuffer
(
parcel
:
*
const
CParcel
,
value
:
*
mut
c_void
,
allocator
:
OnCParcelBytesAllocator
)
->
bool
;
pub
fn
CParcelReadBuffer
(
parcel
:
*
const
CParcel
,
value
:
*
mut
u8
,
len
:
u32
)
->
bool
;
pub
fn
CParcelWriteFileDescriptor
(
parcel
:
*
mut
CParcel
,
fd
:
i32
)
->
bool
;
pub
fn
CParcelWriteFileDescriptor
(
parcel
:
*
mut
CParcel
,
fd
:
i32
)
->
bool
;
pub
fn
CParcelReadFileDescriptor
(
parcel
:
*
const
CParcel
,
fd
:
*
mut
i32
)
->
bool
;
pub
fn
CParcelReadFileDescriptor
(
parcel
:
*
const
CParcel
,
fd
:
*
mut
i32
)
->
bool
;
pub
fn
CParcelGetDataSize
(
parcel
:
*
const
CParcel
)
->
u32
;
pub
fn
CParcelGetDataSize
(
parcel
:
*
const
CParcel
)
->
u32
;
...
@@ -134,7 +133,6 @@ extern "C" {
...
@@ -134,7 +133,6 @@ extern "C" {
pub
fn
GetContextManager
()
->
*
mut
CRemoteObject
;
pub
fn
GetContextManager
()
->
*
mut
CRemoteObject
;
pub
fn
JoinWorkThread
();
pub
fn
JoinWorkThread
();
pub
fn
StopWorkThread
();
pub
fn
StopWorkThread
();
pub
fn
InitTokenId
();
pub
fn
GetCallingTokenId
()
->
u64
;
pub
fn
GetCallingTokenId
()
->
u64
;
pub
fn
GetFirstToekenId
()
->
u64
;
pub
fn
GetFirstToekenId
()
->
u64
;
pub
fn
GetSelfToekenId
()
->
u64
;
pub
fn
GetSelfToekenId
()
->
u64
;
...
...
interfaces/innerkits/rust/src/lib.rs
浏览文件 @
268e9ce6
...
@@ -13,11 +13,13 @@
...
@@ -13,11 +13,13 @@
* limitations under the License.
* limitations under the License.
*/
*/
//! Safe Rust interface to OHOS IPC/RPC
mod
ipc_binding
;
mod
ipc_binding
;
pub
mod
errors
;
mod
errors
;
pub
mod
ipc
;
mod
ipc
;
pub
mod
parcel
;
mod
parcel
;
pub
mod
process
;
mod
process
;
// Export types of this crate
// Export types of this crate
pub
use
crate
::
errors
::{
Result
,
result_status
};
pub
use
crate
::
errors
::{
Result
,
result_status
};
...
@@ -26,17 +28,19 @@ pub use crate::ipc::{
...
@@ -26,17 +28,19 @@ pub use crate::ipc::{
remote_obj
::
RemoteObj
,
remote_obj
::
death_recipient
::
DeathRecipient
,
remote_stub
::
RemoteStub
,
remote_obj
::
RemoteObj
,
remote_obj
::
death_recipient
::
DeathRecipient
,
remote_stub
::
RemoteStub
,
};
};
pub
use
crate
::
parcel
::{
MsgParcel
,
BorrowedMsgParcel
,
IMsgParcel
,
pub
use
crate
::
parcel
::{
MsgParcel
,
BorrowedMsgParcel
,
IMsgParcel
,
parcelable
::{
Serialize
,
Deserialize
,
SerOption
,
De
SerOption
,
SerArray
,
DeArray
},
parcelable
::{
Serialize
,
Deserialize
,
SerOption
,
De
Option
},
};
};
// pub use crate::parcel::{SerArray, DeArray};
pub
use
crate
::
parcel
::
types
::{
pub
use
crate
::
parcel
::
types
::{
interface_token
::
InterfaceToken
,
file_desc
::
FileDesc
,
interface_token
::
InterfaceToken
,
file_desc
::
FileDesc
,
string16
::
String16
string16
::
String16
};
};
pub
use
crate
::
process
::{
pub
use
crate
::
process
::{
add_service
,
get_service
,
init_access_token
,
join_work_thread
,
stop_work_threa
d
,
add_service
,
get_service
,
join_work_thread
,
stop_work_thread
,
get_calling_ui
d
,
get_calling_token_id
,
get_first_token_id
,
get_self_token_id
,
get_calling_pid
,
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)
/// First request code available for user IPC request(inclusive)
...
...
interfaces/innerkits/rust/src/parcel/mod.rs
浏览文件 @
268e9ce6
...
@@ -19,86 +19,132 @@ pub mod types;
...
@@ -19,86 +19,132 @@ pub mod types;
use
crate
::{
ipc_binding
,
Result
};
use
crate
::{
ipc_binding
,
Result
};
use
crate
::
ipc_binding
::{
CParcel
};
use
crate
::
ipc_binding
::{
CParcel
};
use
std
::
marker
::
PhantomData
;
use
std
::
marker
::
PhantomData
;
use
std
::
mem
::
ManuallyDrop
;
use
std
::
mem
::
{
ManuallyDrop
,
MaybeUninit
}
;
use
std
::
ops
::{
Drop
};
use
std
::
ops
::{
Drop
};
use
std
::
ptr
::{
NonNull
};
use
std
::
ptr
::{
NonNull
};
use
crate
::
AsRawPtr
;
use
crate
::
AsRawPtr
;
use
crate
::
parcel
::
parcelable
::{
Serialize
,
Deserialize
};
use
crate
::
parcel
::
parcelable
::{
Serialize
,
Deserialize
};
/// This trait implements the common function for MsgParcel
/// This trait implements the common function for MsgParcel
/// and BorrowedMsgParcel
/// and BorrowedMsgParcel
pub
trait
IMsgParcel
:
AsRawPtr
<
CParcel
>
{
pub
trait
IMsgParcel
:
AsRawPtr
<
CParcel
>
{
/// Get current data size in parcel
fn
get_data_size
(
&
self
)
->
u32
{
fn
get_data_size
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetDataSize
(
self
.as_raw
())
ipc_binding
::
CParcelGetDataSize
(
self
.as_raw
())
}
}
}
}
/// Set current data size in parcel
fn
set_data_size
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
fn
set_data_size
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelSetDataSize
(
self
.as_mut_raw
(),
new_size
)
ipc_binding
::
CParcelSetDataSize
(
self
.as_mut_raw
(),
new_size
)
}
}
}
}
/// Get current data capacity in parcel
fn
get_data_capacity
(
&
self
)
->
u32
{
fn
get_data_capacity
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetDataCapacity
(
self
.as_raw
())
ipc_binding
::
CParcelGetDataCapacity
(
self
.as_raw
())
}
}
}
}
/// Set current data capacity in parcel
fn
set_data_capacity
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
fn
set_data_capacity
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelSetDataCapacity
(
self
.as_mut_raw
(),
new_size
)
ipc_binding
::
CParcelSetDataCapacity
(
self
.as_mut_raw
(),
new_size
)
}
}
}
}
/// Get maximum capacity in parcel
fn
get_max_capacity
(
&
self
)
->
u32
{
fn
get_max_capacity
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetMaxCapacity
(
self
.as_raw
())
ipc_binding
::
CParcelGetMaxCapacity
(
self
.as_raw
())
}
}
}
}
/// Set maximum capacity in parcel
fn
set_max_capacity
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
fn
set_max_capacity
(
&
mut
self
,
new_size
:
u32
)
->
bool
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelSetMaxCapacity
(
self
.as_mut_raw
(),
new_size
)
ipc_binding
::
CParcelSetMaxCapacity
(
self
.as_mut_raw
(),
new_size
)
}
}
}
}
/// Get current writalbe bytes in parcel
fn
get_writable_bytes
(
&
self
)
->
u32
{
fn
get_writable_bytes
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetWritableBytes
(
self
.as_raw
())
ipc_binding
::
CParcelGetWritableBytes
(
self
.as_raw
())
}
}
}
}
/// Get current readable bytes in parcel
fn
get_readable_bytes
(
&
self
)
->
u32
{
fn
get_readable_bytes
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetReadableBytes
(
self
.as_raw
())
ipc_binding
::
CParcelGetReadableBytes
(
self
.as_raw
())
}
}
}
}
/// Get current read position of parcel
fn
get_read_position
(
&
self
)
->
u32
{
fn
get_read_position
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetReadPosition
(
self
.as_raw
())
ipc_binding
::
CParcelGetReadPosition
(
self
.as_raw
())
}
}
}
}
/// Get current write position of parcel
fn
get_write_position
(
&
self
)
->
u32
{
fn
get_write_position
(
&
self
)
->
u32
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelGetWritePosition
(
self
.as_raw
())
ipc_binding
::
CParcelGetWritePosition
(
self
.as_raw
())
}
}
}
}
/// Rewind the read position to a new position of parcel
fn
rewind_read
(
&
mut
self
,
new_pos
:
u32
)
->
bool
{
fn
rewind_read
(
&
mut
self
,
new_pos
:
u32
)
->
bool
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelRewindRead
(
self
.as_mut_raw
(),
new_pos
)
ipc_binding
::
CParcelRewindRead
(
self
.as_mut_raw
(),
new_pos
)
}
}
}
}
/// Rewind the write position to a new position of parcel
fn
rewind_write
(
&
mut
self
,
new_pos
:
u32
)
->
bool
{
fn
rewind_write
(
&
mut
self
,
new_pos
:
u32
)
->
bool
{
unsafe
{
unsafe
{
ipc_binding
::
CParcelRewindWrite
(
self
.as_mut_raw
(),
new_pos
)
ipc_binding
::
CParcelRewindWrite
(
self
.as_mut_raw
(),
new_pos
)
}
}
}
}
/// Write a bytes stream into parcel
fn
write_buffer
(
&
mut
self
,
data
:
&
[
u8
])
->
bool
{
// SAFETY:
unsafe
{
ipc_binding
::
CParcelWriteBuffer
(
self
.as_mut_raw
(),
data
.as_ptr
(),
data
.len
()
as
u32
)
}
}
/// Read a sized bytes stream from parcel
fn
read_buffer
(
&
self
,
len
:
u32
)
->
Result
<
Vec
<
u8
>>
{
let
mut
buffer
:
Vec
<
MaybeUninit
<
u8
>>
=
Vec
::
with_capacity
(
len
as
usize
);
// SAFETY: this is safe because the vector contains MaybeUninit elements which can be uninitialized
unsafe
{
buffer
.set_len
(
len
as
usize
);
}
let
ok_status
=
unsafe
{
ipc_binding
::
CParcelReadBuffer
(
self
.as_raw
(),
buffer
.as_mut_ptr
()
as
*
mut
u8
,
len
)
};
// SAFETY: MaybeUninit has been initialized, this should be safe
// since MaybeUninit should have same layout as inner type
unsafe
fn
transmute_vec
(
v
:
Vec
<
std
::
mem
::
MaybeUninit
<
u8
>>
)
->
Vec
<
u8
>
{
std
::
mem
::
transmute
(
v
)
}
let
buffer
=
unsafe
{
transmute_vec
(
buffer
)
};
if
ok_status
{
Ok
(
buffer
)
}
else
{
Err
(
-
1
)
}
}
}
}
/// Container for a message (data and object references) that can be sent
/// Container for a message (data and object references) that can be sent
...
@@ -115,6 +161,7 @@ unsafe impl Send for MsgParcel {}
...
@@ -115,6 +161,7 @@ unsafe impl Send for MsgParcel {}
impl
IMsgParcel
for
MsgParcel
{}
impl
IMsgParcel
for
MsgParcel
{}
impl
MsgParcel
{
impl
MsgParcel
{
/// Create a MsgParcel object
pub
fn
new
()
->
Option
<
Self
>
{
pub
fn
new
()
->
Option
<
Self
>
{
let
cparcel
:
*
mut
CParcel
=
unsafe
{
let
cparcel
:
*
mut
CParcel
=
unsafe
{
ipc_binding
::
CParcelObtain
()
ipc_binding
::
CParcelObtain
()
...
@@ -123,10 +170,12 @@ impl MsgParcel {
...
@@ -123,10 +170,12 @@ impl MsgParcel {
NonNull
::
new
(
cparcel
)
.map
(|
x
|
MsgParcel
{
ptr
:
x
})
NonNull
::
new
(
cparcel
)
.map
(|
x
|
MsgParcel
{
ptr
:
x
})
}
}
/// # Safety
pub
unsafe
fn
from_raw
(
ptr
:
*
mut
CParcel
)
->
Option
<
MsgParcel
>
{
pub
unsafe
fn
from_raw
(
ptr
:
*
mut
CParcel
)
->
Option
<
MsgParcel
>
{
NonNull
::
new
(
ptr
)
.map
(|
ptr
|
Self
{
ptr
})
NonNull
::
new
(
ptr
)
.map
(|
ptr
|
Self
{
ptr
})
}
}
/// Get a raw CParcel pointer and MsgParcel dropped its ownership
pub
fn
into_raw
(
self
)
->
*
mut
CParcel
{
pub
fn
into_raw
(
self
)
->
*
mut
CParcel
{
let
ptr
=
self
.ptr
.as_ptr
();
let
ptr
=
self
.ptr
.as_ptr
();
let
_
=
ManuallyDrop
::
new
(
self
);
let
_
=
ManuallyDrop
::
new
(
self
);
...
@@ -189,7 +238,7 @@ impl<'a> IMsgParcel for BorrowedMsgParcel<'a> {}
...
@@ -189,7 +238,7 @@ impl<'a> IMsgParcel for BorrowedMsgParcel<'a> {}
impl
<
'a
>
BorrowedMsgParcel
<
'a
>
{
impl
<
'a
>
BorrowedMsgParcel
<
'a
>
{
/// # Safety
:
/// # Safety
///
///
/// `*mut CParcel` must be a valid pointer
/// `*mut CParcel` must be a valid pointer
pub
unsafe
fn
from_raw
(
ptr
:
*
mut
CParcel
)
->
Option
<
BorrowedMsgParcel
<
'a
>>
{
pub
unsafe
fn
from_raw
(
ptr
:
*
mut
CParcel
)
->
Option
<
BorrowedMsgParcel
<
'a
>>
{
...
@@ -223,20 +272,24 @@ unsafe impl<'a> AsRawPtr<CParcel> for BorrowedMsgParcel<'a> {
...
@@ -223,20 +272,24 @@ unsafe impl<'a> AsRawPtr<CParcel> for BorrowedMsgParcel<'a> {
}
}
impl
MsgParcel
{
impl
MsgParcel
{
/// Read a data object which implements the Deserialize trait from MsgParcel
pub
fn
read
<
D
:
Deserialize
>
(
&
self
)
->
Result
<
D
>
{
pub
fn
read
<
D
:
Deserialize
>
(
&
self
)
->
Result
<
D
>
{
self
.borrowed_ref
()
.read
()
self
.borrowed_ref
()
.read
()
}
}
/// Write a data object which implements the Serialize trait to MsgParcel
pub
fn
write
<
S
:
Serialize
+
?
Sized
>
(
&
mut
self
,
parcelable
:
&
S
)
->
Result
<
()
>
{
pub
fn
write
<
S
:
Serialize
+
?
Sized
>
(
&
mut
self
,
parcelable
:
&
S
)
->
Result
<
()
>
{
self
.borrowed
()
.write
(
parcelable
)
self
.borrowed
()
.write
(
parcelable
)
}
}
}
}
impl
<
'a
>
BorrowedMsgParcel
<
'a
>
{
impl
<
'a
>
BorrowedMsgParcel
<
'a
>
{
/// Read a data object which implements the Deserialize trait from BorrowedMsgParcel
pub
fn
read
<
D
:
Deserialize
>
(
&
self
)
->
Result
<
D
>
{
pub
fn
read
<
D
:
Deserialize
>
(
&
self
)
->
Result
<
D
>
{
D
::
deserialize
(
self
)
D
::
deserialize
(
self
)
}
}
/// Write a data object which implements the Serialize trait to BorrowedMsgParcel
pub
fn
write
<
S
:
Serialize
+
?
Sized
>
(
&
mut
self
,
parcelable
:
&
S
)
->
Result
<
()
>
{
pub
fn
write
<
S
:
Serialize
+
?
Sized
>
(
&
mut
self
,
parcelable
:
&
S
)
->
Result
<
()
>
{
parcelable
.serialize
(
self
)
parcelable
.serialize
(
self
)
}
}
...
...
interfaces/innerkits/rust/src/parcel/parcelable.rs
浏览文件 @
268e9ce6
...
@@ -18,12 +18,6 @@ use std::mem::MaybeUninit;
...
@@ -18,12 +18,6 @@ use std::mem::MaybeUninit;
use
std
::
ffi
::
c_void
;
use
std
::
ffi
::
c_void
;
use
std
::
ptr
;
use
std
::
ptr
;
// Internal use
pub
(
crate
)
trait
Parcelable
{
fn
marshalling
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
;
fn
unmarshalling
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
;
}
/// Implement `Serialize` trait to serialize a custom MsgParcel.
/// Implement `Serialize` trait to serialize a custom MsgParcel.
///
///
/// # Example:
/// # Example:
...
@@ -38,6 +32,7 @@ pub(crate) trait Parcelable {
...
@@ -38,6 +32,7 @@ pub(crate) trait Parcelable {
/// }
/// }
/// ```
/// ```
pub
trait
Serialize
{
pub
trait
Serialize
{
/// Serialize Self to BorrowedMsgParcel
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
;
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
;
}
}
...
@@ -63,8 +58,9 @@ pub trait Deserialize: Sized {
...
@@ -63,8 +58,9 @@ pub trait Deserialize: Sized {
pub
const
NULL_FLAG
:
i32
=
0
;
pub
const
NULL_FLAG
:
i32
=
0
;
pub
const
NON_NULL_FLAG
:
i32
=
1
;
pub
const
NON_NULL_FLAG
:
i32
=
1
;
//
DOC TODO
//
/ Define trait function for Option<T> which T must implements the trait Serialize.
pub
trait
SerOption
:
Serialize
{
pub
trait
SerOption
:
Serialize
{
/// Serialize the Option<T>
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
(),
>
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
(),
>
{
if
let
Some
(
inner
)
=
this
{
if
let
Some
(
inner
)
=
this
{
parcel
.write
(
&
NON_NULL_FLAG
)
?
;
parcel
.write
(
&
NON_NULL_FLAG
)
?
;
...
@@ -75,8 +71,9 @@ pub trait SerOption: Serialize {
...
@@ -75,8 +71,9 @@ pub trait SerOption: Serialize {
}
}
}
}
// DOC TODO
/// Define trait function for Option<T> which T must implements the trait Deserialize.
pub
trait
DeSerOption
:
Deserialize
{
pub
trait
DeOption
:
Deserialize
{
/// Deserialize the Option<T>
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
let
null
:
i32
=
parcel
.read
()
?
;
let
null
:
i32
=
parcel
.read
()
?
;
if
null
==
NULL_FLAG
{
if
null
==
NULL_FLAG
{
...
@@ -133,12 +130,133 @@ unsafe extern "C" fn allocate_vec<T>(
...
@@ -133,12 +130,133 @@ unsafe extern "C" fn allocate_vec<T>(
true
true
}
}
// DOC TODO
pub
trait
SerArray
:
Serialize
+
Sized
{
fn
ser_array
(
slice
:
&
[
Self
],
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
;
}
// DOC TODO
pub
trait
DeArray
:
Deserialize
{
// /// Helper trait for types that can be serialized as arrays.
fn
de_array
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Vec
<
Self
>>>
;
// /// Defaults to calling Serialize::serialize() manually for every element,
}
// /// but can be overridden for custom implementations like `writeByteArray`.
\ No newline at end of file
// // Until specialization is stabilized in Rust, we need this to be a separate
// // trait because it's the only way to have a default implementation for a method.
// // We want the default implementation for most types, but an override for
// // a few special ones like `readByteArray` for `u8`.
// pub trait SerArray: Serialize + Sized {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: Safe FFI, slice will always be a safe pointer to pass.
// ipc_binding::CparcelWriteParcelableArray(
// parcel.as_mut_raw(),
// slice.as_ptr() as *const c_void,
// slice.len().try_into().or(Err(-1))?,
// ser_element::<Self>,
// )
// };
// result_status::<()>(ret, ())
// }
// }
// /// Callback to serialize an element of a generic parcelable array.
// ///
// /// Safety: We are relying on binder_ndk to not overrun our slice. As long as it
// /// doesn't provide an index larger than the length of the original slice in
// /// serialize_array, this operation is safe. The index provided is zero-based.
// unsafe extern "C" fn ser_element<T: Serialize>(
// parcel: *mut ipc_binding::CParcel,
// array: *const c_void,
// index: c_ulong,
// ) -> bool {
// // c_ulong and usize are the same, but we need the explicitly sized version
// // so the function signature matches what bindgen generates.
// let index = index as usize;
// let slice: &[T] = std::slice::from_raw_parts(array.cast(), index+1);
// let mut parcel = match BorrowedMsgParcel::from_raw(parcel) {
// None => return false,
// Some(p) => p,
// };
// slice[index].serialize(&mut parcel)
// .err()
// .unwrap_or(false)
// }
// /// Helper trait for types that can be deserialized as arrays.
// /// Defaults to calling Deserialize::deserialize() manually for every element,
// /// but can be overridden for custom implementations like `readByteArray`.
// pub trait DeArray: Deserialize {
// /// Deserialize an array of type from the given parcel.
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // SAFETY: Safe FFI, vec is the correct opaque type expected by
// // allocate_vec and de_element.
// ipc_binding::CparcelReadParcelableArray(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec::<Self>,
// de_element::<Self>,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the C-API correctly initialized every
// // element of the vector by now, so we know that all the
// // MaybeUninits are now properly initialized. We can transmute from
// // Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T> has the same
// // alignment and size as T, so the pointer to the vector allocation
// // will be compatible.
// std::mem::transmute(vec)
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
// /// Callback to deserialize a parcelable element.
// ///
// /// 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).
// unsafe extern "C" fn de_element<T: Deserialize>(
// parcel: *const ipc_binding::CParcel,
// array: *mut c_void,
// index: c_ulong,
// ) -> bool {
// // c_ulong and usize are the same, but we need the explicitly sized version
// // so the function signature matches what bindgen generates.
// let index = index as usize;
// let vec = &mut *(array as *mut Option<Vec<MaybeUninit<T>>>);
// let vec = match vec {
// Some(v) => v,
// None => return false,
// };
// let parcel = match BorrowedMsgParcel::from_raw(parcel as *mut _) {
// None => return false,
// Some(p) => p,
// };
// let element = match parcel.read() {
// Ok(e) => e,
// Err(code) => return false,
// };
// ptr::write(vec[index].as_mut_ptr(), element);
// true
// }
// /// Safety: All elements in the vector must be properly initialized.
// unsafe fn vec_assume_init<T>(vec: Vec<MaybeUninit<T>>) -> Vec<T> {
// // We can convert from Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T>
// // has the same alignment and size as T, so the pointer to the vector
// // allocation will be compatible.
// let mut vec = std::mem::ManuallyDrop::new(vec);
// Vec::from_raw_parts(
// vec.as_mut_ptr().cast(),
// vec.len(),
// vec.capacity(),
// )
// }
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types.rs
浏览文件 @
268e9ce6
...
@@ -21,5 +21,11 @@ pub mod strings;
...
@@ -21,5 +21,11 @@ pub mod strings;
pub
mod
interface_token
;
pub
mod
interface_token
;
pub
mod
string16
;
pub
mod
string16
;
pub
mod
file_desc
;
pub
mod
file_desc
;
pub
mod
boxt
;
// pub mod const_array;
// pub mod slices;
// pub mod vector;
use
crate
::
parcel
::
parcelable
::
*
;
use
crate
::
parcel
::
parcelable
::
*
;
use
std
::
ffi
::{
c_char
,
c_void
};
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
AsRawPtr
,
result_status
,
Result
,
SerOption
,
DeOption
};
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types/bool.rs
浏览文件 @
268e9ce6
...
@@ -14,7 +14,6 @@
...
@@ -14,7 +14,6 @@
*/
*/
use
super
::
*
;
use
super
::
*
;
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
AsRawPtr
,
result_status
,
Result
};
impl
Serialize
for
bool
{
impl
Serialize
for
bool
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
...
...
interfaces/innerkits/rust/src/parcel/types/b
ytes
.rs
→
interfaces/innerkits/rust/src/parcel/types/b
oxt
.rs
浏览文件 @
268e9ce6
...
@@ -15,35 +15,26 @@
...
@@ -15,35 +15,26 @@
use
super
::
*
;
use
super
::
*
;
impl
Serialize
for
&
[
u8
]
{
impl
<
T
:
Serialize
>
Serialize
for
Box
<
T
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
Serialize
::
serialize
(
&**
self
,
parcel
)
let
ret
=
unsafe
{
}
ipc_binding
::
CParcelWriteBuffer
(
parcel
.as_mut_raw
(),
self
.as_ptr
()
as
*
const
void
,
self
.len
()
.try_into
()
.unwrap
()
)
};
result_status
::
<
()
>
(
ret
,
())
}
}
impl
Deserialize
for
Vec
<
u8
>
{
impl
<
T
:
Deserialize
>
Deserialize
for
Box
<
T
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
let
mut
vec
:
Option
<
Vec
<
u8
>>
=
None
;
Deserialize
::
deserialize
(
parcel
)
.map
(
Box
::
new
)
let
status
=
unsafe
{
}
// SAFETY: `parcel` always contains a valid pointer to a `CParcel`
}
ipc_binding
::
CParcelReadBuffer
(
parcel
.as_raw
(),
&
mut
vec
as
*
mut
_
as
*
mut
c_void
,
allocate_vec_with_buffer
::
<
u8
>
)
};
if
status
{
impl
<
T
:
SerOption
>
SerOption
for
Box
<
T
>
{
vec
.transpose
()
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
}
else
{
SerOption
::
ser_option
(
this
.map
(|
inner
|
&**
inner
),
parcel
)
Err
(
-
1
)
}
}
}
impl
<
T
:
DeOption
>
DeOption
for
Box
<
T
>
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
DeOption
::
de_option
(
parcel
)
.map
(|
t
|
t
.map
(
Box
::
new
))
}
}
}
}
\ No newline at end of file
interfaces/innerkits/rust/
tests/service
.rs
→
interfaces/innerkits/rust/
src/parcel/types/const_array
.rs
浏览文件 @
268e9ce6
...
@@ -13,55 +13,37 @@
...
@@ -13,55 +13,37 @@
* limitations under the License.
* limitations under the License.
*/
*/
extern
crate
ipc_rust
;
use
super
::
*
;
// Import types
impl
<
T
:
SerArray
,
const
N
:
usize
>
Serialize
for
[
T
;
N
]
{
use
ipc_rust
::{
IRemoteBroker
,
RemoteStub
,
define_remote_object
};
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
use
ipc_rust
::{
MsgParcel
,
BorrowedMsgParcel
};
// forwards to T::serialize_array.
SerArray
::
ser_array
(
self
,
parcel
)
pub
trait
ITest
:
IRemoteBroker
{
}
fn
hello
(
&
self
,
greeting
:
&
str
)
->
String
;
}
}
fn
on_remote_request
(
stub
:
&
dyn
ITest
,
code
:
u32
,
_
data
:
&
BorrowedMsgParcel
,
_
reply
:
&
mut
BorrowedMsgParcel
)
->
i32
{
impl
<
T
:
SerArray
,
const
N
:
usize
>
SerOption
for
[
T
;
N
]
{
match
code
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
1
=>
{
SerOption
::
ser_option
(
this
.map
(|
arr
|
&
arr
[
..
]),
parcel
)
println!
(
"TestStub hello: {}"
,
stub
.hello
(
"hello"
));
0
}
_
=>
-
1
}
}
}
}
define_remote_object!
(
impl
<
T
:
SerArray
,
const
N
:
usize
>
SerArray
for
[
T
;
N
]
{}
ITest
[
"ohos.ipc.test"
]
{
stub
:
TestStub
(
on_remote_request
),
proxy
:
TestProxy
,
}
);
// Make RemoteStub<TestStub> object can call ITest function directly.
impl
<
T
:
DeArray
,
const
N
:
usize
>
Deserialize
for
[
T
;
N
]
{
impl
ITest
for
RemoteStub
<
TestStub
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
fn
hello
(
&
self
,
greeting
:
&
str
)
->
String
{
let
vec
=
DeArray
::
de_array
(
parcel
)
// self will be convert to TestStub automatic because RemoteStub<TestStub>
.transpose
()
// implement the Deref trait
.unwrap_or
(
Err
(
-
1
))
?
;
self
.0
.hello
(
greeting
)
vec
.try_into
()
.or
(
Err
(
-
1
)
)
}
}
}
}
impl
ITest
for
TestProxy
{
impl
<
T
:
DeArray
,
const
N
:
usize
>
DeOption
for
[
T
;
N
]
{
fn
hello
(
&
self
,
_
greeting
:
&
str
)
->
String
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
let
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
vec
=
DeArray
::
de_array
(
parcel
)
?
;
let
reply
=
vec
.map
(|
v
|
v
.try_into
()
.or
(
Err
(
-
1
)))
.transpose
()
self
.remote
.send_request
(
1
,
&
data
,
false
);
match
reply
{
Ok
(
reply
)
=>
{
println!
(
"send hello ipc request success"
);
}
Err
(
error
)
=>
{
println!
(
"send hello ipc request fail: {}"
,
error
);
}
};
String
::
from
(
"hello"
)
}
}
}
}
impl
<
T
:
DeArray
,
const
N
:
usize
>
DeArray
for
[
T
;
N
]
{}
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types/file_desc.rs
浏览文件 @
268e9ce6
...
@@ -24,6 +24,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
...
@@ -24,6 +24,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
pub
struct
FileDesc
(
File
);
pub
struct
FileDesc
(
File
);
impl
FileDesc
{
impl
FileDesc
{
/// Create a FileDesc object with rust File object.
pub
fn
new
(
file
:
File
)
->
Self
{
pub
fn
new
(
file
:
File
)
->
Self
{
Self
(
file
)
Self
(
file
)
}
}
...
@@ -90,7 +91,7 @@ impl SerOption for FileDesc {
...
@@ -90,7 +91,7 @@ impl SerOption for FileDesc {
}
}
}
}
impl
De
Ser
Option
for
FileDesc
{
impl
DeOption
for
FileDesc
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
let
mut
fd
=
-
1i32
;
let
mut
fd
=
-
1i32
;
let
ok_status
=
unsafe
{
let
ok_status
=
unsafe
{
...
...
interfaces/innerkits/rust/src/parcel/types/integer.rs
浏览文件 @
268e9ce6
...
@@ -51,7 +51,6 @@ impl Deserialize for u8 {
...
@@ -51,7 +51,6 @@ impl Deserialize for u8 {
}
}
}
}
/// i16 && u16
/// i16 && u16
impl
Serialize
for
i16
{
impl
Serialize
for
i16
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
...
@@ -74,6 +73,55 @@ impl Deserialize for i16 {
...
@@ -74,6 +73,55 @@ impl Deserialize for i16 {
}
}
}
}
// impl SerArray for i16 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt16Array(
// parcel.as_mut_raw(),
// slice.as_ptr(),
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for i16 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt16Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
impl
Serialize
for
u16
{
impl
Serialize
for
u16
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
(
*
self
as
i16
)
.serialize
(
parcel
)
(
*
self
as
i16
)
.serialize
(
parcel
)
...
@@ -86,6 +134,54 @@ impl Deserialize for u16 {
...
@@ -86,6 +134,54 @@ impl Deserialize for u16 {
}
}
}
}
// impl SerArray for u16 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt16Array(
// parcel.as_mut_raw(),
// slice.as_ptr() as *const i16,
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for u16 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt16Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
/// i32 && u32
/// i32 && u32
impl
Serialize
for
i32
{
impl
Serialize
for
i32
{
...
@@ -109,6 +205,55 @@ impl Deserialize for i32 {
...
@@ -109,6 +205,55 @@ impl Deserialize for i32 {
}
}
}
}
// impl SerArray for i32 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt32Array(
// parcel.as_mut_raw(),
// slice.as_ptr(),
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for i32 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt32Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
impl
Serialize
for
u32
{
impl
Serialize
for
u32
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
(
*
self
as
i32
)
.serialize
(
parcel
)
(
*
self
as
i32
)
.serialize
(
parcel
)
...
@@ -121,6 +266,55 @@ impl Deserialize for u32 {
...
@@ -121,6 +266,55 @@ impl Deserialize for u32 {
}
}
}
}
// impl SerArray for u32 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt32Array(
// parcel.as_mut_raw(),
// slice.as_ptr() as *const i32,
// slice.len().try_into().or(Err(-1)?,
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for u32 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt32Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
/// i64 && u64
/// i64 && u64
impl
Serialize
for
i64
{
impl
Serialize
for
i64
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
...
@@ -143,6 +337,55 @@ impl Deserialize for i64 {
...
@@ -143,6 +337,55 @@ impl Deserialize for i64 {
}
}
}
}
// impl SerArray for i64 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt64Array(
// parcel.as_mut_raw(),
// slice.as_ptr() as *const i64,
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for i64 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt64Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
impl
Serialize
for
u64
{
impl
Serialize
for
u64
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
(
*
self
as
i64
)
.serialize
(
parcel
)
(
*
self
as
i64
)
.serialize
(
parcel
)
...
@@ -155,7 +398,54 @@ impl Deserialize for u64 {
...
@@ -155,7 +398,54 @@ impl Deserialize for u64 {
}
}
}
}
// impl SerArray for u64 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteInt64Array(
// parcel.as_mut_raw(),
// slice.as_ptr() as *const i64,
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for u64 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadInt64Array(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
/// f32
/// f32
impl
Serialize
for
f32
{
impl
Serialize
for
f32
{
...
@@ -179,6 +469,53 @@ impl Deserialize for f32 {
...
@@ -179,6 +469,53 @@ impl Deserialize for f32 {
}
}
}
}
// impl SerArray for f32 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteFloatArray(
// parcel.as_mut_raw(),
// slice.as_ptr(),
// slice.len().try_into().or(Err(-1)?,
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for f32 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadFloatArray(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
/// f64
/// f64
impl
Serialize
for
f64
{
impl
Serialize
for
f64
{
...
@@ -201,3 +538,51 @@ impl Deserialize for f64 {
...
@@ -201,3 +538,51 @@ impl Deserialize for f64 {
result_status
::
<
f64
>
(
ret
,
val
)
result_status
::
<
f64
>
(
ret
,
val
)
}
}
}
}
// impl SerArray for f64 {
// fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// let ret = unsafe {
// // SAFETY: `parcel` always contains a valid pointer to a `CParcel`
// // If the slice is > 0 length, `slice.as_ptr()` will be a
// // valid pointer to an array of elements of type `$ty`. If the slice
// // length is 0, `slice.as_ptr()` may be dangling, but this is safe
// // since the pointer is not dereferenced if the length parameter is
// // 0.
// ipc_binding::CParcelWriteDoubleArray(
// parcel.as_mut_raw(),
// slice.as_ptr(),
// slice.len()
// )
// };
// result_status::<()>(ret, ())
// }
// }
// impl DeArray for f64 {
// fn de_array(parcel: &BorrowedMsgParcel<'_>) -> Result<Option<Vec<Self>>> {
// let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
// let ok_status = unsafe {
// // 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.
// ipc_binding::CParcelReadDoubleArray(
// parcel.as_raw(),
// &mut vec as *mut _ as *mut c_void,
// allocate_vec_with_buffer,
// )
// };
// if ok_status{
// let vec: Option<Vec<Self>> = unsafe {
// // SAFETY: We are assuming that the NDK correctly
// // initialized every element of the vector by now, so we
// // know that all the MaybeUninits are now properly
// // initialized.
// vec.map(|vec| vec_assume_init(vec))
// };
// Ok(vec)
// }else{
// Err(-1)
// }
// }
// }
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types/interface_token.rs
浏览文件 @
268e9ce6
...
@@ -15,16 +15,18 @@
...
@@ -15,16 +15,18 @@
use
super
::
*
;
use
super
::
*
;
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
Result
,
AsRawPtr
,
result_status
};
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
Result
,
AsRawPtr
,
result_status
};
use
std
::
ffi
::{
c_char
,
c_void
};
use
std
::
convert
::
TryInto
;
use
std
::
convert
::
TryInto
;
/// InterfaceToken packed a String type which transfered with C++ std::u16string.
pub
struct
InterfaceToken
(
String
);
pub
struct
InterfaceToken
(
String
);
impl
InterfaceToken
{
impl
InterfaceToken
{
/// Create a InterfaceToken object by Rust String
pub
fn
new
(
value
:
&
str
)
->
Self
{
pub
fn
new
(
value
:
&
str
)
->
Self
{
Self
(
String
::
from
(
value
))
Self
(
String
::
from
(
value
))
}
}
/// Get packed String of InterfaceToken
pub
fn
get_token
(
&
self
)
->
String
{
pub
fn
get_token
(
&
self
)
->
String
{
String
::
from
(
&
self
.0
)
String
::
from
(
&
self
.0
)
}
}
...
...
interfaces/innerkits/rust/src/parcel/types/option.rs
浏览文件 @
268e9ce6
...
@@ -14,7 +14,6 @@
...
@@ -14,7 +14,6 @@
*/
*/
use
super
::
*
;
use
super
::
*
;
use
crate
::{
BorrowedMsgParcel
,
Result
,
SerOption
,
DeSerOption
};
impl
<
T
:
SerOption
>
Serialize
for
Option
<
T
>
{
impl
<
T
:
SerOption
>
Serialize
for
Option
<
T
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
...
@@ -22,8 +21,11 @@ impl<T: SerOption> Serialize for Option<T> {
...
@@ -22,8 +21,11 @@ impl<T: SerOption> Serialize for Option<T> {
}
}
}
}
impl
<
T
:
De
Ser
Option
>
Deserialize
for
Option
<
T
>
{
impl
<
T
:
DeOption
>
Deserialize
for
Option
<
T
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
De
Ser
Option
::
de_option
(
parcel
)
DeOption
::
de_option
(
parcel
)
}
}
}
}
// impl<T: DeOption> DeArray for Option<T> {}
// impl<T: SerOption> SerArray for Option<T> {}
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types/slices.rs
浏览文件 @
268e9ce6
...
@@ -13,4 +13,22 @@
...
@@ -13,4 +13,22 @@
* limitations under the License.
* limitations under the License.
*/
*/
// TODO
use
super
::
*
;
\ No newline at end of file
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
AsRawPtr
,
result_status
,
Result
};
impl
<
T
:
SerArray
>
Serialize
for
[
T
]
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
SerArray
::
ser_array
(
self
,
parcel
)
}
}
impl
<
T
:
SerArray
>
SerOption
for
[
T
]
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
if
let
Some
(
v
)
=
this
{
SerArray
::
ser_array
(
v
,
parcel
)
}
else
{
parcel
.write
(
&-
1i32
)
}
}
}
\ No newline at end of file
interfaces/innerkits/rust/src/parcel/types/string16.rs
浏览文件 @
268e9ce6
...
@@ -15,16 +15,18 @@
...
@@ -15,16 +15,18 @@
use
super
::
*
;
use
super
::
*
;
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
Result
,
result_status
,
AsRawPtr
};
use
crate
::{
ipc_binding
,
BorrowedMsgParcel
,
Result
,
result_status
,
AsRawPtr
};
use
std
::
ffi
::{
c_char
,
c_void
};
use
std
::
convert
::
TryInto
;
use
std
::
convert
::
TryInto
;
/// String16 packed a String type which transfered with C++ std::u16string.
pub
struct
String16
(
String
);
pub
struct
String16
(
String
);
impl
String16
{
impl
String16
{
/// Create a String16 object with rust String
pub
fn
new
(
value
:
&
str
)
->
Self
{
pub
fn
new
(
value
:
&
str
)
->
Self
{
Self
(
String
::
from
(
value
))
Self
(
String
::
from
(
value
))
}
}
/// Get packed String of String16
pub
fn
get_string
(
&
self
)
->
String
{
pub
fn
get_string
(
&
self
)
->
String
{
String
::
from
(
&
self
.0
)
String
::
from
(
&
self
.0
)
}
}
...
...
interfaces/innerkits/rust/src/parcel/types/strings.rs
浏览文件 @
268e9ce6
...
@@ -20,7 +20,6 @@ use crate::{
...
@@ -20,7 +20,6 @@ use crate::{
};
};
use
std
::
ptr
;
use
std
::
ptr
;
use
std
::
convert
::
TryInto
;
use
std
::
convert
::
TryInto
;
use
std
::
ffi
::{
c_char
,
c_void
};
impl
SerOption
for
str
{
impl
SerOption
for
str
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
...
...
interfaces/innerkits/rust/src/parcel/types/vector.rs
浏览文件 @
268e9ce6
...
@@ -15,4 +15,29 @@
...
@@ -15,4 +15,29 @@
use
super
::
*
;
use
super
::
*
;
// TODO
\ No newline at end of file
impl
<
T
:
SerArray
>
Serialize
for
Vec
<
T
>
{
fn
serialize
(
&
self
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
SerArray
::
ser_array
(
&
self
[
..
],
parcel
)
}
}
impl
<
T
:
SerArray
>
SerOption
for
Vec
<
T
>
{
fn
ser_option
(
this
:
Option
<&
Self
>
,
parcel
:
&
mut
BorrowedMsgParcel
<
'_
>
)
->
Result
<
()
>
{
SerOption
::
ser_option
(
this
.map
(
Vec
::
as_slice
),
parcel
)
}
}
impl
<
T
:
DeArray
>
Deserialize
for
Vec
<
T
>
{
fn
deserialize
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Self
>
{
DeArray
::
de_array
(
parcel
)
.transpose
()
.unwrap_or
(
Err
(
-
1
))
}
}
impl
<
T
:
DeArray
>
DeOption
for
Vec
<
T
>
{
fn
de_option
(
parcel
:
&
BorrowedMsgParcel
<
'_
>
)
->
Result
<
Option
<
Self
>>
{
DeArray
::
de_array
(
parcel
)
}
}
\ No newline at end of file
interfaces/innerkits/rust/src/process.rs
浏览文件 @
268e9ce6
...
@@ -26,35 +26,38 @@ fn get_samgr() -> Option<RemoteObj>
...
@@ -26,35 +26,38 @@ fn get_samgr() -> Option<RemoteObj>
}
}
}
}
/// Add a service to samgr
pub
fn
add_service
(
service
:
&
RemoteObj
,
said
:
i32
)
->
Result
<
()
>
pub
fn
add_service
(
service
:
&
RemoteObj
,
said
:
i32
)
->
Result
<
()
>
{
{
let
samgr
=
get_samgr
()
.expect
(
"samgr is not null"
);
let
samgr
=
get_samgr
()
.expect
(
"samgr is not null"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel is not null"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel is not null"
);
let
_
=
data
.write
(
&
InterfaceToken
::
new
(
"ohos.samgr.accessToken"
))
?
;
data
.write
(
&
InterfaceToken
::
new
(
"ohos.samgr.accessToken"
))
?
;
let
_
=
data
.write
(
&
said
)
?
;
data
.write
(
&
said
)
?
;
let
_
=
data
.write
(
service
)
?
;
data
.write
(
service
)
?
;
let
_
=
data
.write
(
&
false
)
?
;
data
.write
(
&
false
)
?
;
let
_
=
data
.write
(
&
0
)
?
;
data
.write
(
&
0
)
?
;
let
_
=
data
.write
(
&
String16
::
new
(
""
))
?
;
data
.write
(
&
String16
::
new
(
""
))
?
;
let
_
=
data
.write
(
&
String16
::
new
(
""
))
?
;
data
.write
(
&
String16
::
new
(
""
))
?
;
let
reply
=
samgr
.send_request
(
3
,
&
data
,
false
)
?
;
let
reply
=
samgr
.send_request
(
3
,
&
data
,
false
)
?
;
let
reply
V
alue
:
i32
=
reply
.read
()
?
;
let
reply
_v
alue
:
i32
=
reply
.read
()
?
;
println!
(
"register service result: {}"
,
reply
V
alue
);
println!
(
"register service result: {}"
,
reply
_v
alue
);
if
reply
Value
==
0
{
Ok
(())}
else
{
Err
(
replyV
alue
)
}
if
reply
_value
==
0
{
Ok
(())}
else
{
Err
(
reply_v
alue
)
}
}
}
/// Get a service proxy from samgr
pub
fn
get_service
(
said
:
i32
)
->
Result
<
RemoteObj
>
pub
fn
get_service
(
said
:
i32
)
->
Result
<
RemoteObj
>
{
{
let
samgr
=
get_samgr
()
.expect
(
"samgr is not null"
);
let
samgr
=
get_samgr
()
.expect
(
"samgr is not null"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel is not null"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel is not null"
);
let
_
=
data
.write
(
&
InterfaceToken
::
new
(
"ohos.samgr.accessToken"
))
?
;
data
.write
(
&
InterfaceToken
::
new
(
"ohos.samgr.accessToken"
))
?
;
let
_
=
data
.write
(
&
said
)
?
;
data
.write
(
&
said
)
?
;
let
reply
=
samgr
.send_request
(
2
,
&
data
,
false
)
?
;
let
reply
=
samgr
.send_request
(
2
,
&
data
,
false
)
?
;
let
remote
:
RemoteObj
=
reply
.read
()
?
;
let
remote
:
RemoteObj
=
reply
.read
()
?
;
println!
(
"get service success"
);
println!
(
"get service success"
);
Ok
(
remote
)
Ok
(
remote
)
}
}
/// Make current thread join to the IPC/RPC work thread pool
pub
fn
join_work_thread
()
pub
fn
join_work_thread
()
{
{
unsafe
{
unsafe
{
...
@@ -62,6 +65,7 @@ pub fn join_work_thread()
...
@@ -62,6 +65,7 @@ pub fn join_work_thread()
}
}
}
}
/// Exit current thread from IPC/RPC work thread pool
pub
fn
stop_work_thread
()
pub
fn
stop_work_thread
()
{
{
unsafe
{
unsafe
{
...
@@ -69,13 +73,7 @@ pub fn stop_work_thread()
...
@@ -69,13 +73,7 @@ pub fn stop_work_thread()
}
}
}
}
pub
fn
init_access_token
()
/// Get calling token ID of caller
{
unsafe
{
ipc_binding
::
InitTokenId
();
}
}
pub
fn
get_calling_token_id
()
->
u64
pub
fn
get_calling_token_id
()
->
u64
{
{
unsafe
{
unsafe
{
...
@@ -83,6 +81,7 @@ pub fn get_calling_token_id() -> u64
...
@@ -83,6 +81,7 @@ pub fn get_calling_token_id() -> u64
}
}
}
}
/// Get first calling token ID of caller
pub
fn
get_first_token_id
()
->
u64
pub
fn
get_first_token_id
()
->
u64
{
{
unsafe
{
unsafe
{
...
@@ -90,6 +89,7 @@ pub fn get_first_token_id() -> u64
...
@@ -90,6 +89,7 @@ pub fn get_first_token_id() -> u64
}
}
}
}
/// Get self token id of current process
pub
fn
get_self_token_id
()
->
u64
pub
fn
get_self_token_id
()
->
u64
{
{
unsafe
{
unsafe
{
...
@@ -97,6 +97,7 @@ pub fn get_self_token_id() -> u64
...
@@ -97,6 +97,7 @@ pub fn get_self_token_id() -> u64
}
}
}
}
/// Get calling process id of caller
pub
fn
get_calling_pid
()
->
u64
pub
fn
get_calling_pid
()
->
u64
{
{
unsafe
{
unsafe
{
...
@@ -104,6 +105,7 @@ pub fn get_calling_pid() -> u64
...
@@ -104,6 +105,7 @@ pub fn get_calling_pid() -> u64
}
}
}
}
/// Get calling user id of caller
pub
fn
get_calling_uid
()
->
u64
pub
fn
get_calling_uid
()
->
u64
{
{
unsafe
{
unsafe
{
...
...
ipc/native/src/c_wrapper/include/c_parcel.h
浏览文件 @
268e9ce6
...
@@ -59,6 +59,8 @@ bool CParcelWriteRemoteObject(CParcel *parcel, const CRemoteObject *object);
...
@@ -59,6 +59,8 @@ bool CParcelWriteRemoteObject(CParcel *parcel, const CRemoteObject *object);
CRemoteObject
*
CParcelReadRemoteObject
(
const
CParcel
*
parcel
);
CRemoteObject
*
CParcelReadRemoteObject
(
const
CParcel
*
parcel
);
bool
CParcelWriteFileDescriptor
(
CParcel
*
parcel
,
int32_t
fd
);
bool
CParcelWriteFileDescriptor
(
CParcel
*
parcel
,
int32_t
fd
);
bool
CParcelReadFileDescriptor
(
const
CParcel
*
parcel
,
int32_t
*
fd
);
bool
CParcelReadFileDescriptor
(
const
CParcel
*
parcel
,
int32_t
*
fd
);
bool
CParcelWriteBuffer
(
CParcel
*
parcel
,
const
uint8_t
*
buffer
,
uint32_t
len
);
bool
CParcelReadBuffer
(
const
CParcel
*
parcel
,
uint8_t
*
value
,
uint32_t
len
);
uint32_t
CParcelGetDataSize
(
const
CParcel
*
parcel
);
uint32_t
CParcelGetDataSize
(
const
CParcel
*
parcel
);
bool
CParcelSetDataSize
(
CParcel
*
parcel
,
uint32_t
new_size
);
bool
CParcelSetDataSize
(
CParcel
*
parcel
,
uint32_t
new_size
);
...
...
ipc/native/src/c_wrapper/include/c_process.h
浏览文件 @
268e9ce6
...
@@ -27,7 +27,6 @@ CRemoteObject *GetContextManager(void);
...
@@ -27,7 +27,6 @@ CRemoteObject *GetContextManager(void);
void
JoinWorkThread
(
void
);
void
JoinWorkThread
(
void
);
void
StopWorkThread
(
void
);
void
StopWorkThread
(
void
);
void
InitTokenId
(
void
);
uint64_t
GetCallingTokenId
(
void
);
uint64_t
GetCallingTokenId
(
void
);
uint64_t
GetFirstToekenId
(
void
);
uint64_t
GetFirstToekenId
(
void
);
uint64_t
GetSelfToekenId
(
void
);
uint64_t
GetSelfToekenId
(
void
);
...
...
ipc/native/src/c_wrapper/source/c_parcel.cpp
浏览文件 @
268e9ce6
...
@@ -274,7 +274,7 @@ bool CParcelReadString16(const CParcel *parcel, void *stringData, OnCParcelBytes
...
@@ -274,7 +274,7 @@ bool CParcelReadString16(const CParcel *parcel, void *stringData, OnCParcelBytes
}
}
std
::
string
value
=
Str16ToStr8
(
u16string
);
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
());
printf
(
"%s: u16string len: %
lu, string len: %l
u
\n
"
,
__func__
,
u16string
.
length
(),
value
.
length
());
return
false
;
return
false
;
}
}
char
*
buffer
=
nullptr
;
char
*
buffer
=
nullptr
;
...
@@ -315,7 +315,7 @@ bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelByte
...
@@ -315,7 +315,7 @@ bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelByte
std
::
u16string
u16string
=
parcel
->
parcel_
->
ReadInterfaceToken
();
std
::
u16string
u16string
=
parcel
->
parcel_
->
ReadInterfaceToken
();
std
::
string
value
=
Str16ToStr8
(
u16string
);
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
());
printf
(
"%s: u16string len: %
lu, string len: %l
u
\n
"
,
__func__
,
u16string
.
length
(),
value
.
length
());
return
false
;
return
false
;
}
}
printf
(
"%s: c read interface token: %s
\n
"
,
__func__
,
value
.
c_str
());
printf
(
"%s: c read interface token: %s
\n
"
,
__func__
,
value
.
c_str
());
...
@@ -386,6 +386,35 @@ bool CParcelReadFileDescriptor(const CParcel *parcel, int32_t *fd)
...
@@ -386,6 +386,35 @@ bool CParcelReadFileDescriptor(const CParcel *parcel, int32_t *fd)
return
(
*
fd
<
0
)
?
false
:
true
;
return
(
*
fd
<
0
)
?
false
:
true
;
}
}
bool
CParcelWriteBuffer
(
CParcel
*
parcel
,
const
uint8_t
*
buffer
,
uint32_t
len
)
{
if
(
!
IsValidParcel
(
parcel
,
__func__
))
{
return
false
;
}
if
(
buffer
==
nullptr
)
{
printf
(
"%s: buffer is null: %d
\n
"
,
__func__
,
len
);
return
false
;
}
return
parcel
->
parcel_
->
WriteBuffer
(
buffer
,
len
);
}
bool
CParcelReadBuffer
(
const
CParcel
*
parcel
,
uint8_t
*
value
,
uint32_t
len
)
{
if
(
!
IsValidParcel
(
parcel
,
__func__
)
||
value
==
nullptr
)
{
return
false
;
}
const
uint8_t
*
data
=
parcel
->
parcel_
->
ReadBuffer
(
len
);
if
(
data
==
nullptr
)
{
printf
(
"%s: read buffer failed
\n
"
,
__func__
);
return
false
;
}
if
(
len
>
0
&&
memcpy_s
(
value
,
len
,
data
,
len
)
!=
EOK
)
{
printf
(
"%s: copy buffer failed
\n
"
,
__func__
);
return
false
;
}
return
true
;
}
uint32_t
CParcelGetDataSize
(
const
CParcel
*
parcel
)
uint32_t
CParcelGetDataSize
(
const
CParcel
*
parcel
)
{
{
if
(
!
IsValidParcel
(
parcel
,
__func__
))
{
if
(
!
IsValidParcel
(
parcel
,
__func__
))
{
...
...
ipc/native/src/c_wrapper/source/c_process.cpp
浏览文件 @
268e9ce6
...
@@ -15,8 +15,6 @@
...
@@ -15,8 +15,6 @@
#include "c_process.h"
#include "c_process.h"
#include <nativetoken_kit.h>
#include <token_setproc.h>
#include "c_remote_object_internal.h"
#include "c_remote_object_internal.h"
#include "ipc_skeleton.h"
#include "ipc_skeleton.h"
...
@@ -48,23 +46,6 @@ void StopWorkThread(void)
...
@@ -48,23 +46,6 @@ void StopWorkThread(void)
IPCSkeleton
::
StopWorkThread
();
IPCSkeleton
::
StopWorkThread
();
}
}
void
InitTokenId
(
void
)
{
uint64_t
tokenId
;
NativeTokenInfoParams
infoInstance
=
{
.
dcapsNum
=
0
,
.
permsNum
=
0
,
.
aclsNum
=
0
,
.
dcaps
=
NULL
,
.
perms
=
NULL
,
.
acls
=
NULL
,
.
processName
=
"com.ipc.test"
,
.
aplStr
=
"normal"
,
};
tokenId
=
GetAccessTokenId
(
&
infoInstance
);
SetSelfTokenID
(
tokenId
);
}
uint64_t
GetCallingTokenId
(
void
)
uint64_t
GetCallingTokenId
(
void
)
{
{
return
IPCSkeleton
::
GetCallingFullTokenID
();
return
IPCSkeleton
::
GetCallingFullTokenID
();
...
...
ipc/native/src/c_wrapper/source/c_remote_object.cpp
浏览文件 @
268e9ce6
...
@@ -163,7 +163,7 @@ bool RemoteObjectLessThan(const CRemoteObject *lhs, const CRemoteObject *rhs)
...
@@ -163,7 +163,7 @@ bool RemoteObjectLessThan(const CRemoteObject *lhs, const CRemoteObject *rhs)
int
RemoteObjectSendRequest
(
const
CRemoteObject
*
object
,
uint32_t
code
,
int
RemoteObjectSendRequest
(
const
CRemoteObject
*
object
,
uint32_t
code
,
const
CParcel
*
data
,
CParcel
*
reply
,
bool
isAsync
)
const
CParcel
*
data
,
CParcel
*
reply
,
bool
isAsync
)
{
{
if
(
!
IsValidRemoteObject
(
object
,
__func__
)
||
data
==
nullptr
)
{
if
(
!
IsValidRemoteObject
(
object
,
__func__
)
||
data
==
nullptr
||
reply
==
nullptr
)
{
printf
(
"%s: object and data must be not null
\n
"
,
__func__
);
printf
(
"%s: object and data must be not null
\n
"
,
__func__
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -180,7 +180,7 @@ CDeathRecipient *CreateDeathRecipient(OnDeathRecipientCb onDeathRecipient,
...
@@ -180,7 +180,7 @@ CDeathRecipient *CreateDeathRecipient(OnDeathRecipientCb onDeathRecipient,
}
}
CDeathRecipient
*
recipient
=
new
(
std
::
nothrow
)
CDeathRecipient
(
onDeathRecipient
,
CDeathRecipient
*
recipient
=
new
(
std
::
nothrow
)
CDeathRecipient
(
onDeathRecipient
,
onDestroy
,
userData
);
onDestroy
,
userData
);
if
(
userData
==
nullptr
)
{
if
(
recipient
==
nullptr
)
{
printf
(
"%s: create CDeathRecipient object failed
\n
"
,
__func__
);
printf
(
"%s: create CDeathRecipient object failed
\n
"
,
__func__
);
return
nullptr
;
return
nullptr
;
}
}
...
...
ipc/native/test/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -18,5 +18,8 @@ import("//build/test.gni")
...
@@ -18,5 +18,8 @@ import("//build/test.gni")
group("unittest") {
group("unittest") {
testonly = true
testonly = true
deps = [ "unittest/common:unittest" ]
deps = [ "unittest/common:unittest" ]
if (target_cpu == "arm64") {
deps += [ "unittest/rust:unittest" ]
}
}
}
###############################################################################
###############################################################################
ipc/native/test/unittest/common/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -334,6 +334,42 @@ ohos_unittest("RPCFeatureUnitTest") {
...
@@ -334,6 +334,42 @@ ohos_unittest("RPCFeatureUnitTest") {
"//foundation/communication/ipc/test/resource/ipc/ohos_test.xml"
"//foundation/communication/ipc/test/resource/ipc/ohos_test.xml"
}
}
if (target_cpu == "arm64") {
ohos_unittest("IPCCInterfaceUnitTest") {
module_out_path = MODULE_OUTPUT_PATH
include_dirs = [
"//commonlibrary/c_utils/base/include",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//foundation/communication/ipc/ipc/native/src/c_wrapper/include",
]
sources = [
"ipc_c_message_parcel_unittest.cpp",
"ipc_c_process_unittest.cpp",
"ipc_c_remote_object_unittest.cpp",
]
configs = [
"$SUBSYSTEM_DIR:ipc_util_config",
"$IPC_TEST_ROOT:ipc_test_config",
]
deps = [
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
"//foundation/communication/ipc/interfaces/innerkits/rust:ipc_c",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
]
external_deps = [ "c_utils:utils" ]
resource_config_file =
"//foundation/communication/ipc/test/resource/ipc/ohos_test.xml"
}
}
###############################################################################
###############################################################################
group("unittest") {
group("unittest") {
testonly = true
testonly = true
...
@@ -347,6 +383,9 @@ group("unittest") {
...
@@ -347,6 +383,9 @@ group("unittest") {
":InvokerFactoryTest",
":InvokerFactoryTest",
":RPCFeatureUnitTest",
":RPCFeatureUnitTest",
]
]
if (target_cpu == "arm64") {
deps += [ ":IPCCInterfaceUnitTest" ]
}
if (support_jsapi) {
if (support_jsapi) {
deps += [ ":IPCNapiUnitTest" ]
deps += [ ":IPCNapiUnitTest" ]
}
}
...
...
ipc/native/test/unittest/common/ipc_c_message_parcel_unittest.cpp
0 → 100644
浏览文件 @
268e9ce6
/*
* 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.
*/
#include <gtest/gtest.h>
#include <refbase.h>
#include "c_parcel.h"
#include "c_parcel_internal.h"
using
namespace
testing
::
ext
;
using
namespace
OHOS
;
static
const
int
NUMBER_CONSTANT
=
100
;
static
const
float
FLOAT_CONSTANT
=
1.1
;
static
const
char
*
STRING_CONSTATN
=
"HELLO"
;
class
IpcCMessageParcelUnitTest
:
public
testing
::
Test
{
public:
static
void
SetUpTestCase
(
void
);
static
void
TearDownTestCase
(
void
);
void
SetUp
();
void
TearDown
();
};
void
IpcCMessageParcelUnitTest
::
SetUpTestCase
()
{}
void
IpcCMessageParcelUnitTest
::
TearDownTestCase
()
{}
void
IpcCMessageParcelUnitTest
::
SetUp
()
{}
void
IpcCMessageParcelUnitTest
::
TearDown
()
{}
static
bool
CParcelBytesAllocatorOk
(
void
*
stringData
,
char
**
buffer
,
int32_t
len
)
{
if
(
buffer
==
nullptr
||
len
<
0
)
{
return
false
;
}
*
buffer
=
(
char
*
)
malloc
(
len
);
if
(
*
buffer
==
nullptr
)
{
return
false
;
}
void
**
ptr
=
reinterpret_cast
<
void
**>
(
stringData
);
if
(
ptr
!=
nullptr
)
{
*
ptr
=
*
buffer
;
}
return
true
;
}
static
bool
CParcelBytesAllocatorErr
(
void
*
stringData
,
char
**
buffer
,
int32_t
len
)
{
(
void
)
stringData
;
(
void
)
buffer
;
(
void
)
len
;
return
false
;
}
/**
* @tc.name: CParcelRefCount
* @tc.desc: Verify the CParcel reference count functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelRefCount
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
RefBase
*
ref
=
static_cast
<
RefBase
*>
(
parcel
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
CParcelIncStrongRef
(
parcel
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
2
);
CParcelDecStrongRef
(
parcel
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
CParcelIncStrongRef
(
nullptr
);
CParcelDecStrongRef
(
nullptr
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelBool
* @tc.desc: Verify the CParcel for bool type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelBool
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
EXPECT_EQ
(
CParcelWriteBool
(
nullptr
,
true
),
false
);
EXPECT_EQ
(
CParcelWriteBool
(
parcel
,
false
),
true
);
EXPECT_EQ
(
CParcelWriteBool
(
parcel
,
true
),
true
);
bool
bool_val
=
true
;
EXPECT_EQ
(
CParcelReadBool
(
nullptr
,
&
bool_val
),
false
);
EXPECT_EQ
(
CParcelReadBool
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadBool
(
parcel
,
&
bool_val
),
true
);
EXPECT_EQ
(
bool_val
,
false
);
EXPECT_EQ
(
CParcelReadBool
(
parcel
,
&
bool_val
),
true
);
EXPECT_EQ
(
bool_val
,
true
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInt8
* @tc.desc: Verify the CParcel for int8_t type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInt8
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
int8_t
int8_val
=
static_cast
<
int8_t
>
(
NUMBER_CONSTANT
);
EXPECT_EQ
(
CParcelWriteInt8
(
nullptr
,
int8_val
),
false
);
EXPECT_EQ
(
CParcelWriteInt8
(
parcel
,
int8_val
),
true
);
EXPECT_EQ
(
CParcelReadInt8
(
nullptr
,
&
int8_val
),
false
);
EXPECT_EQ
(
CParcelReadInt8
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadInt8
(
parcel
,
&
int8_val
),
true
);
EXPECT_EQ
(
int8_val
,
static_cast
<
int8_t
>
(
NUMBER_CONSTANT
));
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInt16
* @tc.desc: Verify the CParcel for int16_t type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInt16
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
int16_t
int16_val
=
static_cast
<
int16_t
>
(
NUMBER_CONSTANT
);
EXPECT_EQ
(
CParcelWriteInt16
(
nullptr
,
int16_val
),
false
);
EXPECT_EQ
(
CParcelWriteInt16
(
parcel
,
int16_val
),
true
);
EXPECT_EQ
(
CParcelReadInt16
(
nullptr
,
&
int16_val
),
false
);
EXPECT_EQ
(
CParcelReadInt16
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadInt16
(
parcel
,
&
int16_val
),
true
);
EXPECT_EQ
(
int16_val
,
static_cast
<
int16_t
>
(
NUMBER_CONSTANT
));
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInt32
* @tc.desc: Verify the CParcel for int32_t type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInt32
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
int32_t
int32_val
=
static_cast
<
int32_t
>
(
NUMBER_CONSTANT
);
EXPECT_EQ
(
CParcelWriteInt32
(
nullptr
,
int32_val
),
false
);
EXPECT_EQ
(
CParcelWriteInt32
(
parcel
,
int32_val
),
true
);
EXPECT_EQ
(
CParcelReadInt32
(
nullptr
,
&
int32_val
),
false
);
EXPECT_EQ
(
CParcelReadInt32
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadInt32
(
parcel
,
&
int32_val
),
true
);
EXPECT_EQ
(
int32_val
,
static_cast
<
int32_t
>
(
NUMBER_CONSTANT
));
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInt64
* @tc.desc: Verify the CParcel for int32_t type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInt64
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
int64_t
int64_val
=
static_cast
<
int64_t
>
(
NUMBER_CONSTANT
);
EXPECT_EQ
(
CParcelWriteInt64
(
nullptr
,
int64_val
),
false
);
EXPECT_EQ
(
CParcelWriteInt64
(
parcel
,
int64_val
),
true
);
EXPECT_EQ
(
CParcelReadInt64
(
nullptr
,
&
int64_val
),
false
);
EXPECT_EQ
(
CParcelReadInt64
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadInt64
(
parcel
,
&
int64_val
),
true
);
EXPECT_EQ
(
int64_val
,
static_cast
<
int64_t
>
(
NUMBER_CONSTANT
));
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelFloat
* @tc.desc: Verify the CParcel for float type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelFloat
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
float
float_val
=
static_cast
<
float
>
(
FLOAT_CONSTANT
);
EXPECT_EQ
(
CParcelWriteFloat
(
nullptr
,
float_val
),
false
);
EXPECT_EQ
(
CParcelWriteFloat
(
parcel
,
float_val
),
true
);
EXPECT_EQ
(
CParcelReadFloat
(
nullptr
,
&
float_val
),
false
);
EXPECT_EQ
(
CParcelReadFloat
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadFloat
(
parcel
,
&
float_val
),
true
);
EXPECT_TRUE
(
abs
(
float_val
-
static_cast
<
float
>
(
FLOAT_CONSTANT
))
<
0.0001
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelDouble
* @tc.desc: Verify the CParcel for double type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelDouble
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
double
double_val
=
static_cast
<
double
>
(
FLOAT_CONSTANT
);
EXPECT_EQ
(
CParcelWriteDouble
(
nullptr
,
double_val
),
false
);
EXPECT_EQ
(
CParcelWriteDouble
(
parcel
,
double_val
),
true
);
EXPECT_EQ
(
CParcelReadDouble
(
nullptr
,
&
double_val
),
false
);
EXPECT_EQ
(
CParcelReadDouble
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadDouble
(
parcel
,
&
double_val
),
true
);
EXPECT_TRUE
(
abs
(
double_val
-
static_cast
<
double
>
(
FLOAT_CONSTANT
))
<
0.0001
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelString001
* @tc.desc: Verify the CParcel for string type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelString001
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelReadString
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorOk
),
false
);
EXPECT_EQ
(
CParcelWriteString
(
nullptr
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteString
(
parcel
,
nullptr
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteString
(
parcel
,
STRING_CONSTATN
,
-
1
),
false
);
EXPECT_EQ
(
CParcelWriteString
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
EXPECT_EQ
(
CParcelWriteString
(
parcel
,
nullptr
,
-
1
),
true
);
EXPECT_EQ
(
CParcelReadString
(
nullptr
,
reinterpret_cast
<
void
*>
(
&
data
),
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadString
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorOk
),
true
);
EXPECT_EQ
(
strncmp
((
reinterpret_cast
<
char
*>
(
data
)),
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
0
);
if
(
data
!=
nullptr
)
{
free
(
data
);
}
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelString002
* @tc.desc: Verify the CParcel for string type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelString002
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
EXPECT_EQ
(
CParcelWriteString
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelReadString
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorErr
),
false
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelString16001
* @tc.desc: Verify the CParcel for string16 type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelString16001
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelReadString16
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorOk
),
false
);
EXPECT_EQ
(
CParcelWriteString16
(
nullptr
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteString16
(
parcel
,
nullptr
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteString16
(
parcel
,
STRING_CONSTATN
,
-
1
),
false
);
EXPECT_EQ
(
CParcelWriteString16
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
EXPECT_EQ
(
CParcelWriteString16
(
parcel
,
nullptr
,
-
1
),
true
);
EXPECT_EQ
(
CParcelReadString16
(
nullptr
,
reinterpret_cast
<
void
*>
(
&
data
),
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadString16
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorOk
),
true
);
EXPECT_EQ
(
strncmp
((
reinterpret_cast
<
char
*>
(
data
)),
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
0
);
if
(
data
!=
nullptr
)
{
free
(
data
);
}
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelString16002
* @tc.desc: Verify the CParcel for string16 type functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelString16002
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
EXPECT_EQ
(
CParcelWriteString16
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelReadString16
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorErr
),
false
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInterfaceToken001
* @tc.desc: Verify the CParcel for interface token functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInterfaceToken001
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelWriteInterfaceToken
(
nullptr
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteInterfaceToken
(
parcel
,
nullptr
,
strlen
(
STRING_CONSTATN
)),
false
);
EXPECT_EQ
(
CParcelWriteInterfaceToken
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
EXPECT_EQ
(
CParcelReadInterfaceToken
(
nullptr
,
reinterpret_cast
<
void
*>
(
&
data
),
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadInterfaceToken
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorOk
),
true
);
EXPECT_EQ
(
strncmp
((
reinterpret_cast
<
char
*>
(
data
)),
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
0
);
if
(
data
!=
nullptr
)
{
free
(
data
);
}
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelInterfaceToken002
* @tc.desc: Verify the CParcel for interface token functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelInterfaceToken002
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
EXPECT_EQ
(
CParcelWriteInterfaceToken
(
parcel
,
STRING_CONSTATN
,
strlen
(
STRING_CONSTATN
)),
true
);
void
*
data
=
nullptr
;
EXPECT_EQ
(
CParcelReadInterfaceToken
(
parcel
,
reinterpret_cast
<
void
*>
(
&
data
),
CParcelBytesAllocatorErr
),
false
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelFileDescriptor
* @tc.desc: Verify the CParcel for file descriptor functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelFileDescriptor
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
int32_t
fd
=
open
(
"/dev/null"
,
O_RDONLY
);
EXPECT_TRUE
(
fd
>=
0
);
EXPECT_EQ
(
CParcelWriteFileDescriptor
(
nullptr
,
fd
),
false
);
EXPECT_EQ
(
CParcelWriteFileDescriptor
(
parcel
,
fd
),
true
);
int32_t
ret_fd
;
EXPECT_EQ
(
CParcelReadFileDescriptor
(
nullptr
,
&
ret_fd
),
false
);
EXPECT_EQ
(
CParcelReadFileDescriptor
(
parcel
,
nullptr
),
false
);
EXPECT_EQ
(
CParcelReadFileDescriptor
(
parcel
,
&
ret_fd
),
true
);
EXPECT_TRUE
(
ret_fd
>
0
);
close
(
fd
);
close
(
ret_fd
);
// destroy the CParcel object
CParcelDecStrongRef
(
parcel
);
}
/**
* @tc.name: CParcelDataInfoNullCheck
* @tc.desc: Verify the CParcel data info null check
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelDataInfoNullCheck
,
TestSize
.
Level1
)
{
EXPECT_EQ
(
CParcelGetDataSize
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelSetDataSize
(
nullptr
,
0
),
false
);
EXPECT_EQ
(
CParcelGetDataCapacity
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelSetDataCapacity
(
nullptr
,
0
),
false
);
EXPECT_EQ
(
CParcelGetMaxCapacity
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelSetMaxCapacity
(
nullptr
,
0
),
false
);
EXPECT_EQ
(
CParcelGetWritableBytes
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelGetReadableBytes
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelGetReadPosition
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelGetWritePosition
(
nullptr
),
0
);
EXPECT_EQ
(
CParcelRewindRead
(
nullptr
,
0
),
false
);
EXPECT_EQ
(
CParcelRewindWrite
(
nullptr
,
0
),
false
);
}
/**
* @tc.name: CParcelDataInfo
* @tc.desc: Verify the CParcel data info functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCMessageParcelUnitTest
,
CParcelDataInfo
,
TestSize
.
Level1
)
{
CParcel
*
parcel
=
CParcelObtain
();
EXPECT_NE
(
parcel
,
nullptr
);
uint32_t
maxCapacity
=
CParcelGetMaxCapacity
(
parcel
);
EXPECT_TRUE
(
maxCapacity
>
0
);
EXPECT_TRUE
(
CParcelSetMaxCapacity
(
parcel
,
maxCapacity
+
1
));
EXPECT_EQ
(
CParcelGetMaxCapacity
(
parcel
),
maxCapacity
+
1
);
EXPECT_EQ
(
CParcelGetDataSize
(
parcel
),
0
);
EXPECT_EQ
(
CParcelGetDataCapacity
(
parcel
),
0
);
EXPECT_EQ
(
CParcelGetWritableBytes
(
parcel
),
0
);
EXPECT_EQ
(
CParcelGetReadableBytes
(
parcel
),
0
);
EXPECT_EQ
(
CParcelGetReadPosition
(
parcel
),
0
);
EXPECT_EQ
(
CParcelGetWritePosition
(
parcel
),
0
);
EXPECT_TRUE
(
CParcelWriteInt32
(
parcel
,
0
));
uint32_t
dataSize
=
CParcelGetDataSize
(
parcel
);
EXPECT_TRUE
(
dataSize
>
0
);
EXPECT_TRUE
(
CParcelGetDataCapacity
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelGetWritableBytes
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelGetReadableBytes
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelGetReadPosition
(
parcel
)
==
0
);
EXPECT_TRUE
(
CParcelGetWritePosition
(
parcel
)
>
0
);
int32_t
value
;
EXPECT_TRUE
(
CParcelReadInt32
(
parcel
,
&
value
));
EXPECT_EQ
(
CParcelGetReadableBytes
(
parcel
),
0
);
EXPECT_TRUE
(
CParcelGetReadPosition
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelSetDataSize
(
parcel
,
dataSize
-
1
));
EXPECT_TRUE
(
CParcelSetDataCapacity
(
parcel
,
dataSize
+
1
));
EXPECT_TRUE
(
CParcelRewindRead
(
parcel
,
0
));
EXPECT_TRUE
(
CParcelRewindWrite
(
parcel
,
0
));
EXPECT_EQ
(
CParcelGetDataSize
(
parcel
),
0
);
EXPECT_TRUE
(
CParcelGetDataCapacity
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelGetWritableBytes
(
parcel
)
>
0
);
EXPECT_TRUE
(
CParcelGetReadableBytes
(
parcel
)
==
0
);
EXPECT_TRUE
(
CParcelGetReadPosition
(
parcel
)
==
0
);
EXPECT_TRUE
(
CParcelGetWritePosition
(
parcel
)
==
0
);
CParcelDecStrongRef
(
parcel
);
}
\ No newline at end of file
ipc/native/test/unittest/common/ipc_c_process_unittest.cpp
0 → 100644
浏览文件 @
268e9ce6
/*
* 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.
*/
#include <gtest/gtest.h>
#include <nativetoken_kit.h>
#include <token_setproc.h>
#include <unistd.h>
#include "c_process.h"
using
namespace
testing
::
ext
;
class
IpcCProcessUnitTest
:
public
testing
::
Test
{
public:
static
void
SetUpTestCase
(
void
);
static
void
TearDownTestCase
(
void
);
void
SetUp
();
void
TearDown
();
};
void
IpcCProcessUnitTest
::
SetUpTestCase
()
{}
void
IpcCProcessUnitTest
::
TearDownTestCase
()
{}
void
IpcCProcessUnitTest
::
SetUp
()
{}
void
IpcCProcessUnitTest
::
TearDown
()
{}
static
void
InitTokenId
(
void
)
{
uint64_t
tokenId
;
NativeTokenInfoParams
infoInstance
=
{
.
dcapsNum
=
0
,
.
permsNum
=
0
,
.
aclsNum
=
0
,
.
dcaps
=
NULL
,
.
perms
=
NULL
,
.
acls
=
NULL
,
.
processName
=
"com.ipc.test"
,
.
aplStr
=
"normal"
,
};
tokenId
=
GetAccessTokenId
(
&
infoInstance
);
SetSelfTokenID
(
tokenId
);
}
/**
* @tc.name: CProcessCallingInfo
* @tc.desc: Verify the CProcess calling info functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCProcessUnitTest
,
CProcessCallingInfo
,
TestSize
.
Level1
)
{
InitTokenId
();
uint64_t
selfTokenId
=
GetSelfToekenId
();
EXPECT_EQ
(
GetCallingTokenId
(),
selfTokenId
);
EXPECT_EQ
(
GetFirstToekenId
(),
0
);
EXPECT_EQ
(
GetCallingPid
(),
static_cast
<
uint64_t
>
(
getpid
()));
EXPECT_EQ
(
GetCallingUid
(),
static_cast
<
uint64_t
>
(
getuid
()));
}
\ No newline at end of file
ipc/native/test/unittest/common/ipc_c_remote_object_unittest.cpp
0 → 100644
浏览文件 @
268e9ce6
/*
* 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.
*/
#include <gtest/gtest.h>
#include "c_process.h"
#include "c_remote_object.h"
#include "c_remote_object_internal.h"
using
namespace
testing
::
ext
;
using
namespace
OHOS
;
static
const
uint32_t
DUMP_CODE
=
1598311760
;
static
const
char
*
SERVICE_NAME
=
"ohos.ipc.test"
;
class
IpcCRemoteObjectUnitTest
:
public
testing
::
Test
{
public:
static
void
SetUpTestCase
(
void
);
static
void
TearDownTestCase
(
void
);
void
SetUp
();
void
TearDown
();
};
void
IpcCRemoteObjectUnitTest
::
SetUpTestCase
()
{}
void
IpcCRemoteObjectUnitTest
::
TearDownTestCase
()
{}
void
IpcCRemoteObjectUnitTest
::
SetUp
()
{}
void
IpcCRemoteObjectUnitTest
::
TearDown
()
{}
static
int
OnRemoteRequest
(
const
CRemoteObject
*
stub
,
int
code
,
const
CParcel
*
data
,
CParcel
*
reply
)
{
(
void
)
stub
;
(
void
)
code
;
(
void
)
data
;
(
void
)
reply
;
return
0
;
}
static
void
OnRemoteObjectDestroy
(
const
void
*
userData
)
{
(
void
)
userData
;
}
static
void
OnDeathRecipient
(
const
void
*
userData
)
{
(
void
)
userData
;
}
static
void
OnDeathRecipientDestroy
(
const
void
*
userData
)
{
(
void
)
userData
;
}
/**
* @tc.name: CRemoteObjectRefCount
* @tc.desc: Verify the CRemoteObject reference count functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CRemoteObjectRefCount
,
TestSize
.
Level1
)
{
CRemoteObject
*
remote
=
CreateRemoteStub
(
nullptr
,
OnRemoteRequest
,
OnRemoteObjectDestroy
,
nullptr
);
EXPECT_EQ
(
remote
,
nullptr
);
remote
=
CreateRemoteStub
(
SERVICE_NAME
,
OnRemoteRequest
,
OnRemoteObjectDestroy
,
nullptr
);
EXPECT_NE
(
remote
,
nullptr
);
RefBase
*
ref
=
static_cast
<
RefBase
*>
(
remote
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
RemoteObjectIncStrongRef
(
remote
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
2
);
RemoteObjectDecStrongRef
(
remote
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
RemoteObjectIncStrongRef
(
nullptr
);
RemoteObjectDecStrongRef
(
nullptr
);
// destroy the CRemoteObject object
RemoteObjectDecStrongRef
(
remote
);
}
/**
* @tc.name: CRemoteObjectUserData
* @tc.desc: Verify the CRemoteObject user data function
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CRemoteObjectUserData
,
TestSize
.
Level1
)
{
EXPECT_EQ
(
RemoteObjectGetUserData
(
nullptr
),
nullptr
);
int8_t
userData
;
CRemoteObject
*
remote
=
CreateRemoteStub
(
SERVICE_NAME
,
OnRemoteRequest
,
OnRemoteObjectDestroy
,
&
userData
);
EXPECT_NE
(
remote
,
nullptr
);
EXPECT_EQ
(
RemoteObjectGetUserData
(
remote
),
&
userData
);
// destroy the CRemoteObject object
RemoteObjectDecStrongRef
(
remote
);
}
/**
* @tc.name: CRemoteObjectCompare
* @tc.desc: Verify the CRemoteObject less than function
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CRemoteObjectCompare
,
TestSize
.
Level1
)
{
int8_t
userData
;
CRemoteObject
*
remote
=
CreateRemoteStub
(
SERVICE_NAME
,
OnRemoteRequest
,
OnRemoteObjectDestroy
,
&
userData
);
EXPECT_NE
(
remote
,
nullptr
);
EXPECT_FALSE
(
RemoteObjectLessThan
(
nullptr
,
remote
));
EXPECT_FALSE
(
RemoteObjectLessThan
(
remote
,
nullptr
));
CRemoteObject
*
samgr1
=
GetContextManager
();
EXPECT_NE
(
samgr1
,
nullptr
);
CRemoteObject
*
samgr2
=
GetContextManager
();
EXPECT_NE
(
samgr2
,
nullptr
);
EXPECT_FALSE
(
RemoteObjectLessThan
(
samgr1
,
samgr2
));
EXPECT_FALSE
(
RemoteObjectLessThan
(
samgr2
,
samgr1
));
CRemoteObjectHolder
*
samgr
=
static_cast
<
CRemoteObjectHolder
*>
(
samgr1
);
CRemoteObjectHolder
*
holder
=
static_cast
<
CRemoteObjectHolder
*>
(
remote
);
if
(
samgr
->
remote_
.
GetRefPtr
()
<
holder
->
remote_
.
GetRefPtr
())
{
EXPECT_TRUE
(
RemoteObjectLessThan
(
samgr1
,
remote
));
}
else
{
EXPECT_FALSE
(
RemoteObjectLessThan
(
samgr1
,
remote
));
}
// destroy the CRemoteObject object
RemoteObjectDecStrongRef
(
remote
);
RemoteObjectDecStrongRef
(
samgr1
);
RemoteObjectDecStrongRef
(
samgr2
);
}
/**
* @tc.name: CRemoteObjectSendRequest
* @tc.desc: Verify the CRemoteObject sendRequest function
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CRemoteObjectSendRequest
,
TestSize
.
Level1
)
{
CRemoteObject
*
samgr
=
GetContextManager
();
EXPECT_NE
(
samgr
,
nullptr
);
CParcel
*
data
=
CParcelObtain
();
EXPECT_NE
(
data
,
nullptr
);
CParcel
*
reply
=
CParcelObtain
();
EXPECT_NE
(
reply
,
nullptr
);
EXPECT_NE
(
RemoteObjectSendRequest
(
nullptr
,
DUMP_CODE
,
data
,
reply
,
true
),
0
);
EXPECT_NE
(
RemoteObjectSendRequest
(
samgr
,
DUMP_CODE
,
nullptr
,
reply
,
true
),
0
);
EXPECT_NE
(
RemoteObjectSendRequest
(
samgr
,
DUMP_CODE
,
data
,
nullptr
,
true
),
0
);
EXPECT_EQ
(
RemoteObjectSendRequest
(
samgr
,
DUMP_CODE
,
data
,
reply
,
true
),
0
);
// destroy the CRemoteObject and CParcel object
RemoteObjectDecStrongRef
(
samgr
);
CParcelDecStrongRef
(
data
);
CParcelDecStrongRef
(
reply
);
}
/**
* @tc.name: CDeathRecipientRefCount
* @tc.desc: Verify the CDeathRecipient reference count function
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CDeathRecipientRefCount
,
TestSize
.
Level1
)
{
int8_t
userData
;
CDeathRecipient
*
recipient
=
CreateDeathRecipient
(
nullptr
,
OnDeathRecipientDestroy
,
&
userData
);
EXPECT_EQ
(
recipient
,
nullptr
);
recipient
=
CreateDeathRecipient
(
OnDeathRecipient
,
nullptr
,
&
userData
);
EXPECT_EQ
(
recipient
,
nullptr
);
recipient
=
CreateDeathRecipient
(
OnDeathRecipient
,
OnDeathRecipientDestroy
,
nullptr
);
EXPECT_EQ
(
recipient
,
nullptr
);
recipient
=
CreateDeathRecipient
(
OnDeathRecipient
,
OnDeathRecipientDestroy
,
&
userData
);
EXPECT_NE
(
recipient
,
nullptr
);
RefBase
*
ref
=
static_cast
<
RefBase
*>
(
recipient
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
DeathRecipientIncStrongRef
(
recipient
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
2
);
DeathRecipientDecStrongRef
(
recipient
);
EXPECT_EQ
(
ref
->
GetSptrRefCount
(),
1
);
DeathRecipientIncStrongRef
(
nullptr
);
DeathRecipientDecStrongRef
(
nullptr
);
// destroy the CDeathRecipient object
DeathRecipientDecStrongRef
(
recipient
);
}
/**
* @tc.name: CDeathRecipientStub
* @tc.desc: Verify the CDeathRecipient as stub functions
* @tc.type: FUNC
*/
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
);
EXPECT_NE
(
remote
,
nullptr
);
EXPECT_FALSE
(
AddDeathRecipient
(
remote
,
recipient
));
EXPECT_FALSE
(
RemoveDeathRecipient
(
remote
,
recipient
));
// destroy the CDeathRecipient object
DeathRecipientDecStrongRef
(
recipient
);
RemoteObjectDecStrongRef
(
remote
);
}
/**
* @tc.name: CDeathRecipient
* @tc.desc: Verify the CDeathRecipient functions
* @tc.type: FUNC
*/
HWTEST_F
(
IpcCRemoteObjectUnitTest
,
CDeathRecipient
,
TestSize
.
Level1
)
{
int8_t
userData
;
CDeathRecipient
*
recipient
=
CreateDeathRecipient
(
OnDeathRecipient
,
OnDeathRecipientDestroy
,
&
userData
);
EXPECT_NE
(
recipient
,
nullptr
);
CRemoteObject
*
samgr
=
GetContextManager
();
EXPECT_NE
(
samgr
,
nullptr
);
EXPECT_FALSE
(
AddDeathRecipient
(
nullptr
,
recipient
));
EXPECT_FALSE
(
AddDeathRecipient
(
samgr
,
nullptr
));
EXPECT_FALSE
(
RemoveDeathRecipient
(
nullptr
,
recipient
));
EXPECT_FALSE
(
RemoveDeathRecipient
(
samgr
,
nullptr
));
EXPECT_TRUE
(
AddDeathRecipient
(
samgr
,
recipient
));
EXPECT_TRUE
(
RemoveDeathRecipient
(
samgr
,
recipient
));
// destroy the CDeathRecipient object
DeathRecipientDecStrongRef
(
recipient
);
RemoteObjectDecStrongRef
(
samgr
);
}
\ No newline at end of file
ipc/native/test/unittest/rust/BUILD.gn
0 → 100644
浏览文件 @
268e9ce6
# 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.
import("//build/test.gni")
#################################group#########################################
group("unittest") {
testonly = true
deps = [
"client:rust_ipc_test_client",
"server:rust_ipc_test_server",
]
}
###############################################################################
i
nterfaces/innerkits/rust/tests
/client/BUILD.gn
→
i
pc/native/test/unittest/rust
/client/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -11,17 +11,22 @@
...
@@ -11,17 +11,22 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import("//build/
ohos
.gni")
import("//build/
test
.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
SUBSYSTEM_DIR = "//foundation/communication/ipc"
MODULE_OUTPUT_PATH = "ipc"
ohos_rust_test("rust_ipc_test_client") {
ohos_rust_unittest("rust_ipc_test_client") {
module_out_path = MODULE_OUTPUT_PATH
sources = [ "src/main.rs" ]
sources = [ "src/main.rs" ]
deps = [
deps = [
"$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust",
"$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust",
"$SUBSYSTEM_DIR/i
nterfaces/innerkits/rust/tests
/service:test_ipc_service",
"$SUBSYSTEM_DIR/i
pc/native/test/unittest/rust
/service:test_ipc_service",
]
]
resource_config_file =
"//foundation/communication/ipc/test/resource/ipc/ohos_test.xml"
subsystem_name = "communication"
subsystem_name = "communication"
part_name = "ipc"
part_name = "ipc"
}
}
i
nterfaces/innerkits/rust/tests
/client/src/main.rs
→
i
pc/native/test/unittest/rust
/client/src/main.rs
浏览文件 @
268e9ce6
...
@@ -18,15 +18,14 @@ extern crate test_ipc_service;
...
@@ -18,15 +18,14 @@ extern crate test_ipc_service;
use
std
::
thread
;
use
std
::
thread
;
use
std
::
time
::
Duration
;
use
std
::
time
::
Duration
;
use
std
::
io
::
Write
;
use
std
::
io
::
{
Read
,
SeekFrom
,
Seek
}
;
use
ipc_rust
::{
use
ipc_rust
::{
FromRemoteObj
,
DeathRecipient
,
IRemoteObj
,
FileDesc
,
RemoteObjRef
,
FromRemoteObj
,
DeathRecipient
,
IRemoteObj
,
FileDesc
,
RemoteObjRef
,
MsgParcel
,
String16
,
InterfaceToken
,
get_service
,
init_access_token
,
MsgParcel
,
String16
,
InterfaceToken
,
get_service
,
get_first_token_id
,
get_first_token_id
,
get_self_token_id
,
get_calling_pid
,
get_calling_uid
,
get_self_token_id
,
get_calling_pid
,
get_calling_uid
,
IMsgParcel
,
IMsgParcel
,
};
};
use
test_ipc_service
::{
ITest
,
IPC_TEST_SERVICE_ID
};
use
test_ipc_service
::{
ITest
,
TestProxy
,
IPC_TEST_SERVICE_ID
,
IFoo
,
init_access_token
};
use
std
::
fs
::
OpenOptions
;
use
std
::
fs
::
File
;
fn
get_test_service
()
->
RemoteObjRef
<
dyn
ITest
>
fn
get_test_service
()
->
RemoteObjRef
<
dyn
ITest
>
{
{
...
@@ -47,21 +46,6 @@ fn test_add_access_token() {
...
@@ -47,21 +46,6 @@ fn test_add_access_token() {
init_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
remote
=
get_test_service
();
for
_
i
in
1
..=
5
{
assert
!
(
remote
.request_concurent
(
false
));
assert
!
(
remote
.request_concurent
(
true
));
}
}
#[test]
#[test]
fn
test_death_recipient_001
()
{
fn
test_death_recipient_001
()
{
let
object
=
get_service
(
IPC_TEST_SERVICE_ID
)
.expect
(
"get itest service failed"
);
let
object
=
get_service
(
IPC_TEST_SERVICE_ID
)
.expect
(
"get itest service failed"
);
...
@@ -225,15 +209,84 @@ fn test_calling_info() {
...
@@ -225,15 +209,84 @@ fn test_calling_info() {
}
}
#[test]
#[test]
fn
test_
parcel_fd
()
{
fn
test_
sync_request
()
{
let
remote
=
get_test_service
();
let
remote
=
get_test_service
();
let
value
=
remote
.test_sync_transaction
(
2019
,
0
)
.expect
(
"should return reverse value"
);
assert_eq!
(
value
,
9102
);
}
let
path
=
"/data/test_fd"
;
#[test]
let
mut
value
=
OpenOptions
::
new
()
.read
(
true
)
fn
test_async_request
()
{
.write
(
true
)
let
remote
=
get_test_service
();
.create
(
true
)
remote
.test_async_transaction
(
2019
,
0
)
.expect
(
"should return reverse value"
);
.open
(
path
)
.expect
(
"create data failed"
);
}
let
file_content
=
"Rust IPC Pass FD"
;
write!
(
value
,
"{}"
,
file_content
);
#[test]
assert_eq!
(
remote
.pass_file
(
FileDesc
::
new
(
value
)),
file_content
);
fn
test_ping_service
()
{
let
remote
=
get_test_service
();
let
descriptor
=
String16
::
new
(
TestProxy
::
get_descriptor
());
remote
.test_ping_service
(
&
descriptor
)
.expect
(
"should success"
);
}
#[test]
fn
test_fd
()
{
let
remote
=
get_test_service
();
let
fd
:
FileDesc
=
remote
.test_transact_fd
()
.expect
(
"should return valied fd"
);
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
);
assert_eq!
(
info
,
"Sever write!
\n
"
);
}
#[test]
fn
test_loop_request
()
{
let
remote
=
get_test_service
();
// start loop test, test times is 1000
let
mut
value
=
String
::
new
();
for
_
i
in
1
..=
1000
{
value
.push_str
(
"0123456789abcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+{}?/[]<>-='|~"
);
let
len
=
remote
.test_transact_string
(
&
value
)
.expect
(
"should return value length"
);
assert_eq!
(
value
.len
()
as
i32
,
len
);
}
}
#[test]
fn
test_remote_obj
()
{
let
remote
=
get_test_service
();
let
remote
=
remote
.test_get_foo_service
()
.expect
(
"should return valid RemoteObj"
);
<
dyn
IFoo
as
FromRemoteObj
>
::
from
(
remote
)
.expect
(
"convert foo service should success"
);
}
#[test]
fn
test_parcel_buffer
(){
let
u8_slice
=
[
1u8
;
100
];
let
u8_slice
=
&
u8_slice
[
..
];
let
mut
parcel
=
MsgParcel
::
new
()
.expect
(
"create MsgParcel failed"
);
let
res
=
parcel
.write_buffer
(
u8_slice
);
assert_eq!
(
res
,
true
);
let
u8_vec
:
Vec
<
u8
>
=
parcel
.read_buffer
(
100
)
.expect
(
"read buffer failed"
);
assert_eq!
(
u8_vec
,
u8_slice
);
}
#[test]
fn
test_parcel_buffer_other
(){
let
u8_slice
=
[
1u8
;
100
];
let
u8_slice
=
&
u8_slice
[
..
];
let
mut
parcel
=
MsgParcel
::
new
()
.expect
(
"create MsgParcel failed"
);
let
res
=
parcel
.write_buffer
(
u8_slice
);
assert_eq!
(
res
,
true
);
let
u8_vec
=
parcel
.read_buffer
(
0
)
.expect
(
"read zero length buffer failed"
);
assert_eq!
(
u8_vec
.len
()
as
i32
,
0
);
}
#[test]
fn
test_parcel_ref
(){
let
s
=
"hello"
.to_string
();
let
mut
parcel
=
MsgParcel
::
new
()
.expect
(
"create MsgParcel failed"
);
parcel
.write
(
&
s
)
.expect
(
"write false failed"
);
let
res
:
String
=
parcel
.read
()
.expect
(
"read str failed"
);
assert_eq!
(
res
,
s
);
}
}
\ No newline at end of file
i
nterfaces/innerkits/rust/tests
/server/BUILD.gn
→
i
pc/native/test/unittest/rust
/server/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -19,7 +19,7 @@ ohos_rust_executable("rust_ipc_test_server") {
...
@@ -19,7 +19,7 @@ ohos_rust_executable("rust_ipc_test_server") {
sources = [ "src/main.rs" ]
sources = [ "src/main.rs" ]
deps = [
deps = [
"$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust",
"$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust",
"$SUBSYSTEM_DIR/i
nterfaces/innerkits/rust/tests
/service:test_ipc_service",
"$SUBSYSTEM_DIR/i
pc/native/test/unittest/rust
/service:test_ipc_service",
]
]
subsystem_name = "communication"
subsystem_name = "communication"
...
...
i
nterfaces/innerkits/rust/tests
/server/src/main.rs
→
i
pc/native/test/unittest/rust
/server/src/main.rs
浏览文件 @
268e9ce6
...
@@ -13,38 +13,76 @@
...
@@ -13,38 +13,76 @@
* limitations under the License.
* limitations under the License.
*/
*/
//! IPC test server
extern
crate
ipc_rust
;
extern
crate
ipc_rust
;
extern
crate
test_ipc_service
;
extern
crate
test_ipc_service
;
use
ipc_rust
::{
use
ipc_rust
::{
IRemoteBroker
,
join_work_thread
,
FileDesc
,
InterfaceToken
,
Result
,
IRemoteBroker
,
join_work_thread
,
FileDesc
,
InterfaceToken
,
Result
,
add_service
,
init_access_token
,
get_calling_token_id
,
get_first_token_
id
,
add_service
,
get_calling_token_id
,
get_first_token_id
,
get_calling_p
id
,
get_calling_
pid
,
get_calling_uid
,
get_calling_
uid
,
String16
,
RemoteObj
,
IRemoteStub
,
};
};
use
test_ipc_service
::{
ITest
,
TestStub
,
IPC_TEST_SERVICE_ID
};
use
test_ipc_service
::{
ITest
,
TestStub
,
IPC_TEST_SERVICE_ID
,
reverse
,
IFoo
,
FooStub
,
init_access_token
};
use
std
::
io
::{
Read
,
Seek
,
SeekFrom
};
use
std
::
io
::
Write
;
use
std
::
fs
::
File
;
use
std
::
fs
::
OpenOptions
;
use
std
::{
thread
,
time
};
/// FooService type
pub
struct
FooService
;
impl
IFoo
for
FooService
{
}
impl
IRemoteBroker
for
FooService
{
}
/// test.ipc.ITestService type
pub
struct
TestService
;
pub
struct
TestService
;
impl
ITest
for
TestService
{
impl
ITest
for
TestService
{
fn
echo_str
(
&
self
,
value
:
&
str
)
->
String
{
fn
test_sync_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
i32
>
{
println!
(
"TestService echo_str: {}"
,
value
);
if
delay_time
>
0
{
String
::
from
(
value
)
thread
::
sleep
(
time
::
Duration
::
from_millis
(
delay_time
as
u64
));
}
Ok
(
reverse
(
value
))
}
fn
test_async_transaction
(
&
self
,
_
value
:
i32
,
delay_time
:
i32
)
->
Result
<
()
>
{
if
delay_time
>
0
{
thread
::
sleep
(
time
::
Duration
::
from_millis
(
delay_time
as
u64
));
}
Ok
(())
}
fn
test_ping_service
(
&
self
,
service_name
:
&
String16
)
->
Result
<
()
>
{
let
name
=
service_name
.get_string
();
println!
(
"test_ping_service recv service name: {}"
,
name
);
if
name
==
TestStub
::
get_descriptor
()
{
Ok
(())
}
else
{
Err
(
-
1
)
}
}
fn
test_transact_fd
(
&
self
)
->
Result
<
FileDesc
>
{
let
path
=
"/data/test.txt"
;
let
mut
value
=
OpenOptions
::
new
()
.read
(
true
)
.write
(
true
)
.create
(
true
)
.open
(
path
)
.expect
(
"create /data/test.txt failed"
);
let
file_content
=
"Sever write!
\n
"
;
write!
(
value
,
"{}"
,
file_content
)
.expect
(
"write file success"
);
Ok
(
FileDesc
::
new
(
value
))
}
}
fn
request_concurent
(
&
self
,
is_async
:
bool
)
->
bool
{
fn
test_transact_string
(
&
self
,
value
:
&
str
)
->
Result
<
i32
>
{
println!
(
"TestService request_concurent: {}"
,
is_async
);
Ok
(
value
.len
()
as
i32
)
true
}
}
fn
pass_file
(
&
self
,
fd
:
FileDesc
)
->
String
{
fn
test_get_foo_service
(
&
self
)
->
Result
<
RemoteObj
>
{
let
mut
info
=
String
::
new
();
let
service
=
FooStub
::
new_remote_stub
(
FooService
)
.expect
(
"create FooService success"
);
let
mut
file
=
File
::
from
(
fd
);
Ok
(
service
.as_object
()
.expect
(
"get a RemoteObj success"
))
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
>
{
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
{
...
@@ -68,7 +106,7 @@ fn main() {
...
@@ -68,7 +106,7 @@ fn main() {
// create stub
// create stub
let
service
=
TestStub
::
new_remote_stub
(
TestService
)
.expect
(
"create TestService success"
);
let
service
=
TestStub
::
new_remote_stub
(
TestService
)
.expect
(
"create TestService success"
);
add_service
(
&
service
.as_object
()
.expect
(
"get ITest service failed"
),
add_service
(
&
service
.as_object
()
.expect
(
"get ITest service failed"
),
IPC_TEST_SERVICE_ID
);
IPC_TEST_SERVICE_ID
)
.expect
(
"add server to samgr failed"
)
;
println!
(
"join to ipc work thread"
);
println!
(
"join to ipc work thread"
);
join_work_thread
();
join_work_thread
();
}
}
\ No newline at end of file
i
nterfaces/innerkits/rust/tests
/service/BUILD.gn
→
i
pc/native/test/unittest/rust
/service/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -16,9 +16,16 @@ import("//build/ohos.gni")
...
@@ -16,9 +16,16 @@ import("//build/ohos.gni")
SUBSYSTEM_DIR = "//foundation/communication/ipc"
SUBSYSTEM_DIR = "//foundation/communication/ipc"
ohos_rust_shared_library("test_ipc_service") {
ohos_rust_shared_library("test_ipc_service") {
sources = [ "src/lib.rs" ]
sources = [
"src/access_token.rs",
"src/lib.rs",
]
deps = [ "$SUBSYSTEM_DIR/interfaces/innerkits/rust:ipc_rust" ]
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",
]
crate_name = "test_ipc_service"
crate_name = "test_ipc_service"
crate_type = "dylib"
crate_type = "dylib"
...
...
ipc/native/test/unittest/rust/service/src/access_token.rs
0 → 100644
浏览文件 @
268e9ce6
/*
* 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.
*/
//! This crate implements the accesstoken init function FFI binding.
use
std
::
ptr
;
use
std
::
ffi
::
c_char
;
#[repr(C)]
struct
TokenInfoParams
{
dcaps_num
:
i32
,
perms_num
:
i32
,
acls_num
:
i32
,
dcaps
:
*
const
*
const
c_char
,
perms
:
*
const
*
const
c_char
,
acls
:
*
const
*
const
c_char
,
process_name
:
*
const
c_char
,
apl_str
:
*
const
c_char
,
}
extern
"C"
{
fn
GetAccessTokenId
(
tokenInfo
:
*
mut
TokenInfoParams
)
->
u64
;
fn
SetSelfTokenID
(
tokenID
:
u64
)
->
i32
;
}
/// Init access token ID for current process
pub
fn
init_access_token
()
{
let
mut
param
=
TokenInfoParams
{
dcaps_num
:
0
,
perms_num
:
0
,
acls_num
:
0
,
dcaps
:
ptr
::
null
(),
perms
:
ptr
::
null
(),
acls
:
ptr
::
null
(),
process_name
:
"com.ipc.test"
.as_ptr
(),
apl_str
:
"normal"
.as_ptr
(),
};
unsafe
{
let
token_id
=
GetAccessTokenId
(
&
mut
param
as
*
mut
TokenInfoParams
);
SetSelfTokenID
(
token_id
);
}
}
\ No newline at end of file
i
nterfaces/innerkits/rust/tests
/service/src/lib.rs
→
i
pc/native/test/unittest/rust
/service/src/lib.rs
浏览文件 @
268e9ce6
...
@@ -13,63 +13,121 @@
...
@@ -13,63 +13,121 @@
* limitations under the License.
* limitations under the License.
*/
*/
//! This create implement the IPC proxy and stub for "test.ipc.ITestService"
extern
crate
ipc_rust
;
extern
crate
ipc_rust
;
// Import types
mod
access_token
;
// use std::convert::{TryFrom, TryInto};
use
ipc_rust
::{
use
ipc_rust
::{
IRemoteBroker
,
IRemoteObj
,
RemoteStub
,
Result
,
IRemoteBroker
,
IRemoteObj
,
RemoteStub
,
Result
,
RemoteObj
,
define_remote_object
,
FIRST_CALL_TRANSACTION
RemoteObj
,
define_remote_object
,
FIRST_CALL_TRANSACTION
};
};
use
ipc_rust
::{
use
ipc_rust
::{
MsgParcel
,
BorrowedMsgParcel
,
FileDesc
,
InterfaceToken
,
MsgParcel
,
BorrowedMsgParcel
,
FileDesc
,
InterfaceToken
,
String16
,
};
};
pub
use
access_token
::
init_access_token
;
/// Reverse a i32 value, for example reverse 2019 to 9102
pub
fn
reverse
(
mut
value
:
i32
)
->
i32
{
let
mut
result
=
0
;
let
decimal
=
10
;
while
value
!=
0
{
result
=
result
*
decimal
+
value
%
decimal
;
value
/=
decimal
;
}
result
}
/// SA ID for "test.ipc.ITestService"
pub
const
IPC_TEST_SERVICE_ID
:
i32
=
1118
;
pub
const
IPC_TEST_SERVICE_ID
:
i32
=
1118
;
/// Function code of ITestService
pub
enum
ITestCode
{
pub
enum
ITestCode
{
CodeEchoStr
=
FIRST_CALL_TRANSACTION
,
/// Sync transaction code
CodeRequestConcurrent
=
2
,
CodeSyncTransaction
=
FIRST_CALL_TRANSACTION
,
CodePassFd
=
3
,
/// Async transaction code
CodeInterfaceToekn
=
4
,
CodeAsyncTransaction
,
CodeCallingInfo
=
5
,
/// Ping transaction code
CodePingService
,
/// Get FooService IPC object transaction code
CodeGetFooService
,
/// Transaction file descriptor code
CodeTransactFd
,
/// Transaction string code
CodeTransactString
,
/// Transaction Interface token code
CodeInterfaceToekn
,
/// Transaction calling infomation code
CodeCallingInfo
,
}
}
/// Function between proxy and stub of ITestService
pub
trait
ITest
:
IRemoteBroker
{
pub
trait
ITest
:
IRemoteBroker
{
fn
echo_str
(
&
self
,
value
:
&
str
)
->
String
;
/// Test sync transaction
fn
request_concurent
(
&
self
,
is_async
:
bool
)
->
bool
;
fn
test_sync_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
i32
>
;
fn
pass_file
(
&
self
,
fd
:
FileDesc
)
->
String
;
/// Test async transaction
fn
test_async_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
()
>
;
/// Test ping service transaction
fn
test_ping_service
(
&
self
,
service_name
:
&
String16
)
->
Result
<
()
>
;
/// Test file descriptor transaction
fn
test_transact_fd
(
&
self
)
->
Result
<
FileDesc
>
;
/// Test string transaction
fn
test_transact_string
(
&
self
,
value
:
&
str
)
->
Result
<
i32
>
;
/// Test get foo service IPC object transaction
fn
test_get_foo_service
(
&
self
)
->
Result
<
RemoteObj
>
;
/// Test interface token transaction
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
;
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
;
/// Test calling infomation transaction
fn
echo_calling_info
(
&
self
)
->
Result
<
(
u64
,
u64
,
u64
,
u64
)
>
;
fn
echo_calling_info
(
&
self
)
->
Result
<
(
u64
,
u64
,
u64
,
u64
)
>
;
}
}
fn
on_remote_request
(
stub
:
&
dyn
ITest
,
code
:
u32
,
data
:
&
BorrowedMsgParcel
,
fn
on_
itest_
remote_request
(
stub
:
&
dyn
ITest
,
code
:
u32
,
data
:
&
BorrowedMsgParcel
,
reply
:
&
mut
BorrowedMsgParcel
)
->
Result
<
()
>
{
reply
:
&
mut
BorrowedMsgParcel
)
->
Result
<
()
>
{
println!
(
"on_remote_reuqest in Rust TestStub, code: {}"
,
code
);
println!
(
"on_remote_reuqest in Rust TestStub, code: {}"
,
code
);
match
code
{
match
code
{
1
=>
{
1
=>
{
let
value
:
String
=
data
.read
()
.expect
(
"should have a string"
);
let
value
:
i32
=
data
.read
()
.expect
(
"should a value"
);
let
value
=
stub
.echo_str
(
&
value
);
let
delay_time
:
i32
=
data
.read
()
.expect
(
"should a delay time"
);
reply
.write
(
&
value
);
let
ret
=
stub
.test_sync_transaction
(
value
,
delay_time
)
?
;
reply
.write
(
&
ret
)
?
;
Ok
(())
Ok
(())
}
}
2
=>
{
2
=>
{
stub
.request_concurent
(
true
);
let
value
:
i32
=
data
.read
()
.expect
(
"should a value"
);
let
delay_time
:
i32
=
data
.read
()
.expect
(
"should a delay time"
);
stub
.test_async_transaction
(
value
,
delay_time
)
?
;
Ok
(())
Ok
(())
}
}
3
=>
{
3
=>
{
let
fd
:
FileDesc
=
data
.read
()
.expect
(
"should have a fd"
);
let
service_name
:
String16
=
data
.read
()
.expect
(
"should a service name"
);
let
value
=
stub
.pass_file
(
fd
);
stub
.test_ping_service
(
&
service_name
)
?
;
reply
.write
(
&
value
);
Ok
(())
Ok
(())
}
}
4
=>
{
4
=>
{
let
service
=
stub
.test_get_foo_service
()
?
;
reply
.write
(
&
service
)
?
;
Ok
(())
}
5
=>
{
let
fd
=
stub
.test_transact_fd
()
?
;
reply
.write
(
&
fd
)
.expect
(
"should write fd success"
);
Ok
(())
}
6
=>
{
let
value
:
String
=
data
.read
()
?
;
let
len
=
stub
.test_transact_string
(
&
value
)
?
;
reply
.write
(
&
len
)
?
;
Ok
(())
}
7
=>
{
let
token
:
InterfaceToken
=
data
.read
()
.expect
(
"should have a interface token"
);
let
token
:
InterfaceToken
=
data
.read
()
.expect
(
"should have a interface token"
);
let
value
=
stub
.echo_interface_token
(
&
token
)
.expect
(
"service deal echo token failed"
);
let
value
=
stub
.echo_interface_token
(
&
token
)
.expect
(
"service deal echo token failed"
);
reply
.write
(
&
value
)
.expect
(
"write echo token result failed"
);
reply
.write
(
&
value
)
.expect
(
"write echo token result failed"
);
Ok
(())
Ok
(())
}
}
5
=>
{
8
=>
{
let
(
token_id
,
first_token_id
,
pid
,
uid
)
=
stub
.echo_calling_info
()
?
;
let
(
token_id
,
first_token_id
,
pid
,
uid
)
=
stub
.echo_calling_info
()
?
;
reply
.write
(
&
token_id
)
.expect
(
"write token id failed"
);
reply
.write
(
&
token_id
)
.expect
(
"write token id failed"
);
reply
.write
(
&
first_token_id
)
.expect
(
"write first token id failed"
);
reply
.write
(
&
first_token_id
)
.expect
(
"write first token id failed"
);
...
@@ -82,26 +140,36 @@ fn on_remote_request(stub: &dyn ITest, code: u32, data: &BorrowedMsgParcel,
...
@@ -82,26 +140,36 @@ fn on_remote_request(stub: &dyn ITest, code: u32, data: &BorrowedMsgParcel,
}
}
define_remote_object!
(
define_remote_object!
(
ITest
[
"
ohos.ipc.test
"
]
{
ITest
[
"
test.ipc.ITestService
"
]
{
stub
:
TestStub
(
on_remote_request
),
stub
:
TestStub
(
on_
itest_
remote_request
),
proxy
:
TestProxy
,
proxy
:
TestProxy
,
}
}
);
);
// Make RemoteStub<TestStub> object can call ITest function directly.
// Make RemoteStub<TestStub> object can call ITest function directly.
impl
ITest
for
RemoteStub
<
TestStub
>
{
impl
ITest
for
RemoteStub
<
TestStub
>
{
fn
echo_str
(
&
self
,
value
:
&
str
)
->
String
{
fn
test_sync_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
i32
>
{
// self will be convert to TestStub automatic because RemoteStub<TestStub>
self
.0
.test_sync_transaction
(
value
,
delay_time
)
// implement the Deref trait
}
self
.0
.echo_str
(
value
)
fn
test_async_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
()
>
{
self
.0
.test_async_transaction
(
value
,
delay_time
)
}
fn
test_ping_service
(
&
self
,
service_name
:
&
String16
)
->
Result
<
()
>
{
self
.0
.test_ping_service
(
service_name
)
}
fn
test_transact_fd
(
&
self
)
->
Result
<
FileDesc
>
{
self
.0
.test_transact_fd
()
}
}
fn
request_concurent
(
&
self
,
is_async
:
bool
)
->
bool
{
fn
test_transact_string
(
&
self
,
value
:
&
str
)
->
Result
<
i32
>
{
self
.0
.
request_concurent
(
is_async
)
self
.0
.
test_transact_string
(
value
)
}
}
fn
pass_file
(
&
self
,
fd
:
FileDesc
)
->
String
{
fn
test_get_foo_service
(
&
self
)
->
Result
<
RemoteObj
>
{
self
.0
.
pass_file
(
fd
)
self
.0
.
test_get_foo_service
(
)
}
}
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
{
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
{
...
@@ -114,46 +182,56 @@ impl ITest for RemoteStub<TestStub> {
...
@@ -114,46 +182,56 @@ impl ITest for RemoteStub<TestStub> {
}
}
impl
ITest
for
TestProxy
{
impl
ITest
for
TestProxy
{
fn
echo_str
(
&
self
,
value
:
&
str
)
->
String
{
fn
test_sync_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
i32
>
{
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
data
.write
(
value
);
data
.write
(
&
value
)
?
;
let
reply
=
data
.write
(
&
delay_time
)
?
;
self
.remote
.send_request
(
ITestCode
::
CodeEchoStr
as
u32
,
&
data
,
false
);
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeSyncTransaction
as
u32
,
match
reply
{
&
data
,
false
)
?
;
Ok
(
reply
)
=>
{
let
ret
:
i32
=
reply
.read
()
.expect
(
"need reply i32"
);
let
echo_value
:
String
=
reply
.read
()
.expect
(
"need reply value"
);
Ok
(
ret
)
echo_value
}
Err
(
_
)
=>
{
String
::
from
(
"Error"
)
}
}
}
}
fn
request_concurent
(
&
self
,
is_async
:
bool
)
->
bool
{
fn
test_async_transaction
(
&
self
,
value
:
i32
,
delay_time
:
i32
)
->
Result
<
()
>
{
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
reply
=
data
.write
(
&
value
)
?
;
self
.remote
.send_request
(
ITestCode
::
CodeRequestConcurrent
as
u32
,
&
data
,
is_async
);
data
.write
(
&
delay_time
)
?
;
match
reply
{
let
_
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeAsyncTransaction
as
u32
,
Ok
(
_
)
=>
true
,
&
data
,
true
)
?
;
Err
(
_
)
=>
false
Ok
(())
}
}
}
fn
pass_file
(
&
self
,
fd
:
FileDesc
)
->
String
{
fn
test_ping_service
(
&
self
,
service_name
:
&
String16
)
->
Result
<
()
>
{
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
data
.write
(
&
fd
)
.expect
(
"write fd should success"
);
data
.write
(
service_name
)
?
;
let
reply
=
let
_
reply
=
self
.remote
.send_request
(
ITestCode
::
CodePingService
as
u32
,
self
.remote
.send_request
(
ITestCode
::
CodePassFd
as
u32
,
&
data
,
false
);
&
data
,
false
)
?
;
match
reply
{
Ok
(())
Ok
(
reply
)
=>
{
let
echo_value
:
String
=
reply
.read
()
.expect
(
"need reply value"
);
echo_value
}
}
Err
(
_
)
=>
{
String
::
from
(
"Error"
)
fn
test_transact_fd
(
&
self
)
->
Result
<
FileDesc
>
{
let
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeTransactFd
as
u32
,
&
data
,
false
)
?
;
let
fd
:
FileDesc
=
reply
.read
()
?
;
Ok
(
fd
)
}
}
fn
test_transact_string
(
&
self
,
value
:
&
str
)
->
Result
<
i32
>
{
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
data
.write
(
value
)
.expect
(
"should write string success"
);
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeTransactString
as
u32
,
&
data
,
false
)
?
;
let
len
:
i32
=
reply
.read
()
?
;
Ok
(
len
)
}
}
fn
test_get_foo_service
(
&
self
)
->
Result
<
RemoteObj
>
{
let
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeGetFooService
as
u32
,
&
data
,
false
)
?
;
let
service
:
RemoteObj
=
reply
.read
()
?
;
Ok
(
service
)
}
}
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
{
fn
echo_interface_token
(
&
self
,
token
:
&
InterfaceToken
)
->
Result
<
InterfaceToken
>
{
...
@@ -166,7 +244,7 @@ impl ITest for TestProxy {
...
@@ -166,7 +244,7 @@ impl ITest for TestProxy {
}
}
fn
echo_calling_info
(
&
self
)
->
Result
<
(
u64
,
u64
,
u64
,
u64
)
>
{
fn
echo_calling_info
(
&
self
)
->
Result
<
(
u64
,
u64
,
u64
,
u64
)
>
{
let
mut
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
data
=
MsgParcel
::
new
()
.expect
(
"MsgParcel should success"
);
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeCallingInfo
as
u32
,
let
reply
=
self
.remote
.send_request
(
ITestCode
::
CodeCallingInfo
as
u32
,
&
data
,
false
)
?
;
&
data
,
false
)
?
;
let
token_id
:
u64
=
reply
.read
()
.expect
(
"need reply calling token id"
);
let
token_id
:
u64
=
reply
.read
()
.expect
(
"need reply calling token id"
);
...
@@ -176,3 +254,25 @@ impl ITest for TestProxy {
...
@@ -176,3 +254,25 @@ impl ITest for TestProxy {
Ok
((
token_id
,
first_token_id
,
pid
,
uid
))
Ok
((
token_id
,
first_token_id
,
pid
,
uid
))
}
}
}
}
/// Interface trait for FooService
pub
trait
IFoo
:
IRemoteBroker
{
}
fn
on_foo_remote_request
(
_
stub
:
&
dyn
IFoo
,
_
code
:
u32
,
_
data
:
&
BorrowedMsgParcel
,
_
reply
:
&
mut
BorrowedMsgParcel
)
->
Result
<
()
>
{
Ok
(())
}
impl
IFoo
for
RemoteStub
<
FooStub
>
{
}
impl
IFoo
for
FooProxy
{
}
define_remote_object!
(
IFoo
[
"ohos.ipc.test.foo"
]
{
stub
:
FooStub
(
on_foo_remote_request
),
proxy
:
FooProxy
,
}
);
\ No newline at end of file
ipc/test/auxiliary/native/BUILD.gn
浏览文件 @
268e9ce6
...
@@ -61,7 +61,11 @@ ohos_executable("ipc_server_test") {
...
@@ -61,7 +61,11 @@ ohos_executable("ipc_server_test") {
"$IPC_TEST_ROOT:ipc_test_config",
"$IPC_TEST_ROOT:ipc_test_config",
]
]
deps = [ ":ipc_test_helper" ]
deps = [
":ipc_test_helper",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
]
external_deps = [
external_deps = [
"c_utils:utils",
"c_utils:utils",
...
@@ -82,7 +86,11 @@ ohos_executable("ipc_client_test") {
...
@@ -82,7 +86,11 @@ ohos_executable("ipc_client_test") {
"$IPC_TEST_ROOT:ipc_test_config",
"$IPC_TEST_ROOT:ipc_test_config",
]
]
deps = [ ":ipc_test_helper" ]
deps = [
":ipc_test_helper",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
]
external_deps = [
external_deps = [
"c_utils:utils",
"c_utils:utils",
...
@@ -142,7 +150,11 @@ ohos_executable("ipc_server_test_extra") {
...
@@ -142,7 +150,11 @@ ohos_executable("ipc_server_test_extra") {
"$IPC_TEST_ROOT:ipc_test_config",
"$IPC_TEST_ROOT:ipc_test_config",
]
]
deps = [ ":ipc_test_helper_extra" ]
deps = [
":ipc_test_helper_extra",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
]
external_deps = [
external_deps = [
"c_utils:utils",
"c_utils:utils",
...
...
ipc/test/auxiliary/native/src/main_client.cpp
浏览文件 @
268e9ce6
...
@@ -26,11 +26,30 @@
...
@@ -26,11 +26,30 @@
#include "test_service_skeleton.h"
#include "test_service_skeleton.h"
#include "if_system_ability_manager.h"
#include "if_system_ability_manager.h"
#include "log_tags.h"
#include "log_tags.h"
#include <nativetoken_kit.h>
#include <token_setproc.h>
using
namespace
OHOS
;
using
namespace
OHOS
;
using
namespace
OHOS
::
HiviewDFX
;
using
namespace
OHOS
::
HiviewDFX
;
static
constexpr
HiLogLabel
LABEL
=
{
LOG_CORE
,
LOG_ID_IPC
,
"IPCTestClient"
};
static
constexpr
HiLogLabel
LABEL
=
{
LOG_CORE
,
LOG_ID_IPC
,
"IPCTestClient"
};
static
void
InitTokenId
(
void
)
{
uint64_t
tokenId
;
NativeTokenInfoParams
infoInstance
=
{
.
dcapsNum
=
0
,
.
permsNum
=
0
,
.
aclsNum
=
0
,
.
dcaps
=
NULL
,
.
perms
=
NULL
,
.
acls
=
NULL
,
.
processName
=
"com.ipc.test"
,
.
aplStr
=
"normal"
,
};
tokenId
=
GetAccessTokenId
(
&
infoInstance
);
SetSelfTokenID
(
tokenId
);
}
std
::
vector
<
std
::
string
>
GetArgvOptions
(
int
argc
,
char
**
argv
)
std
::
vector
<
std
::
string
>
GetArgvOptions
(
int
argc
,
char
**
argv
)
{
{
std
::
vector
<
std
::
string
>
argvOptions
;
std
::
vector
<
std
::
string
>
argvOptions
;
...
@@ -42,6 +61,7 @@ std::vector<std::string> GetArgvOptions(int argc, char **argv)
...
@@ -42,6 +61,7 @@ std::vector<std::string> GetArgvOptions(int argc, char **argv)
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
InitTokenId
();
int
result
=
0
;
int
result
=
0
;
TestCommand
commandId
=
TestCommand
::
TEST_CMD_SYNC_TRANS
;
TestCommand
commandId
=
TestCommand
::
TEST_CMD_SYNC_TRANS
;
if
(
argc
>
1
)
{
if
(
argc
>
1
)
{
...
...
ipc/test/auxiliary/native/src/main_server.cpp
浏览文件 @
268e9ce6
...
@@ -17,14 +17,34 @@
...
@@ -17,14 +17,34 @@
#include "ipc_skeleton.h"
#include "ipc_skeleton.h"
#include "test_service.h"
#include "test_service.h"
#include "log_tags.h"
#include "log_tags.h"
#include <nativetoken_kit.h>
#include <token_setproc.h>
using
namespace
OHOS
;
using
namespace
OHOS
;
using
namespace
OHOS
::
HiviewDFX
;
using
namespace
OHOS
::
HiviewDFX
;
[[
maybe_unused
]]
static
constexpr
HiLogLabel
LABEL
=
{
LOG_CORE
,
LOG_ID_IPC
,
"IPCTestServer"
};
[[
maybe_unused
]]
static
constexpr
HiLogLabel
LABEL
=
{
LOG_CORE
,
LOG_ID_IPC
,
"IPCTestServer"
};
static
void
InitTokenId
(
void
)
{
uint64_t
tokenId
;
NativeTokenInfoParams
infoInstance
=
{
.
dcapsNum
=
0
,
.
permsNum
=
0
,
.
aclsNum
=
0
,
.
dcaps
=
NULL
,
.
perms
=
NULL
,
.
acls
=
NULL
,
.
processName
=
"com.ipc.test"
,
.
aplStr
=
"normal"
,
};
tokenId
=
GetAccessTokenId
(
&
infoInstance
);
SetSelfTokenID
(
tokenId
);
}
int
main
(
int
argc
__attribute__
((
unused
)),
char
**
argv
__attribute__
((
unused
)))
int
main
(
int
argc
__attribute__
((
unused
)),
char
**
argv
__attribute__
((
unused
)))
{
{
InitTokenId
();
TestService
::
Instantiate
();
TestService
::
Instantiate
();
ZLOGD
(
LABEL
,
"call StartThreadPool"
);
ZLOGD
(
LABEL
,
"call StartThreadPool"
);
IPCSkeleton
::
JoinWorkThread
();
IPCSkeleton
::
JoinWorkThread
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录