diff --git a/interfaces/innerkits/rust/BUILD.gn b/interfaces/innerkits/rust/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..31560becb44f16910e7699d9daa9a448e3270a26 --- /dev/null +++ b/interfaces/innerkits/rust/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright (C) 2023 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/ohos.gni") + +ohos_rust_shared_library("rust_samgr") { + sources = [ + "src/lib.rs", + "src/rust_samgr.rs", + ] + + deps = [ + "//base/hiviewdfx/hilog/interfaces/rust:hilog_rust", + "//foundation/communication/ipc/interfaces/innerkits/rust:ipc_rust", + ] + crate_name = "rust_samgr" + crate_type = "dylib" + + install_images = [ system_base_dir ] + relative_install_dir = "chipset-pub-sdk" + subsystem_name = "systemabilitymgr" + part_name = "samgr" +} diff --git a/interfaces/innerkits/rust/src/lib.rs b/interfaces/innerkits/rust/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..112ae57287d8d1bfa9307aed56d7275a03cddc7b --- /dev/null +++ b/interfaces/innerkits/rust/src/lib.rs @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 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. + */ + +//! Safe Rust interface to OHOS samgr + mod rust_samgr; + + // Export types of this crate + pub use crate::rust_samgr::{SAExtraProp, get_samgr_proxy}; diff --git a/interfaces/innerkits/rust/src/rust_samgr.rs b/interfaces/innerkits/rust/src/rust_samgr.rs new file mode 100644 index 0000000000000000000000000000000000000000..13c850a36dc50c03cdd9af41bccade750822fca1 --- /dev/null +++ b/interfaces/innerkits/rust/src/rust_samgr.rs @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2023 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. + */ + +extern crate ipc_rust; +use ipc_rust::{ + IRemoteObj, RemoteObjRef, FromRemoteObj, IRemoteBroker, MsgParcel, RemoteObj, InterfaceToken, String16, Result, get_context_object +}; +use std::ffi::{c_char, CString}; +use std::default::Default; +use hilog_rust::{info, error, hilog, HiLogLabel, LogType}; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xd003200, + tag: "rustSA" +}; + +pub enum ISystemAbilityManagerCode { + /// get systemability code + CodeGetSystemAbility = 2, + /// add systemability code + CodeAddSystemAbility = 3, +} + +/// SAExtraProp is used to add_service +pub struct SAExtraProp { + /// Set whether SA is distributed + pub is_distributed: bool, + /// Additional parameters for SA, default is 8 + pub dump_flags: u32, + /// Additional parameters for SA, default is "" + pub capability: String16, + /// Additional parameters for SA, default is "" + pub permission: String16, +} + +impl Default for SAExtraProp { + fn default() -> SAExtraProp { + SAExtraProp { + is_distributed: false, + dump_flags: 8, + capability: String16::new(""), + permission: String16::new(""), + } + } +} + +/// samgr interface +pub trait ISystemAbilityManager: IRemoteBroker { + /// add_service + fn add_service(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> Result<()>; + /// get_service + fn get_service(&self, said: i32) -> Result; +} + +impl FromRemoteObj for dyn ISystemAbilityManager { + /// For example, convert RemoteObj to RemoteObjRef + fn from(object: RemoteObj) -> Result> { + Ok(RemoteObjRef::new(Box::new(SamgrProxy::from_remote_object(object)?))) + } +} + +/// get_samgr_handler +pub fn get_samgr_proxy() -> RemoteObjRef +{ + let object = get_context_object().expect("samgr is null"); + let remote = ::from(object); + let remote = match remote { + Ok(x) => x, + Err(error) => { + error!(LOG_LABEL, "convert RemoteObj to SamgrProxy failed: {}", error); + panic!(); + } + }; + remote +} + +/// define rust samgr proxy +pub struct SamgrProxy { + remote: RemoteObj, +} + +impl SamgrProxy { + fn from_remote_object(remote: RemoteObj) -> Result { + Ok(Self {remote}) + } +} + +impl IRemoteBroker for SamgrProxy { + /// Get Remote object from proxy + fn as_object(&self) -> Option { + Some(self.remote.clone()) + } +} + +impl ISystemAbilityManager for SamgrProxy { + fn add_service(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> Result<()> + { + let mut data = MsgParcel::new().expect("MsgParcel is null"); + data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?; + data.write(&said)?; + data.write(service)?; + data.write(&extra_prop.is_distributed)?; + data.write(&extra_prop.dump_flags)?; + data.write(&extra_prop.capability)?; + data.write(&extra_prop.permission)?; + let reply = self.remote.send_request( + ISystemAbilityManagerCode::CodeAddSystemAbility as u32, &data, false)?; + let reply_value: i32 = reply.read()?; + info!(LOG_LABEL, "register service result: {}", reply_value); + if reply_value == 0 { Ok(())} else { Err(reply_value) } + } + + fn get_service(&self, said: i32) -> Result + { + let mut data = MsgParcel::new().expect("MsgParcel is null"); + data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?; + data.write(&said)?; + let reply = self.remote.send_request( + ISystemAbilityManagerCode::CodeGetSystemAbility as u32, &data, false)?; + let remote: RemoteObj = reply.read()?; + Ok(remote) + } +} + diff --git a/services/samgr/native/BUILD.gn b/services/samgr/native/BUILD.gn index 7a497b6f9598c99c3c0c08a5e76cbc4cae7261c0..ef4b3038173aac00def8f4b9f31eb24f299d3319 100644 --- a/services/samgr/native/BUILD.gn +++ b/services/samgr/native/BUILD.gn @@ -51,6 +51,9 @@ ohos_executable("samgr") { ] deps = [ "//foundation/systemabilitymgr/samgr/interfaces/innerkits/common:samgr_common" ] + if (product_name == "rk3568" && target_cpu == "arm64") { + deps += [ "//foundation/systemabilitymgr/samgr/interfaces/innerkits/rust:rust_samgr" ] + } configs = [ ":sam_config", diff --git a/services/samgr/native/test/unittest/BUILD.gn b/services/samgr/native/test/unittest/BUILD.gn index 67828148507db7faed3f8ed1b92b72087ecb59a5..577133ea3dbe89ea5d866e11d0985015a5fced0f 100644 --- a/services/samgr/native/test/unittest/BUILD.gn +++ b/services/samgr/native/test/unittest/BUILD.gn @@ -299,6 +299,26 @@ ohos_executable("TestTool") { subsystem_name = "systemabilitymgr" } +ohos_rust_unittest("rust_samgr_test_client") { + module_out_path = module_output_path + + resource_config_file = + "//foundation/systemabilitymgr/samgr/test/resource/ohos_test.xml" + + sources = [ "./rust/rust_samgr_test.rs" ] + deps = [ + "//base/hiviewdfx/hilog/interfaces/rust:hilog_rust", + "//foundation/communication/ipc/interfaces/innerkits/rust:ipc_rust", + "//foundation/systemabilitymgr/safwk/test/services/safwk/unittest/rust:rust_service_test", + "//foundation/systemabilitymgr/safwk/test/services/safwk/unittest/rust:sa_test", + "//foundation/systemabilitymgr/samgr/interfaces/innerkits/rust:rust_samgr", + "//foundation/systemabilitymgr/samgr/services/samgr/native/test/unittest/rust/service:test_access_token", + ] + + subsystem_name = "systemabilitymgr" + part_name = "samgr" +} + group("unittest") { testonly = true deps = [ @@ -309,4 +329,7 @@ group("unittest") { ":TestTool", ":ondemand", ] + if (product_name == "rk3568" && target_cpu == "arm64") { + deps += [ ":rust_samgr_test_client" ] + } } diff --git a/services/samgr/native/test/unittest/rust/rust_samgr_test.rs b/services/samgr/native/test/unittest/rust/rust_samgr_test.rs new file mode 100644 index 0000000000000000000000000000000000000000..d1554558656eb5e055b8268aed2b238dc6f66e62 --- /dev/null +++ b/services/samgr/native/test/unittest/rust/rust_samgr_test.rs @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 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. + */ + + +extern crate ipc_rust; +extern crate sa_test; +extern crate rust_samgr; +extern crate test_access_token; +extern crate rust_service_test; +use ipc_rust::{ + FromRemoteObj, IRemoteBroker, RemoteObjRef +}; +use std::ffi::{c_char, CString}; +use hilog_rust::{error, info, hilog, HiLogLabel, LogType}; +const LOG_LABEL: HiLogLabel = HiLogLabel { + log_type: LogType::LogCore, + domain: 0xd003200, + tag: "rustSA" +}; +use rust_samgr::{get_samgr_proxy, SAExtraProp}; +use rust_service_test::{ TEST_SERVICE_ID, TestService }; +use test_access_token::{ init_access_token }; +use sa_test::{ + ITest, TestStub +}; + +fn get_test_service() -> RemoteObjRef +{ + let samgr_proxy = get_samgr_proxy(); + let object = samgr_proxy.get_service(TEST_SERVICE_ID).expect("get itest service failed"); + let remote = ::from(object); + let remote = match remote { + Ok(x) => x, + Err(error) => { + error!(LOG_LABEL,"convert RemoteObj to TestProxy failed: {}", error); + panic!(); + } + }; + return remote; +} + +#[test] +fn test_add_access_token() { + init_access_token(); +} + +#[test] +fn add_service_test() +{ + init_access_token(); + let service = TestStub::new_remote_stub(TestService).expect("create TestService failed"); + let Sapro = SAExtraProp::default(); + let samgr_proxy = get_samgr_proxy(); + samgr_proxy.add_service(&service.as_object().unwrap(), TEST_SERVICE_ID, Sapro).expect("add_service failed"); +} + +#[test] +fn get_service_test() +{ + init_access_token(); + let service = TestStub::new_remote_stub(TestService).expect("create TestService failed"); + let Sapro = SAExtraProp::default(); + let samgr_proxy = get_samgr_proxy(); + samgr_proxy.add_service(&service.as_object().unwrap(), TEST_SERVICE_ID, Sapro).expect("add_service failed"); + let remote = get_test_service(); +} + +#[test] +fn test_echo_str() { + init_access_token(); + let service = TestStub::new_remote_stub(TestService).expect("create TestService failed"); + let Sapro = SAExtraProp::default(); + let samgr_proxy = get_samgr_proxy(); + samgr_proxy.add_service(&service.as_object().unwrap(), TEST_SERVICE_ID, Sapro).expect("add_service failed"); + let remote = get_test_service(); + let value = remote.echo_str("hello").expect("should return string"); + assert_eq!(value, "hello"); +} + +#[test] +fn test_request_concurent() { + init_access_token(); + let service = TestStub::new_remote_stub(TestService).expect("create TestService failed"); + let Sapro = SAExtraProp::default(); + let samgr_proxy = get_samgr_proxy(); + samgr_proxy.add_service(&service.as_object().unwrap(), TEST_SERVICE_ID, Sapro).expect("add_service failed"); + let remote = get_test_service(); + let value = remote.request_concurent(false).expect("should return true"); + assert_eq!(value, true); +} diff --git a/services/samgr/native/test/unittest/rust/service/BUILD.gn b/services/samgr/native/test/unittest/rust/service/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..c084724589dcb10ad66c6eb3ab3df3bbf0eaea0e --- /dev/null +++ b/services/samgr/native/test/unittest/rust/service/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2023 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/ohos.gni") + +ohos_rust_shared_library("test_access_token") { + sources = [ + "src/access_token.rs", + "src/lib.rs", + ] + + deps = [ + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + ] + + crate_name = "test_access_token" + crate_type = "dylib" + + subsystem_name = "systemabilitymgr" + part_name = "samgr" +} diff --git a/services/samgr/native/test/unittest/rust/service/src/access_token.rs b/services/samgr/native/test/unittest/rust/service/src/access_token.rs new file mode 100644 index 0000000000000000000000000000000000000000..b50b10d018c58f12a91c2a41b0a2d8a3aefa99eb --- /dev/null +++ b/services/samgr/native/test/unittest/rust/service/src/access_token.rs @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 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, CString}; + +#[repr(C)] +struct TokenInfoParams { + dcaps_num: i32, + perms_num: i32, + acls_num: i32, + dcaps: *const *const c_char, + perms: *const c_char, + acls: *const *const c_char, + process_name: *const c_char, + apl_str: *const c_char, +} + +extern "C" { + fn GetAccessTokenId(token_info: *mut TokenInfoParams) -> u64; + fn SetSelfTokenID(token_id: u64) -> i32; +} + +/// Init access token ID for current process +pub fn init_access_token() +{ + let perms_str = CString::new("ohos.permission.DISTRIBUTED_DATASYNC").expect("permission is invalid"); + let name = CString::new("distributedsched").expect("process name is invalid"); + let apl = CString::new("system_core").expect("apl string is invalid"); + let mut param = TokenInfoParams { + dcaps_num: 0, + perms_num: 0, + acls_num: 0, + dcaps: ptr::null(), + perms: perms_str.as_ptr(), + acls: ptr::null(), + process_name: name.as_ptr(), + apl_str: apl.as_ptr(), + }; + + unsafe { + let token_id = GetAccessTokenId(&mut param as *mut TokenInfoParams); + SetSelfTokenID(token_id); + } +} \ No newline at end of file diff --git a/services/samgr/native/test/unittest/rust/service/src/lib.rs b/services/samgr/native/test/unittest/rust/service/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e31c6ea4c8ac38aa9151b9e907a09c6d2171bab2 --- /dev/null +++ b/services/samgr/native/test/unittest/rust/service/src/lib.rs @@ -0,0 +1,20 @@ +/* + * 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. + */ + +//! public init_access_token" + +mod access_token; + +pub use access_token::init_access_token;