diff --git a/interfaces/innerkits/rust/include/status_change_wrapper.h b/interfaces/innerkits/rust/include/status_change_wrapper.h index aa0b1ddbf68b9a460d1afae36e89502316b81e35..39450552e806bdd8d657127b02c3942037f0b5e0 100644 --- a/interfaces/innerkits/rust/include/status_change_wrapper.h +++ b/interfaces/innerkits/rust/include/status_change_wrapper.h @@ -26,32 +26,30 @@ namespace OHOS { namespace SamgrRust { struct SystemProcessInfo; +struct SubscribeSystemAbilityCallback; +struct SubscribeSystemProcessCallback; + class SystemAbilityStatusChangeWrapper : public SystemAbilityStatusChangeStub { public: - SystemAbilityStatusChangeWrapper(const rust::Fn onAdd, - const rust::Fn onRemove); + SystemAbilityStatusChangeWrapper(rust::Box inner); ~SystemAbilityStatusChangeWrapper() = default; void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; - + private: - rust::Fn onAdd_; - rust::Fn onRemove_; + rust::Box inner_; }; class SystemProcessStatusChangeWrapper : public IRemoteProxy { public: - SystemProcessStatusChangeWrapper(const sptr &impl, - const rust::Fn onStart, - const rust::Fn onStop); + SystemProcessStatusChangeWrapper(const sptr &impl, rust::box inner); ~SystemProcessStatusChangeWrapper() = default; void OnSystemProcessStarted(OHOS::SystemProcessInfo &systemProcessInfo) override; void OnSystemProcessStopped(OHOS::SystemProcessInfo &systemProcessInfo) override; private: - rust::Fn onStart_; - rust::Fn onStop_; + rust::Box inner_; }; class UnSubscribeSystemAbilityHandler { diff --git a/interfaces/innerkits/rust/include/system_ability_manager_wrapper.h b/interfaces/innerkits/rust/include/system_ability_manager_wrapper.h index 45470c09f3e5890455dcb970480923d0ea0b60ca..178950f6a7891fd9ebc2027171bdd9ada43d61dd 100644 --- a/interfaces/innerkits/rust/include/system_ability_manager_wrapper.h +++ b/interfaces/innerkits/rust/include/system_ability_manager_wrapper.h @@ -31,15 +31,15 @@ struct SAExtraPropWrapper; struct AbilityStub; struct SystemProcessInfo; struct AddSystemAbilityConfig; +struct LoadSystemAbilityCallback; +struct SubscribeSystemAbilityCallback; std::unique_ptr GetSystemAbility(int32_t systemAbilityId); std::unique_ptr CheckSystemAbility(int32_t systemAbilityId); std::unique_ptr LoadSystemAbility(int32_t systemAbilityId, int32_t timeout); std::unique_ptr LoadSystemAbility(int32_t systemAbilityId, int32_t timeout); -int32_t LoadSystemAbilityWithCallback(int32_t systemAbilityId, rust::Fn on_success, rust::Fn on_fail); - -std::unique_ptr GetContextManager(); +int32_t LoadSystemAbilityWithCallback(int32_t systemAbilityId, rust::Box callback); int32_t RemoveSystemAbility(int32_t systemAbilityId); @@ -47,21 +47,21 @@ std::unique_ptr GetSystemAbilityWithDeviceId(int32_t systemAb std::unique_ptr CheckSystemAbilityWithDeviceId(int32_t systemAbilityId, const std::string &deviceId); rust::Vec ListSystemAbilities(); rust::Vec ListSystemAbilitiesWithDumpFlag(unsigned int dumpFlags); -std::unique_ptr SubscribeSystemAbility(int32_t systemAbilityId, - rust::Fn onAdd, - rust::Fn onRemove); + +std::unique_ptr SubscribeSystemAbility( + int32_t systemAbilityId, rust::box callback); +std::unique_ptr SubscribeSystemProcess( + rust::Box callback); + int32_t AddOnDemandSystemAbilityInfo(int32_t systemAbilityId, const rust::str localAbilityManagerName); int32_t UnloadSystemAbility(int32_t systemAbilityId); int32_t CancelUnloadSystemAbility(int32_t systemAbilityId); int32_t UnloadAllIdleSystemAbility(); -int32_t GetCommonEventExtraDataIdlist(int32_t saId, rust::Vec& extraDataIdList, const std::string& eventName); +int32_t GetCommonEventExtraDataIdlist(int32_t saId, rust::Vec &extraDataIdList, const std::string &eventName); SystemProcessInfo GetSystemProcessInfo(int32_t systemAbilityId); rust::Vec GetRunningSystemProcess(); int32_t SendStrategy(int32_t type, rust::Vec systemAbilityIds, int32_t level, std::string &action); int32_t AddSystemAbility(int32_t systemAbilityId, rust::Box ability, AddSystemAbilityConfig config); -std::unique_ptr SubscribeSystemProcess( - rust::Fn onStart_, - rust::Fn onStop_); int32_t GetOnDemandReasonExtraData(int64_t extraDataId, MessageParcel &parcel); @@ -82,13 +82,12 @@ private: class LoadCallbackWrapper : public SystemAbilityLoadCallbackStub { public: - LoadCallbackWrapper(rust::Fn on_success, rust::Fn on_fail); + LoadCallbackWrapper(rust::Box); void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) override; void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; private: - rust::Fn on_success_; - rust::Fn on_fail_; + rust::Box inner_; }; } // namespace SamgrRust diff --git a/interfaces/innerkits/rust/src/cxx/status_change_wrapper.cpp b/interfaces/innerkits/rust/src/cxx/status_change_wrapper.cpp index 12cdf31946ae231b4f73325bdeee84afe1762d47..bc0b802ece19cacf617d9d85633ed3527720b5d5 100644 --- a/interfaces/innerkits/rust/src/cxx/status_change_wrapper.cpp +++ b/interfaces/innerkits/rust/src/cxx/status_change_wrapper.cpp @@ -22,50 +22,44 @@ #include "wrapper.rs.h" namespace OHOS { namespace SamgrRust { -SystemAbilityStatusChangeWrapper::SystemAbilityStatusChangeWrapper( - const rust::Fn onAdd, - const rust::Fn onRemove) +SystemAbilityStatusChangeWrapper::SystemAbilityStatusChangeWrapper(rust::Box inner) + : inner_(std::move(inner)) { - this->onAdd_ = onAdd; - this->onRemove_ = onRemove; } void SystemAbilityStatusChangeWrapper::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) { - onAdd_(systemAbilityId, deviceId); + inner_->on_add(systemAbilityId, rust::string(deviceId)); } void SystemAbilityStatusChangeWrapper::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) { - onRemove_(systemAbilityId, deviceId); + inner_->on_remove(systemAbilityId, rust::string(deviceId)); } -SystemProcessStatusChangeWrapper::SystemProcessStatusChangeWrapper(const sptr &impl, - const rust::Fn onStart, - const rust::Fn onStop) - : IRemoteProxy(impl) +SystemProcessStatusChangeWrapper::SystemProcessStatusChangeWrapper( + const sptr &impl, rust::box inner) + : IRemoteProxy(impl), inner_(std::move(inner)) { - this->onStart_ = onStart; - this->onStop_ = onStop; } void SystemProcessStatusChangeWrapper::OnSystemProcessStarted(OHOS::SystemProcessInfo &systemProcessInfo) { auto info = OHOS::SamgrRust::SystemProcessInfo{ - .processName = systemProcessInfo.processName, + .process_name = systemProcessInfo.processName, .pid = systemProcessInfo.pid, .uid = systemProcessInfo.uid, }; - onStart_(info); + inner_->on_start(info); } void SystemProcessStatusChangeWrapper::OnSystemProcessStopped(OHOS::SystemProcessInfo &systemProcessInfo) { auto info = OHOS::SamgrRust::SystemProcessInfo{ - .processName = systemProcessInfo.processName, + .process_name = systemProcessInfo.processName, .pid = systemProcessInfo.pid, .uid = systemProcessInfo.uid, }; - onStop_(info); + inner_->on_stop(info); } UnSubscribeSystemAbilityHandler::UnSubscribeSystemAbilityHandler( diff --git a/interfaces/innerkits/rust/src/cxx/system_ability_manager_wrapper.cpp b/interfaces/innerkits/rust/src/cxx/system_ability_manager_wrapper.cpp index 633329186e83f24de64f66cbd4ab4cedd3bf2f2e..e55b33b8999de5529d1c725c1c3040cf07729838 100644 --- a/interfaces/innerkits/rust/src/cxx/system_ability_manager_wrapper.cpp +++ b/interfaces/innerkits/rust/src/cxx/system_ability_manager_wrapper.cpp @@ -35,7 +35,7 @@ namespace SamgrRust { static constexpr size_t MAX_RUST_STR_LEN = 1024; -static void* g_selfSoHandle = nullptr; +static void *g_selfSoHandle = nullptr; extern "C" __attribute__((constructor)) void InitSamgrRust() { @@ -48,7 +48,7 @@ extern "C" __attribute__((constructor)) void InitSamgrRust() return; } - char path[PATH_MAX] = {'\0'}; + char path[PATH_MAX] = { '\0' }; if (realpath(info.dli_fname, path) == nullptr) { return; } @@ -58,25 +58,29 @@ extern "C" __attribute__((constructor)) void InitSamgrRust() if (vectorSize == 0) { return; } - auto& fileName = strVector[vectorSize - 1]; + auto &fileName = strVector[vectorSize - 1]; g_selfSoHandle = dlopen(fileName.c_str(), RTLD_LAZY); if (g_selfSoHandle == nullptr) { return; } } +std::string u16string_to_string(const std::u16string &u16str) +{ + std::wstring_convert, char16_t> convert; + return convert.to_bytes(u16str); +} + rust::Vec ListSystemAbilities() { auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); auto res = rust::Vec(); - if (sysm == nullptr) { return res; } - auto list = sysm->ListSystemAbilities(); for (auto s : list) { - res.push_back(s.data()); + res.push_back(u16string_to_string(s)); } return res; } @@ -85,15 +89,12 @@ rust::Vec ListSystemAbilitiesWithDumpFlag(unsigned int dumpFlags) { auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); auto res = rust::Vec(); - if (sysm == nullptr) { return res; } - auto list = sysm->ListSystemAbilities(dumpFlags); for (auto s : list) { - char16_t *c = s.data(); - res.push_back(c); + res.push_back(u16string_to_string(s)); } return res; } @@ -104,7 +105,6 @@ std::unique_ptr LoadSystemAbility(int32_t systemAbilityId, in if (sysm == nullptr) { return nullptr; } - auto ability = sysm->LoadSystemAbility(systemAbilityId, timeout); if (ability == nullptr) { return nullptr; @@ -112,23 +112,14 @@ std::unique_ptr LoadSystemAbility(int32_t systemAbilityId, in return std::make_unique(std::move(ability)); } -int32_t LoadSystemAbilityWithCallback(int32_t systemAbilityId, rust::Fn on_success, rust::Fn on_fail) +int32_t LoadSystemAbilityWithCallback(int32_t systemAbilityId, rust::Box callback) { auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sysm == nullptr) { return -1; } - auto callback = sptr::MakeSptr(on_success, on_fail); - return sysm->LoadSystemAbility(systemAbilityId, callback); -} - -std::unique_ptr GetContextManager() -{ - sptr saMgr = IPCSkeleton::GetContextObject(); - if (saMgr == nullptr) { - return nullptr; - } - return std::make_unique(std::move(saMgr)); + auto cb = sptr::MakeSptr(std::move(callback)); + return sysm->LoadSystemAbility(systemAbilityId, cb); } std::unique_ptr GetSystemAbility(int32_t systemAbilityId) @@ -194,20 +185,31 @@ std::unique_ptr CheckSystemAbilityWithDeviceId(int32_t system return std::make_unique(std::move(ability)); } -std::unique_ptr SubscribeSystemAbility(int32_t systemAbilityId, - rust::Fn onAdd, - rust::Fn onRemove) +std::unique_ptr SubscribeSystemAbility( + int32_t systemAbilityId, rust::box callback) { auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sysm == nullptr) { return nullptr; } - - sptr listener = new SystemAbilityStatusChangeWrapper(onAdd, onRemove); + sptr listener = new SystemAbilityStatusChangeWrapper(std::move(callback)); sysm->SubscribeSystemAbility(systemAbilityId, listener); return std::make_unique(systemAbilityId, listener); } +std::unique_ptr SubscribeSystemProcess( + rust::Box callback) +{ + auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sysm == nullptr) { + return nullptr; + } + sptr listener = + sptr::MakeSptr(nullptr, std::move(callback)); + sysm->SubscribeSystemProcess(listener); + return std::make_unique(listener); +} + int32_t AddOnDemandSystemAbilityInfo(int32_t systemAbilityId, const rust::str localAbilityManagerName) { if (localAbilityManagerName.length() > MAX_RUST_STR_LEN) { @@ -270,14 +272,14 @@ SystemProcessInfo GetSystemProcessInfo(int32_t systemAbilityId) OHOS::SystemProcessInfo info; if (sysm == nullptr) { return SystemProcessInfo{ - .processName = info.processName.data(), + .process_name = info.processName.data(), .pid = info.pid, .uid = info.uid, }; } sysm->GetSystemProcessInfo(systemAbilityId, info); return SystemProcessInfo{ - .processName = info.processName.data(), + .process_name = info.processName.data(), .pid = info.pid, .uid = info.uid, }; @@ -296,7 +298,7 @@ rust::Vec GetRunningSystemProcess() sysm->GetRunningSystemProcess(infos); for (auto info : infos) { res.push_back(SystemProcessInfo{ - .processName = info.processName, + .process_name = info.processName, .pid = info.pid, .uid = info.uid, }); @@ -322,19 +324,6 @@ int32_t GetCommonEventExtraDataIdlist(int32_t saId, rust::Vec &extraDat return ret; } -std::unique_ptr SubscribeSystemProcess( - rust::Fn onStart_, - rust::Fn onStop_) -{ - auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (sysm == nullptr) { - return nullptr; - } - sptr listener = new SystemProcessStatusChangeWrapper(nullptr, onStart_, onStop_); - sysm->SubscribeSystemProcess(listener); - return std::make_unique(listener); -} - int32_t GetOnDemandReasonExtraData(int64_t extraDataId, MessageParcel &parcel) { auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); @@ -379,19 +368,18 @@ int RemoteServiceStub ::OnRemoteDump( return 0; } -LoadCallbackWrapper::LoadCallbackWrapper(rust::Fn on_success, rust::Fn on_fail) - : on_success_(on_success), on_fail_(on_fail) +LoadCallbackWrapper::LoadCallbackWrapper(rust::Box inner) : inner_(std::move(inner)) { } void LoadCallbackWrapper::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) { - on_success_(); + inner_->on_success(systemAbilityId, std::make_unique(remoteObject)); } void LoadCallbackWrapper::OnLoadSystemAbilityFail(int32_t systemAbilityId) { - on_fail_(); + inner_->on_fail(systemAbilityId); } } // namespace SamgrRust diff --git a/interfaces/innerkits/rust/src/hilog.rs b/interfaces/innerkits/rust/src/hilog.rs deleted file mode 100644 index bba5f811b47d4f8262e2ba7fbbe550a6d785be54..0000000000000000000000000000000000000000 --- a/interfaces/innerkits/rust/src/hilog.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2024 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. - -/// hilog label. - -macro_rules! debug { - ($($args:tt)*) => {{ - use hilog_rust::hilog; - use std::ffi::{c_char, CString}; - use $crate::LOG_LABEL; - - let log = format!($($args)*); - - hilog_rust::debug!(LOG_LABEL,"{}",@public(log)); - }} -} - -macro_rules! info { - ($($args:tt)*) => {{ - use hilog_rust::hilog; - use std::ffi::{c_char, CString}; - use $crate::LOG_LABEL; - - let log = format!($($args)*); - - hilog_rust::info!(LOG_LABEL,"{}",@public(log)); - }} -} - -macro_rules! error { - ($($args:tt)*) => {{ - use hilog_rust::hilog; - use std::ffi::{c_char, CString}; - use $crate::LOG_LABEL; - - let log = format!($($args)*); - - hilog_rust::error!(LOG_LABEL,"{}",@public(log)); - }} -} diff --git a/interfaces/innerkits/rust/src/lib.rs b/interfaces/innerkits/rust/src/lib.rs index e799ab9cb1f0177b6853eb9afedd424066dc3c2d..60c5ceaa4948819e59dd9850098cd164a5133a2b 100644 --- a/interfaces/innerkits/rust/src/lib.rs +++ b/interfaces/innerkits/rust/src/lib.rs @@ -11,14 +11,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![allow(missing_docs)] -#![allow(clippy::missing_safety_doc)] //! Safe Rust interface to OHOS samgr // Export types of this crate -#[macro_use] -#[allow(unused)] -mod hilog; +#![allow(missing_docs)] +#![allow(clippy::missing_safety_doc)] pub mod definition; mod dump_flag; @@ -26,8 +23,5 @@ pub mod manage; pub use dump_flag::DumpFlagPriority; mod wrapper; -pub const LOG_LABEL: hilog_rust::HiLogLabel = hilog_rust::HiLogLabel { - log_type: hilog_rust::LogType::LogCore, - domain: 0xD001800, - tag: "SAMGR_RUST", -}; +#[cfg(test)] +mod test; diff --git a/interfaces/innerkits/rust/src/manage.rs b/interfaces/innerkits/rust/src/manage.rs index bc6539bc72f7dd96b9b7e1c02b8c4dd47032bdb3..517a032b30f77cb477de011afc5be62058ed7baf 100644 --- a/interfaces/innerkits/rust/src/manage.rs +++ b/interfaces/innerkits/rust/src/manage.rs @@ -15,17 +15,7 @@ use cxx::{let_cxx_string, UniquePtr}; use ipc::parcel::MsgParcel; use ipc::remote::{RemoteObj, RemoteStub}; -use crate::wrapper::{ - GetCommonEventExtraDataIdlist, - AbilityStub, AddOnDemandSystemAbilityInfo, AddSystemAbility, AddSystemAbilityConfig, - CancelUnloadSystemAbility, CheckSystemAbility, CheckSystemAbilityWithDeviceId, - GetContextManager, GetOnDemandReasonExtraData, GetRunningSystemProcess, GetSystemAbility, - GetSystemAbilityWithDeviceId, GetSystemProcessInfo, ListSystemAbilities, - ListSystemAbilitiesWithDumpFlag, LoadSystemAbility, LoadSystemAbilityWithCallback, - RemoveSystemAbility, SendStrategy, SubscribeSystemAbility, SubscribeSystemProcess, - SystemProcessInfo, UnSubscribeSystemAbilityHandler, UnSubscribeSystemProcessHandler, - UnloadAllIdleSystemAbility, UnloadSystemAbility, -}; +use crate::wrapper::*; use crate::DumpFlagPriority; pub struct SystemAbilityManager; @@ -34,78 +24,169 @@ unsafe impl Sync for SystemAbilityManager {} unsafe impl Send for SystemAbilityManager {} impl SystemAbilityManager { + /// List all active system abilities with default dump flag + /// DUMP_FLAG_PRIORITY_ALL. + /// /// # Example /// ```rust /// use samgr::manage::SystemAbilityManager; /// - /// let context = SystemAbilityManager::get_context_manager(); - /// ``` - pub fn get_context_manager() -> Option { - info!("get context manager"); - RemoteObj::from_sptr(GetContextManager()) - } - - /// let abilities = sysm.list_system_ability(); - /// - /// - /// # Example - /// ```rust + /// let abilities = SystemAbilityManager::list_system_abilities(); + /// assert!(!abilities.is_empty()): /// ``` pub fn list_system_abilities() -> Vec { - info!("list system ability"); ListSystemAbilities() } - /// let abilities = sysm.list_system_ability(); - /// + + /// List all active system abilities with dump flag /// /// # Example /// ```rust + /// use samgr::manage::SystemAbilityManager; + /// use samgr::DumpFlagPriority; + /// + /// let abilities = SystemAbilityManager::list_system_abilities_with_dump_flag(DumpFlagPriority::Critical); + /// assert!(!abilities.is_empty()): /// ``` pub fn list_system_abilities_with_dump_flag(dump_flag: DumpFlagPriority) -> Vec { - info!("list system ability"); ListSystemAbilitiesWithDumpFlag(dump_flag as u32) } + /// Get a system ability by its ID. Returns None if the ability is not + /// loaded. In fact, it calls [`check_system_ability`] multiple times, + /// blocking for a few seconds if it doesn't exist. + /// + /// [`check_system_ability`]: #method.check_system_ability /// # Example /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; /// use samgr::manage::SystemAbilityManager; /// - /// let request_abilty = SystemAbilityManager::get_system_ability(3706, None); + /// let ability = SystemAbilityManager::get_system_ability(DOWNLOAD_SERVICE_ID); /// ``` pub fn get_system_ability(said: i32) -> Option { - info!("get system ability {}", said); RemoteObj::from_sptr(GetSystemAbility(said)) } + /// Get a system ability by its ID and device ID. Returns None if the + /// ability is not loaded + /// /// # Example /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; /// use samgr::manage::SystemAbilityManager; + /// + /// let ability = + /// SystemAbilityManager::get_system_ability_with_device_id(DOWNLOAD_SERVICE_ID, "device_id"); /// ``` pub fn get_system_ability_with_device_id(said: i32, device_id: &str) -> Option { - info!("get system ability {} with device id", said); let_cxx_string!(id = device_id); RemoteObj::from_sptr(GetSystemAbilityWithDeviceId(said, &id)) } + /// Check if a system ability is loaded. Returns None if the ability is not + /// loaded + /// /// # Example /// ```rust /// use samgr::definition::DOWNLOAD_SERVICE_ID; /// use samgr::manage::SystemAbilityManager; /// - /// let download_service = SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID).unwrap(); + /// let ability = SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID); /// ``` pub fn check_system_ability(said: i32) -> Option { - info!("check system ability {}", said); - RemoteObj::from_sptr(CheckSystemAbility(said)) } - pub fn check_system_ability_with_ability(said: i32, device_id: &str) -> Option { - info!("check system ability {} with device id", said); + /// Check if a system ability is loaded with device ID. Returns None if the + /// ability is not loaded + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// let ability = + /// SystemAbilityManager::check_system_ability_with_device_id(DOWNLOAD_SERVICE_ID, "device_id"); + /// ``` + pub fn check_system_ability_with_device_id(said: i32, device_id: &str) -> Option { let_cxx_string!(id = device_id); RemoteObj::from_sptr(CheckSystemAbilityWithDeviceId(said, &id)) } + /// Checks if a system ability is already loaded. If not, attempts to load + /// it. The operation times out after the specified number of + /// milliseconds. + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// let ability = SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 1000); + /// ``` + pub fn load_system_ability(said: i32, timeout: i32) -> Option { + RemoteObj::from_sptr(LoadSystemAbility(said, timeout)) + } + + /// Load a system ability with a callback function. The callback is called + /// when the ability is loaded successfully or fails to load. + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// SystemAbilityManager::load_system_ability_with_callback( + /// DOWNLOAD_SERVICE_ID, + /// |said, obj| { + /// println!("ability {} loaded successfully", said); + /// }, + /// |said| { + /// println!("ability {} failed to load", said); + /// }, + /// ); + /// ``` + pub fn load_system_ability_with_callback( + said: i32, + on_success: impl Fn(i32, Option) + 'static, + on_fail: impl Fn(i32) + 'static, + ) -> i32 { + let callback = Box::new(LoadSystemAbilityCallback::new( + Box::new(on_success), + Box::new(on_fail), + )); + LoadSystemAbilityWithCallback(said, callback) + } + + /// Unload a system ability by its ID + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// SystemAbilityManager::unload_system_ability(DOWNLOAD_SERVICE_ID); + /// ``` + pub fn unload_system_ability(said: i32) -> i32 { + UnloadSystemAbility(said) + } + + /// Cancel the unload operation of a system ability by its ID + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// SystemAbilityManager::cancel_unload_system_ability(DOWNLOAD_SERVICE_ID); + /// ``` + pub fn cancel_unload_system_ability(said: i32) -> i32 { + CancelUnloadSystemAbility(said) + } + + /// Remove a system ability by its ID + /// /// # Example /// ```rust /// use samgr::definition::DOWNLOAD_SERVICE_ID; @@ -114,13 +195,78 @@ impl SystemAbilityManager { /// SystemAbilityManager::remove_system_ability(DOWNLOAD_SERVICE_IDD); /// ``` pub fn remove_system_ability(said: i32) -> i32 { - info!("remove system ability {}", said); RemoveSystemAbility(said) } - /// Adds a new system ability + /// Unload all idle system abilities + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// + /// SystemAbilityManager::unload_all_idle_system_ability(); + /// ``` + pub fn unload_all_idle_system_ability() -> i32 { + UnloadAllIdleSystemAbility() + } + + /// Subscribe a system ability for its add and remove events + /// + /// # Example + /// ```rust + /// use samgr::definition::DOWNLOAD_SERVICE_ID; + /// use samgr::manage::SystemAbilityManager; + /// + /// SystemAbilityManager::subscribe_system_ability( + /// DOWNLOAD_SERVICE_ID, + /// |said, name| { + /// println!("ability {} added: {}", said, name); + /// }, + /// |said, name| { + /// println!("ability {} removed: {}", said, name); + /// }, + /// ); + /// ``` + pub fn subscribe_system_ability( + said: i32, + on_add: impl Fn(i32, String) + 'static, + on_remove: impl Fn(i32, String) + 'static, + ) -> UnsubscribeHandler { + let callback = Box::new(SubscribeSystemAbilityCallback::new( + Box::new(on_add), + Box::new(on_remove), + )); + UnsubscribeHandler::new(Unsubscribe::Ability(SubscribeSystemAbility(said, callback))) + } + + /// Subscribe system process for its start and stop events + /// + /// # Example + /// ```rust + /// use samgr::manage::SystemAbilityManager; + /// + /// SystemAbilityManager::subscribe_system_process( + /// |info| { + /// println!("process {} started", info.process_name); + /// }, + /// |info| { + /// println!("process {} stopped", info.process_name); + /// }, + /// ); + /// ``` + pub fn subscribe_system_process( + on_start: impl Fn(&SystemProcessInfo) + 'static, + on_stop: impl Fn(&SystemProcessInfo) + 'static, + ) -> UnsubscribeHandler { + let callback = Box::new(SubscribeSystemProcessCallback::new( + Box::new(on_start), + Box::new(on_stop), + )); + UnsubscribeHandler::new(Unsubscribe::Process(SubscribeSystemProcess(callback))) + } + + /// Add an ability to samgr pub fn add_systemability(said: i32, ability: A) -> i32 { - info!("add system ability {}", said); let is_distributed = false; let dump_flags = DumpFlagPriority::Default; let capability = ""; @@ -138,6 +284,7 @@ impl SystemAbilityManager { ) } + /// Add an ability to samgr with extra config pub fn add_systemability_with_extra( said: i32, ability: A, @@ -146,7 +293,6 @@ impl SystemAbilityManager { capability: &str, permission: &str, ) -> i32 { - info!("add system ability {}", said); let stub = AbilityStub::new(ability); AddSystemAbility( said, @@ -160,91 +306,38 @@ impl SystemAbilityManager { ) } - pub fn load_system_ability(said: i32, timeout: i32) -> Option { - info!("load system ability {}", said); - RemoteObj::from_sptr(LoadSystemAbility(said, timeout)) - } - - pub fn load_system_ability_with_callback(said: i32, on_success: fn(), on_fail: fn()) -> i32 { - info!("load system ability {}", said); - LoadSystemAbilityWithCallback(said, on_success, on_fail) - } - - pub fn subscribe_system_ability( - said: i32, - on_add: fn(i32, &str), - on_remove: fn(i32, &str), - ) -> UnsubscribeHandler { - info!("subscribe system ability {}", said); - UnsubscribeHandler::new(Unsubscribe::Ability(SubscribeSystemAbility( - said, on_add, on_remove, - ))) - } - - /// # Example - /// ```rust - /// use samgr::definition::DOWNLOAD_SERVICE_ID; - /// use samgr::manage::SystemAbilityManager; - /// - /// SystemAbilityManager::remove_system_ability(DOWNLOAD_SERVICE_IDD); - /// ``` + /// Add ondemand ability info. pub fn add_ondemand_system_ability_info(said: i32, local_ability_manager_name: &str) -> i32 { - info!("add ondemand system ability {} info", said); - AddOnDemandSystemAbilityInfo(said, local_ability_manager_name) } - pub fn unload_system_ability(said: i32) -> i32 { - info!("unload system ability {}", said); - UnloadSystemAbility(said) - } - - pub fn cancel_unload_system_ability(said: i32) -> i32 { - info!("cancel unload system ability {}", said); - CancelUnloadSystemAbility(said) - } - - /// # Example - /// ```rust - /// use samgr::definition::DOWNLOAD_SERVICE_ID; - /// - /// SystemAbilityManager::unload_all_idle_system_ability(); - /// ``` - pub fn unload_all_idle_system_ability(&self) -> i32 { - info!("unload all idle system ability"); - UnloadAllIdleSystemAbility() - } - + /// Get process info by said. pub fn get_system_process_info(said: i32) -> SystemProcessInfo { - info!("get system ability {} process info", said); GetSystemProcessInfo(said) } + /// Get running system process info. pub fn get_running_system_process() -> Vec { - info!("get running system ability process info"); GetRunningSystemProcess() } - /// + /// Send strategy to SystemAbility. pub fn send_strategy(s_type: i32, saids: Vec, level: i32, action: &str) -> i32 { let_cxx_string!(action = action); SendStrategy(s_type, saids, level, action) } - pub fn get_common_event_extra_data_id_list(said: i32, extraids: &mut Vec, event_name: &str) -> i32 { + /// Get common event extra data id list. + pub fn get_common_event_extra_data_id_list( + said: i32, + extraids: &mut Vec, + event_name: &str, + ) -> i32 { let_cxx_string!(event_name = event_name); GetCommonEventExtraDataIdlist(said, extraids, &event_name) } - pub fn subscribe_system_process( - on_start: fn(&SystemProcessInfo), - on_stop: fn(&SystemProcessInfo), - ) -> UnsubscribeHandler { - UnsubscribeHandler::new(Unsubscribe::Process(SubscribeSystemProcess( - on_start, on_stop, - ))) - } - + /// Get ondemand reason extra data. pub fn get_on_demand_reason_extra_date(extra_data_id: i64, parcel: &mut MsgParcel) -> i32 { GetOnDemandReasonExtraData(extra_data_id, parcel.pin_mut().unwrap()) } @@ -271,3 +364,124 @@ impl UnsubscribeHandler { } } } + +#[cfg(test)] +mod test { + use std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::Arc; + use std::thread::sleep; + + use super::*; + use crate::definition::{APP_MGR_SERVICE_ID, DOWNLOAD_SERVICE_ID}; + use crate::test::init_access_token; + + #[test] + fn system_ability_basic_ut() { + init_access_token(); + let abilities = SystemAbilityManager::list_system_abilities(); + assert!(!abilities.is_empty()); + let abilities = + SystemAbilityManager::list_system_abilities_with_dump_flag(DumpFlagPriority::High); + assert!(!abilities.is_empty()); + let ability = SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 7000); + assert!(ability.is_some()); + + loop { + let ability = SystemAbilityManager::get_system_ability(DOWNLOAD_SERVICE_ID); + if ability.is_some() { + break; + } else { + SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 7000); + } + } + loop { + let ability = SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID); + if ability.is_some() { + break; + } else { + SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 7000); + } + } + } + + #[test] + fn system_ability_callback_ut() { + init_access_token(); + let flag_s_0 = Arc::new(AtomicBool::new(false)); + let flag_f_0 = Arc::new(AtomicBool::new(false)); + let flag_s_1 = flag_s_0.clone(); + let flag_f_1 = flag_f_0.clone(); + SystemAbilityManager::load_system_ability_with_callback( + DOWNLOAD_SERVICE_ID, + move |said, obj| { + if obj.is_some() && said == DOWNLOAD_SERVICE_ID { + flag_s_1.store(true, Ordering::SeqCst); + } + }, + move |_said| { + flag_f_1.store(true, Ordering::SeqCst); + }, + ); + while !flag_s_0.load(Ordering::SeqCst) { + std::thread::sleep(std::time::Duration::from_secs(1)); + } + assert!(!flag_f_0.load(Ordering::SeqCst)); + } + + #[test] + fn system_ability_unload_ut() { + init_access_token(); + let ability = SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 7000); + assert!(ability.is_some()); + SystemAbilityManager::unload_system_ability(DOWNLOAD_SERVICE_ID); + SystemAbilityManager::cancel_unload_system_ability(DOWNLOAD_SERVICE_ID); + SystemAbilityManager::remove_system_ability(DOWNLOAD_SERVICE_ID); + assert_eq!(SystemAbilityManager::unload_all_idle_system_ability(), 0); + } + + #[test] + fn subscribe_system_ability_ut() { + init_access_token(); + SystemAbilityManager::subscribe_system_ability( + DOWNLOAD_SERVICE_ID, + move |said, name| { + println!("ability added {} {}", said, name); + }, + move |said, name| { + println!("ability removed {} {}", said, name); + }, + ); + let handler = SystemAbilityManager::subscribe_system_ability( + APP_MGR_SERVICE_ID, + |_, _| {}, + |_, _| {}, + ); + handler.unsubscribe(); + sleep(std::time::Duration::from_secs(100)); + } + + #[test] + fn subscribe_system_process_ut() { + init_access_token(); + SystemAbilityManager::subscribe_system_process( + move |info| { + println!("process started {}", info.process_name); + }, + |info| { + println!("process stopped {}", info.process_name); + }, + ); + let handler = SystemAbilityManager::subscribe_system_process(|_| {}, |_| {}); + handler.unsubscribe(); + } + + #[test] + fn system_ability_info_ut() { + init_access_token(); + let info = SystemAbilityManager::get_system_process_info(3706); + println!("process name is {:?}", info); + let infos = SystemAbilityManager::get_running_system_process(); + println!("running process len {:?}", infos.len()); + println!("running process last item is {:?}", infos.last()); + } +} diff --git a/interfaces/innerkits/rust/src/test.rs b/interfaces/innerkits/rust/src/test.rs new file mode 100644 index 0000000000000000000000000000000000000000..15d17f019a33e63546f77b751db4701a50f06080 --- /dev/null +++ b/interfaces/innerkits/rust/src/test.rs @@ -0,0 +1,57 @@ +// Copyright (C) 2025 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::ffi::{c_char, CString}; +use std::ptr; +use std::sync::Once; +#[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; +} + +pub(crate) fn init_access_token() { + static ONCE: Once = Once::new(); + ONCE.call_once(|| { + let perms_str = + CString::new("ohos.permission.DISTRIBUTED_DATASYNC").expect("permission is invalid"); + let name = CString::new("listen_test").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); + } + }); +} diff --git a/interfaces/innerkits/rust/src/wrapper.rs b/interfaces/innerkits/rust/src/wrapper.rs index 8652ce1e33699e40f3c2692d71f7c37590386622..7851d37d0e1ee2e8edce559c56332ea192ea4b7e 100644 --- a/interfaces/innerkits/rust/src/wrapper.rs +++ b/interfaces/innerkits/rust/src/wrapper.rs @@ -13,16 +13,86 @@ use std::pin::Pin; +use cxx::UniquePtr; pub(crate) use ffi::*; use ipc::cxx_share::RemoteStubWrapper; -use ipc::remote::RemoteStub; +use ipc::remote::{RemoteObj, RemoteStub}; + +pub struct LoadSystemAbilityCallback { + on_success: Box)>, + on_fail: Box, +} + +pub struct SubscribeSystemAbilityCallback { + on_add: Box, + on_remove: Box, +} + +pub struct SubscribeSystemProcessCallback { + on_start: Box, + on_stop: Box, +} + +impl LoadSystemAbilityCallback { + pub(crate) fn new( + on_success: Box)>, + on_fail: Box, + ) -> Self { + Self { + on_success, + on_fail, + } + } + + fn on_success(&self, said: i32, remote: UniquePtr) { + (self.on_success)(said, RemoteObj::from_sptr(remote)) + } + + fn on_fail(&self, said: i32) { + (self.on_fail)(said) + } +} + +impl SubscribeSystemAbilityCallback { + pub(crate) fn new( + on_add: Box, + on_remove: Box, + ) -> Self { + Self { on_add, on_remove } + } + + fn on_add(&self, said: i32, name: String) { + (self.on_add)(said, name) + } + + fn on_remove(&self, said: i32, name: String) { + (self.on_remove)(said, name) + } +} + +impl SubscribeSystemProcessCallback { + pub(crate) fn new( + on_start: Box, + on_stop: Box, + ) -> Self { + Self { on_start, on_stop } + } + + fn on_start(&self, info: &SystemProcessInfo) { + (self.on_start)(info) + } + + fn on_stop(&self, info: &SystemProcessInfo) { + (self.on_stop)(info) + } +} #[cxx::bridge(namespace = "OHOS::SamgrRust")] mod ffi { #[derive(Debug)] struct SystemProcessInfo { - processName: String, + process_name: String, pid: i32, uid: i32, } @@ -36,6 +106,22 @@ mod ffi { extern "Rust" { type AbilityStub; + type LoadSystemAbilityCallback; + type SubscribeSystemAbilityCallback; + type SubscribeSystemProcessCallback; + + fn on_success( + self: &LoadSystemAbilityCallback, + said: i32, + remote: UniquePtr, + ); + fn on_fail(self: &LoadSystemAbilityCallback, said: i32); + + fn on_add(self: &SubscribeSystemAbilityCallback, said: i32, name: String); + fn on_remove(self: &SubscribeSystemAbilityCallback, said: i32, name: String); + + fn on_start(self: &SubscribeSystemProcessCallback, info: &SystemProcessInfo); + fn on_stop(self: &SubscribeSystemProcessCallback, info: &SystemProcessInfo); fn on_remote_request( self: &mut AbilityStub, @@ -62,12 +148,13 @@ mod ffi { pub type UnSubscribeSystemProcessHandler; fn LoadSystemAbility(said: i32, timeout: i32) -> UniquePtr; - fn LoadSystemAbilityWithCallback(said: i32, on_success: fn(), on_fail: fn()) -> i32; + fn LoadSystemAbilityWithCallback( + said: i32, + callback: Box, + ) -> i32; fn GetSystemAbility(said: i32) -> UniquePtr; - fn GetContextManager() -> UniquePtr; - fn CheckSystemAbility(said: i32) -> UniquePtr; fn GetSystemAbilityWithDeviceId( @@ -87,8 +174,7 @@ mod ffi { fn SubscribeSystemAbility( said: i32, - on_add: fn(i32, &str), - on_remove: fn(i32, &str), + callback: Box, ) -> UniquePtr; fn UnSubscribe(self: Pin<&mut UnSubscribeSystemAbilityHandler>); @@ -120,8 +206,7 @@ mod ffi { ) -> i32; fn SubscribeSystemProcess( - on_start: fn(&SystemProcessInfo), - on_stop: fn(&SystemProcessInfo), + callback: Box, ) -> UniquePtr; fn UnSubscribe(self: Pin<&mut UnSubscribeSystemProcessHandler>); diff --git a/interfaces/innerkits/rust/tests/BUILD.gn b/interfaces/innerkits/rust/tests/BUILD.gn index bfff3bd41700f17115f0a6107015b61316749965..5e9024b577c215555e5f266682e78217dc0b309c 100644 --- a/interfaces/innerkits/rust/tests/BUILD.gn +++ b/interfaces/innerkits/rust/tests/BUILD.gn @@ -53,6 +53,15 @@ ohos_rust_unittest("rust_samgr_ut_test") { "//third_party/rust/crates/cxx:lib", ] + defines = [] + if (samgr_support_access_token) { + external_deps += [ + "access_token:libnativetoken", + "access_token:libtoken_setproc", + ] + defines += [ "SUPPORT_ACCESS_TOKEN" ] + } + subsystem_name = "systemabilitymgr" part_name = "samgr" } @@ -89,8 +98,12 @@ ohos_rust_systemtest("rust_samgr_sdv_test") { group("unittest") { testonly = true - deps = [ - ":rust_samgr_sdv_test", - ":rust_samgr_ut_test", - ] + deps = [] + + if (!use_clang_coverage) { + deps = [ + ":rust_samgr_sdv_test", + ":rust_samgr_ut_test", + ] + } } diff --git a/interfaces/innerkits/rust/tests/basic.rs b/interfaces/innerkits/rust/tests/basic.rs index dd370f5bf2a3dbd7848107c672831940381abb3b..a9cf766c3dc22d6a798686866f8d7fd3b1b846b7 100644 --- a/interfaces/innerkits/rust/tests/basic.rs +++ b/interfaces/innerkits/rust/tests/basic.rs @@ -12,7 +12,6 @@ // limitations under the License. use samgr::manage::SystemAbilityManager; -use samgr::DumpFlagPriority; fn init() { #[cfg(gn_test)] @@ -20,16 +19,14 @@ fn init() { } #[test] -fn basic() { +fn system_ability() { init(); - let abilities = SystemAbilityManager::list_system_abilities(); - assert!(!abilities.is_empty()); - let abilities = - SystemAbilityManager::list_system_abilities_with_dump_flag(DumpFlagPriority::High); - assert!(!abilities.is_empty()); + + + let info = SystemAbilityManager::get_system_process_info(3706); - assert_eq!("download_server", info.processName); + assert_eq!("download_server", info.process_name); let infos = SystemAbilityManager::get_running_system_process(); assert!(!infos.is_empty()); } @@ -39,16 +36,19 @@ fn common_event() { init(); let obj_j = SystemAbilityManager::check_system_ability(1494); if let Some(obj) = obj_j { - let mut id_list:Vec = vec![]; + let mut id_list: Vec = vec![]; let ret = SystemAbilityManager::get_common_event_extra_data_id_list(1494, &mut id_list, ""); assert_eq!(ret, 0); for id in id_list { println!("all extra id is {}", id) } - let mut id_list:Vec = vec![]; - let ret = - SystemAbilityManager::get_common_event_extra_data_id_list(1494, &mut id_list, "usual.event.SCREEN_ON"); + let mut id_list: Vec = vec![]; + let ret = SystemAbilityManager::get_common_event_extra_data_id_list( + 1494, + &mut id_list, + "usual.event.SCREEN_ON", + ); assert_eq!(ret, 0); for id in id_list { println!("usual.event.SCREEN_ON event extra id is {}", id)