diff --git a/bundle.json b/bundle.json index eb78c8cf7f0148b29ebc5fda126f7ca0c8360fc8..50e6f6e120b48421b201808b2afa1277402fac8a 100644 --- a/bundle.json +++ b/bundle.json @@ -69,6 +69,7 @@ "device_manager", "dfs_service", "dsoftbus", + "ffrt", "hicollie", "hilog", "hisysevent", @@ -77,6 +78,8 @@ "kv_store", "image_framework", "ipc", + "json", + "jsoncpp", "memmgr", "napi", "netmanager_base", @@ -89,6 +92,7 @@ "screenlock_mgr", "time_service", "udmf", + "window_manager", "app_file_service", "file_api", "openssl", @@ -110,7 +114,9 @@ "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/rust/extension:build_module", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:build_module", "//foundation/distributeddatamgr/datamgr_service/conf:build_module", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share:build_module" + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share:build_module", + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr/framework:dataobsms_target", + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr/interfaces:dataobs_manager" ], "inner_kits": [ { @@ -169,6 +175,20 @@ ], "header_base": "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include" } + }, + { + "name": "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr/interfaces:dataobs_manager", + "header": { + "header_files": [ + "data_ability_observer_interface.h", + "data_ability_observer_stub.h", + "dataobs_mgr_changeinfo.h", + "dataobs_mgr_client.h", + "dataobs_mgr_errors.h", + "dataobs_utils.h" + ], + "header_base": "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr/interfaces/include" + } } ], "test": [ diff --git a/datamgr_service.gni b/datamgr_service.gni index 7b327ccea5c69ef499da3dbd5991d35f004b2ed9..36f31e02f280998feb6e0d77b66f21dc9ac96044 100644 --- a/datamgr_service.gni +++ b/datamgr_service.gni @@ -26,6 +26,8 @@ dsoftbus_core_path = "//foundation/communication/dsoftbus/core/common/include" datashare_path = "//foundation/distributeddatamgr/data_share" +dataobsmgr_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr" + ipc_core_path = "//foundation/communication/ipc/interfaces/innerkits/ipc_core" device_manager_path = "//foundation/distributedhardware/device_manager" diff --git a/services/distributeddataservice/service/BUILD.gn b/services/distributeddataservice/service/BUILD.gn index f75ebfcd39b40948512fd808c4bdcfe29780cb92..e95ab06db3c8f8fd018b2c8115b666d78a8999de 100644 --- a/services/distributeddataservice/service/BUILD.gn +++ b/services/distributeddataservice/service/BUILD.gn @@ -85,6 +85,7 @@ ohos_shared_library("distributeddatasvc") { "${data_service_path}/service/common:distributeddata_common", "${data_service_path}/service/config:distributeddata_config", "${data_service_path}/service/crypto:distributeddata_crypto", + "${data_service_path}/service/dataobsmgr/framework:dataobsms", "${data_service_path}/service/dumper:distributeddata_dumper", "${data_service_path}/service/matrix:distributeddata_matrix", "${data_service_path}/service/permission:distributeddata_permit", diff --git a/services/distributeddataservice/service/data_share/BUILD.gn b/services/distributeddataservice/service/data_share/BUILD.gn index 74ab6cf29f61fd0275632e2dc2f59e558e3c0d5e..61d098d658b11742a974d53f27b840f608395888 100644 --- a/services/distributeddataservice/service/data_share/BUILD.gn +++ b/services/distributeddataservice/service/data_share/BUILD.gn @@ -108,13 +108,13 @@ ohos_source_set("data_share_service") { deps = [ "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/service/common:distributeddata_common", + "${dataobsmgr_path}/interfaces:dataobs_manager", "../../framework:distributeddatasvcfwk", ] external_deps = [ "ability_base:want", "ability_runtime:ability_connect_callback_stub", - "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 6c30e699cca319d94bc18041cd4b386cf4fd712f..4ff440a82507291ca1b0384b00e2ad1c29b96b87 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -141,7 +141,7 @@ bool DataShareServiceImpl::NotifyChange(const std::string &uri, int32_t userId) { RadarReporter::RadarReport report(RadarReporter::NOTIFY_OBSERVER_DATA_CHANGE, RadarReporter::NOTIFY_DATA_CHANGE, __FUNCTION__); - auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance(); + auto obsMgrClient = DataObs::DataObsMgrClient::GetInstance(); if (obsMgrClient == nullptr) { ZLOGE("obsMgrClient is nullptr"); report.SetError(RadarReporter::DATA_OBS_EMPTY_ERROR); diff --git a/services/distributeddataservice/service/dataobsmgr/framework/BUILD.gn b/services/distributeddataservice/service/dataobsmgr/framework/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..dbdc5c6019d2237af9ebc7ce74ffa1c6ffb3de99 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/BUILD.gn @@ -0,0 +1,126 @@ +# Copyright (c) 2021-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/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") +import( + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/dataobsmgr/framework/dataobsms.gni") + +group("dataobsms_target") { + deps = [ ":dataobsms" ] +} + +config("dataobsms_config") { + include_dirs = [ "include/" ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } +} + +ohos_shared_library("dataobsms") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = dataobsms_files + + configs = [ ":dataobsms_config" ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:task_handler_wrap", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "image_framework:image_native", + "ipc:ipc_core", + "json:nlohmann_json_static", + "jsoncpp:jsoncpp", + "kv_store:datamgr_common", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + defines = [] + if (window_manager_use_sceneboard) { + external_deps += [ "window_manager:libwm_lite" ] + defines += [ "SCENE_BOARD_ENABLE" ] + } else { + external_deps += [ "window_manager:libwm" ] + } + + subsystem_name = "distributeddatamgr" + + part_name = "datamgr_service" +} + +# Note: Just for test +ohos_static_library("dataobsms_static") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = dataobsms_files + + configs = [ ":dataobsms_config" ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:task_handler_wrap", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "image_framework:image_native", + "ipc:ipc_core", + "json:nlohmann_json_static", + "jsoncpp:jsoncpp", + "kv_store:datamgr_common", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + defines = [] + if (window_manager_use_sceneboard) { + external_deps += [ "window_manager:libwm_lite" ] + defines += [ "SCENE_BOARD_ENABLE" ] + } else { + external_deps += [ "window_manager:libwm" ] + } + + subsystem_name = "distributeddatamgr" + + part_name = "datamgr_service" +} diff --git a/services/distributeddataservice/service/dataobsmgr/framework/dataobsms.gni b/services/distributeddataservice/service/dataobsmgr/framework/dataobsms.gni new file mode 100644 index 0000000000000000000000000000000000000000..353676254ec469f0f4c56fa106a64b259e6e7568 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/dataobsms.gni @@ -0,0 +1,26 @@ +# Copyright (c) 2021 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") +import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +dataobsms_files = [ + "src/dataobs_mgr_changeinfo.cpp", + "src/dataobs_mgr_inner.cpp", + "src/dataobs_mgr_inner_ext.cpp", + "src/dataobs_mgr_inner_pref.cpp", + "src/dataobs_mgr_proxy.cpp", + "src/dataobs_mgr_stub.cpp", + "src/dataobs_mgr_service.cpp", + "src/data_ability_observer_proxy.cpp", +] diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/common_utils.h b/services/distributeddataservice/service/dataobsmgr/framework/include/common_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..bdf9f6e7e7642f3e451a7e6852daa05067df173a --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/common_utils.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#ifndef DATAOBSSERVICE_COMMON_UTILS_H +#define DATAOBSSERVICE_COMMON_UTILS_H + +#include + +namespace OHOS { +namespace DataObs { +class CommonUtils { +public: + static std::string Anonymous(const std::string &name) + { + static constexpr uint32_t HEAD_SIZE = 6; + static constexpr int32_t END_SIZE = 5; + static constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; + static constexpr const char *REPLACE_CHAIN = "***"; + static constexpr const char *DEFAULT_ANONYMOUS = "******"; + if (name.length() <= HEAD_SIZE) { + return DEFAULT_ANONYMOUS; + } + + if (name.length() < MIN_SIZE) { + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN); + } + + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); + } +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_COMMON_UTILS_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/concurrent_map.h b/services/distributeddataservice/service/dataobsmgr/framework/include/concurrent_map.h new file mode 100644 index 0000000000000000000000000000000000000000..eb0e0a2bf29e09684cd800a14a07a5363f086b5d --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/concurrent_map.h @@ -0,0 +1,291 @@ +/* + * 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. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#include +#include +#include +namespace OHOS { +template class ConcurrentMap { + template static _First First(); + +public: + using map_type = typename std::map<_Key, _Tp>; + using filter_type = typename std::function; + using key_type = typename std::map<_Key, _Tp>::key_type; + using mapped_type = typename std::map<_Key, _Tp>::mapped_type; + using value_type = typename std::map<_Key, _Tp>::value_type; + using size_type = typename std::map<_Key, _Tp>::size_type; + using reference = typename std::map<_Key, _Tp>::reference; + using const_reference = typename std::map<_Key, _Tp>::const_reference; + + ConcurrentMap() = default; + ~ConcurrentMap() + { + Clear(); + } + + ConcurrentMap(const ConcurrentMap &other) + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(const ConcurrentMap &other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Clone(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + ConcurrentMap(ConcurrentMap &&other) noexcept + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(ConcurrentMap &&other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Steal(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + bool Emplace() noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(); + return it.second; + } + + template + typename std::enable_if()), filter_type>, bool>::type Emplace( + _Args &&... __args) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(std::forward<_Args>(__args)...); + return it.second; + } + + template + typename std::enable_if, bool>::type Emplace( + const _Filter &filter, _Args &&... __args) noexcept + { + std::lock_guard lock(mutex_); + if (!filter(entries_)) { + return false; + } + auto it = entries_.emplace(std::forward<_Args>(__args)...); + return it.second; + } + + std::pair Find(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return std::pair{ false, mapped_type() }; + } + + return std::pair{ true, it->second }; + } + + bool Contains(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + return (entries_.find(key) != entries_.end()); + } + + template bool InsertOrAssign(const key_type &key, _Obj &&obj) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert_or_assign(key, std::forward<_Obj>(obj)); + return it.second; + } + + bool Insert(const key_type &key, const mapped_type &value) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert(value_type{ key, value }); + return it.second; + } + + size_type Erase(const key_type &key) noexcept + { + std::lock_guard lock(mutex_); + return entries_.erase(key); + } + + void Clear() noexcept + { + std::lock_guard lock(mutex_); + return entries_.clear(); + } + + bool Empty() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.empty(); + } + + size_type Size() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.size(); + } + + // The action`s return true means meeting the erase condition + // The action`s return false means not meeting the erase condition + size_type EraseIf(const std::function &action) noexcept + { + if (action == nullptr) { + return 0; + } + std::lock_guard lock(mutex_); +#if __cplusplus > 201703L + auto count = std::erase_if( + entries_, [&action](value_type &value) -> bool { return action(value.first, value.second); }); +#else + auto count = entries_.size(); + for (auto it = entries_.begin(); it != entries_.end();) { + if (action((*it).first, (*it).second)) { + it = entries_.erase(it); + } else { + ++it; + } + } + count -= entries_.size(); +#endif + return count; + } + + void ForEach(const std::function &action) + { + if (action == nullptr) { + return; + } + std::lock_guard lock(mutex_); + for (auto &[key, value] : entries_) { + if (action(key, value)) { + break; + } + } + } + + void ForEachCopies(const std::function &action) + { + if (action == nullptr) { + return; + } + auto entries = Clone(); + for (auto &[key, value] : entries) { + if (action(key, value)) { + break; + } + } + } + + // The action's return value means that the element is keep in map or not; + // true means keeping, false means removing. + bool Compute(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + auto result = entries_.emplace(key, mapped_type()); + it = result.second ? result.first : entries_.end(); + } + if (it == entries_.end()) { + return false; + } + if (!action(it->first, it->second)) { + entries_.erase(key); + } + return true; + } + + // The action's return value means that the element is keep in map or not; + // true means keeping, false means removing. + bool ComputeIfPresent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return false; + } + if (!action(key, it->second)) { + entries_.erase(key); + } + return true; + } + + bool ComputeIfAbsent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it != entries_.end()) { + return false; + } + entries_.emplace(key, action(key)); + return true; + } + + void DoActionIfEmpty(const std::function &action) + { + if (action == nullptr) { + return; + } + std::lock_guard lock(mutex_); + if (entries_.empty()) { + action(); + } + return; + } + +private: + std::map<_Key, _Tp> Steal() noexcept + { + std::lock_guard lock(mutex_); + return std::move(entries_); + } + + std::map<_Key, _Tp> Clone() const noexcept + { + std::lock_guard lock(mutex_); + return entries_; + } + +private: + mutable std::recursive_mutex mutex_; + std::map<_Key, _Tp> entries_; +}; +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_CONCURRENT_MAP_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/data_ability_observer_proxy.h b/services/distributeddataservice/service/dataobsmgr/framework/include/data_ability_observer_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..9f0b3a0387dfbd31a3ab4be0b57333ab64aeb61f --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/data_ability_observer_proxy.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021-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. + */ +#ifndef DATAOBSSERVICE_DATA_ABILITY_OBSERVER_PROXY_H +#define DATAOBSSERVICE_DATA_ABILITY_OBSERVER_PROXY_H + +#include + +#include "data_ability_observer_interface.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +class DataAbilityObserverProxy : public IRemoteProxy { +public: + explicit DataAbilityObserverProxy(const sptr &remote); + virtual ~DataAbilityObserverProxy(); + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param uri Indicates the path of the data to operate. + */ + void OnChange() override; + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param changeInfo Indicates the info of the data to operate. + */ + void OnChangeExt(const ChangeInfo &changeInfo) override; + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param uri Indicates the path of the data to operate. + */ + void OnChangePreferences(const std::string &key) override; + +private: + static inline BrokerDelegator delegator_; + int32_t SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + void SetMessageOption(MessageOption &option); + uint32_t messageCount_ = 0; + std::mutex countMutex_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATA_ABILITY_OBSERVER_PROXY_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_log.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_log.h new file mode 100644 index 0000000000000000000000000000000000000000..ee806812eb976c54c44dc64115f4047e9851689b --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_log.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef DATAOBS_LOG_PRINT_H +#define DATAOBS_LOG_PRINT_H + +#include "hilog/log.h" + +namespace OHOS::DataObs { +static inline OHOS::HiviewDFX::HiLogLabel LogLabel() +{ + return { LOG_CORE, 0xD001661, "DataObs" }; +} +} // namespace OHOS::DataObs + +#define LOG_DEBUG(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_DEBUG)) { \ + ((void)HILOG_IMPL(lable.type, LogLevel::LOG_DEBUG, lable.domain, lable.tag, \ + "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ + } \ + } while (0) + +#define LOG_INFO(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_INFO)) { \ + ((void)HILOG_IMPL(lable.type, LogLevel::LOG_INFO, lable.domain, lable.tag, \ + "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ + } \ + } while (0) + +#define LOG_WARN(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_WARN)) { \ + ((void)HILOG_IMPL(lable.type, LogLevel::LOG_WARN, lable.domain, lable.tag, \ + "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ + } \ + } while (0) + +#define LOG_ERROR(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_ERROR)) { \ + ((void)HILOG_IMPL(lable.type, LogLevel::LOG_ERROR, lable.domain, lable.tag, \ + "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ + } \ + } while (0) + +#define LOG_FATAL(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_FATAL)) { \ + ((void)HILOG_IMPL(lable.type, LogLevel::LOG_FATAL, lable.domain, lable.tag, \ + "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ + } \ + } while (0) + +#endif // DATAOBS_LOG_PRINT_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..f88681415e02f7ae10e243d01acf7db18a5cfdd7 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_INNER_H +#define DATAOBSSERVICE_DATAOBS_MGR_INNER_H + +#include +#include +#include +#include +#include +#include + +#include "cpp/mutex.h" +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_inner_common.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +class DataObsMgrInner : public std::enable_shared_from_this { +public: + using ObsMapType = std::map>; + using ObsRecipientMapType = std::map, sptr>; + + DataObsMgrInner(); + virtual ~DataObsMgrInner(); + + int HandleRegisterObserver(const Uri &uri, struct ObserverNode observerNode); + int HandleUnregisterObserver(const Uri &uri, struct ObserverNode observerNode); + int HandleNotifyChange(const Uri &uri, int32_t userId); + void OnCallBackDied(const wptr &remote); + +private: + void AddObsDeathRecipient(sptr dataObserver); + void RemoveObsDeathRecipient(sptr dataObserver); + void RemoveObs(sptr dataObserver); + bool HaveRegistered(sptr dataObserver); + + static constexpr uint32_t OBS_NUM_MAX = 50; + ffrt::mutex innerMutex_; + ObsMapType observers_; + ObsRecipientMapType obsRecipient_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_common.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_common.h new file mode 100644 index 0000000000000000000000000000000000000000..b81b0af4c5f41c25c296d2ba26ee54383bf59e99 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_common.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_INNER_COMMON_H +#define DATAOBSSERVICE_DATAOBS_MGR_INNER_COMMON_H + +#include "data_ability_observer_interface.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +struct ObserverNode { + sptr observer_ = nullptr; + int32_t userId_ = -1; + + ObserverNode(sptr observer, int32_t userId) : observer_(observer), userId_(userId) + { + } + + bool operator==(struct ObserverNode other) const + { + return (observer_ == other.observer_) && (userId_ == other.userId_); + } +}; + +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_COMMON_H \ No newline at end of file diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_ext.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..e07663e01dc9450a6cb2b8ae2a51e3f7c8d248d7 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_ext.h @@ -0,0 +1,98 @@ +/* + * 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_INNER_EXT_H +#define DATAOBSSERVICE_DATAOBS_MGR_INNER_EXT_H + +#include +#include +#include +#include +#include +#include + +#include "cpp/mutex.h" +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_inner_common.h" +#include "iremote_object.h" +#include "refbase.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +class DataObsMgrInnerExt : public std::enable_shared_from_this { +public: + DataObsMgrInnerExt(); + virtual ~DataObsMgrInnerExt(); + + Status HandleRegisterObserver( + Uri &uri, sptr dataObserver, int32_t userId, bool isDescendants = false); + Status HandleUnregisterObserver(Uri &uri, sptr dataObserver); + Status HandleUnregisterObserver(sptr dataObserver); + Status HandleNotifyChange(const ChangeInfo &changeInfo, int32_t userId); + void OnCallBackDied(const wptr &remote); + +private: + struct DeathRecipientRef { + DeathRecipientRef(sptr deathRec) : deathRecipient(deathRec), ref(1) + { + } + sptr deathRecipient; + std::atomic ref; + }; + + struct Entry { + Entry(sptr obs, int32_t userId, std::shared_ptr deathRef, bool isDes) + : observer(obs), userId(userId), deathRecipientRef(deathRef), isDescendants(isDes) + { + } + sptr observer; + int32_t userId; + std::shared_ptr deathRecipientRef; + bool isDescendants; + }; + + using ObsMap = std::map, std::list>; + using EntryList = std::list; + + class Node { + public: + Node(const std::string &name); + void GetObs(const std::vector &path, uint32_t index, Uri &uri, int32_t userId, ObsMap &obsMap); + bool AddObserver(const std::vector &path, uint32_t index, const Entry &entry); + bool RemoveObserver( + const std::vector &path, uint32_t index, sptr dataObserver); + inline bool RemoveObserver(sptr dataObserver); + bool RemoveObserver(sptr dataObserver); + + private: + std::string name_; + EntryList entrys_; + std::map> childrens_; + }; + + std::shared_ptr AddObsDeathRecipient(const sptr &dataObserver); + void RemoveObsDeathRecipient(const sptr &dataObserver, bool isForce = false); + + static constexpr uint32_t OBS_NUM_MAX = 50; + + ffrt::mutex nodeMutex_; + std::shared_ptr root_; + std::map, std::shared_ptr> obsRecipientRefs; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_pref.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_pref.h new file mode 100644 index 0000000000000000000000000000000000000000..1f75bf94bc7badeea2c825fa4b0000ed5f0b3c96 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_inner_pref.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_PREF_H +#define DATAOBSSERVICE_DATAOBS_MGR_PREF_H + +#include +#include +#include +#include +#include +#include + +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_inner_common.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +class DataObsMgrInnerPref : public std::enable_shared_from_this { +public: + using ObsMapType = std::map>; + using ObsRecipientMapType = std::map, sptr>; + + DataObsMgrInnerPref(); + virtual ~DataObsMgrInnerPref(); + + int HandleRegisterObserver(const Uri &uri, struct ObserverNode observerNode); + int HandleUnregisterObserver(const Uri &uri, struct ObserverNode observerNode); + int HandleNotifyChange(const Uri &uri, int32_t userId); + void OnCallBackDied(const wptr &remote); + +private: + void AddObsDeathRecipient(sptr dataObserver); + void RemoveObsDeathRecipient(sptr dataObserver); + void RemoveObs(sptr dataObserver); + bool HaveRegistered(sptr dataObserver); + + static constexpr uint32_t OBS_NUM_MAX = 50; + std::mutex preferenceMutex_; + ObsMapType observers_; + ObsRecipientMapType obsRecipient_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_PREFERENCES_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_interface.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..007ee220702a93608fcba02019bb0d6d7b30a481 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_interface.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_INTERFACE_H +#define DATAOBSSERVICE_DATAOBS_MGR_INTERFACE_H + +#include +#include + +#include + +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_errors.h" +#include "idataobs_service.h" +#include "uri.h" + +namespace OHOS { +namespace DataObs { +using Uri = OHOS::Uri; +using namespace AAFwk; + +/** + * @class IDataObsMgr + * IDataObsMgr interface is used to access dataobs manager services. + */ +class IDataObsMgr { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataObs.DataObsMgr") + + enum { + TRANS_HEAD, + REGISTER_OBSERVER = TRANS_HEAD, + UNREGISTER_OBSERVER, + NOTIFY_CHANGE, + REGISTER_OBSERVER_EXT, + UNREGISTER_OBSERVER_EXT, + UNREGISTER_OBSERVER_ALL_EXT, + NOTIFY_CHANGE_EXT, + NOTIFY_PROCESS, + TRANS_BUTT, + }; + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int RegisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int UnregisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uri. + * + * @param uri, Indicates the path of the data to operate. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int NotifyChange(const Uri &uri, int32_t userId = -1, DataObsOption opt = DataObsOption()) = 0; + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * @param isDescendants, Indicates the Whether to note the change of + * descendants. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status RegisterObserverExt(const Uri &uri, sptr dataObserver, bool isDescendants, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters dataObserver used for DataObsMgr specified + * + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + sptr dataObserver, DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uris. + * + * @param changeInfo Indicates the info of the data to operate. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the process observer with the given progress key and cancel + observer. + * + * @param key Identifies the progress of a specific task. + + * @param observer Observer for monitoring the ongoing process. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()) = 0; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INTERFACE_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_proxy.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..6b41bc99fb8c2afe21a9ba8266be58d5f759c059 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_proxy.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021-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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_PROXY_H +#define DATAOBSSERVICE_DATAOBS_MGR_PROXY_H + +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_interface.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +/** + * @class DataObsManagerProxy + * DataObsManagerProxy. + */ +class DataObsManagerProxy : public IRemoteProxy { +public: + explicit DataObsManagerProxy(const sptr &impl) : IRemoteProxy(impl) + { + } + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + + virtual int RegisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) override; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int UnregisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) override; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uri. + * + * @param uri, Indicates the path of the data to operate. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int NotifyChange(const Uri &uri, int32_t userId = -1, DataObsOption opt = DataObsOption()) override; + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * @param isDescendants, Indicates the Whether to note the change of + * descendants. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status RegisterObserverExt(const Uri &uri, sptr dataObserver, bool isDescendants, + DataObsOption opt = DataObsOption()) override; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt = DataObsOption()) override; + + /** + * Deregisters dataObserver used for DataObsMgr specified + * + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + sptr dataObserver, DataObsOption opt = DataObsOption()) override; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uris. + * + * @param changeInfo Indicates the info of the data to operate. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt = DataObsOption()) override; + + /** + * Notifies the process observer with the given progress key and cancel + observer. + * + * @param key Identifies the progress of a specific task. + + * @param observer Observer for monitoring the ongoing process. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()) override; + +private: + bool WriteInterfaceToken(MessageParcel &data); + bool WriteParam(MessageParcel &data, const Uri &uri, sptr dataObserver); + bool WriteObsOpt(MessageParcel &data, DataObsOption opt); + int SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_PROXY_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_service.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_service.h new file mode 100644 index 0000000000000000000000000000000000000000..d870357d817d1dd4bf88dd0f881a64460786a0c9 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_service.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_SERVICE_H +#define DATAOBSSERVICE_DATAOBS_MGR_SERVICE_H + +#include +#include + +#include +#include + +#include "cpp/mutex.h" +#include "dataobs_mgr_inner.h" +#include "dataobs_mgr_inner_ext.h" +#include "dataobs_mgr_inner_pref.h" +#include "dataobs_mgr_stub.h" +#include "iremote_object.h" +#include "system_ability.h" +#include "task_handler_wrap.h" +#include "uri.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +constexpr char SHARE_PREFERENCES[] = "sharepreferences"; +/** + * @class DataObsMgrService + * DataObsMgrService provides a facility for dataobserver. + */ +class DataObsMgrService : public DataObsManagerStub, public std::enable_shared_from_this { +public: + using FeatureSystem = DistributedData::FeatureSystem; + using TaskHandlerWrap = AAFwk::TaskHandlerWrap; + using Handler = std::function> &)>; + DataObsMgrService(); + ~DataObsMgrService(); + int32_t OnInitialize() override; + std::pair ConstructObserverNode( + sptr dataObserver, int32_t userId = -1); + int RegisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) override; + int UnregisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) override; + int NotifyChange(const Uri &uri, int32_t userId = -1, DataObsOption opt = DataObsOption()) override; + Status RegisterObserverExt(const Uri &uri, sptr dataObserver, bool isDescendants, + DataObsOption opt = DataObsOption()) override; + Status UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt = DataObsOption()) override; + Status UnregisterObserverExt(sptr dataObserver, DataObsOption opt = DataObsOption()) override; + Status NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt = DataObsOption()) override; + Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()) override; + +private: + void Init(); + void RegisterDataObsServiceInfo(); + void RegisterHandler(); + static void DumpDataObsServiceInfo(int fd, std::map> ¶ms); + Status DeepCopyChangeInfo(const ChangeInfo &src, ChangeInfo &dst) const; + void GetFocusedAppInfo(int32_t &windowId, sptr &abilityToken) const; + sptr GetAbilityManagerService() const; + int32_t GetCallingUserId(); + +private: + class Factory { + public: + Factory(); + ~Factory(); + }; + static constexpr std::uint32_t TASK_COUNT_MAX = 50; + static Factory factory_; + ffrt::mutex taskCountMutex_; + std::uint32_t taskCount_ = 0; + std::shared_ptr handler_; + + std::shared_ptr dataObsMgrInner_; + std::shared_ptr dataObsMgrInnerExt_; + std::shared_ptr dataObsMgrInnerPref_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_SERVICE_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_stub.h b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..280ff0dad7f9ee16ec8ae6653b0c457d794e746a --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/dataobs_mgr_stub.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_STUB_H +#define DATAOBSSERVICE_DATAOBS_MGR_STUB_H + +#include +#include + +#include + +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_interface.h" +#include "feature/feature_system.h" + +namespace OHOS { +namespace DataObs { +/** + * @class DataObsManagerStub + * DataObsManagerStub. + */ +class DataObsManagerStub : public IDataObsMgr, public DistributedData::FeatureSystem::Feature { +public: + DataObsManagerStub(); + ~DataObsManagerStub(); + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; + void SetServiceReady(); + +private: + int32_t RegisterObserverInner(MessageParcel &data, MessageParcel &reply); + int32_t UnregisterObserverInner(MessageParcel &data, MessageParcel &reply); + int32_t NotifyChangeInner(MessageParcel &data, MessageParcel &reply); + int32_t RegisterObserverExtInner(MessageParcel &data, MessageParcel &reply); + int32_t UnregisterObserverExtInner(MessageParcel &data, MessageParcel &reply); + int32_t UnregisterObserverExtALLInner(MessageParcel &data, MessageParcel &reply); + int32_t NotifyChangeExtInner(MessageParcel &data, MessageParcel &reply); + int32_t NotifyProcessObserverInner(MessageParcel &data, MessageParcel &reply); + + using RequestFuncType = int32_t (DataObsManagerStub::*)(MessageParcel &data, MessageParcel &reply); + static const RequestFuncType HANDLES[TRANS_BUTT]; + static constexpr int SLEEP_TIME = 300; + static constexpr int TRY_TIMES = 5; + std::atomic isReady_ = false; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_STUB_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/idataobs_service.h b/services/distributeddataservice/service/dataobsmgr/framework/include/idataobs_service.h new file mode 100644 index 0000000000000000000000000000000000000000..2dfe89fbed6a74581d53256566bafdf163d8a9f6 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/idataobs_service.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_IDATAOBS_SERVICE_H +#define DATAOBSSERVICE_IDATAOBS_SERVICE_H + +#include +#include + +#include + +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_errors.h" +#include "uri.h" + +namespace OHOS { +namespace DataObs { +using Uri = OHOS::Uri; +using namespace AAFwk; + +struct DataObsOption { +private: + bool isSystem = false; + +public: + DataObsOption() + { + } + DataObsOption(bool isSystem) : isSystem(isSystem) + { + } + bool IsSystem() + { + return isSystem; + } +}; + +/** + * @class IDataObsMgr + * IDataObsMgr interface is used to access dataobs manager services. + */ +class IDataObsService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataObs.IDataObsService") + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int RegisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int UnregisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uri. + * + * @param uri, Indicates the path of the data to operate. + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int NotifyChange(const Uri &uri, int32_t userId = -1, DataObsOption opt = DataObsOption()) = 0; + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * @param isDescendants, Indicates the Whether to note the change of + * descendants. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status RegisterObserverExt(const Uri &uri, sptr dataObserver, bool isDescendants, + DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt = DataObsOption()) = 0; + + /** + * Deregisters dataObserver used for DataObsMgr specified + * + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status UnregisterObserverExt( + sptr dataObserver, DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uris. + * + * @param changeInfo Indicates the info of the data to operate. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt = DataObsOption()) = 0; + + /** + * Notifies the process observer with the given progress key and cancel + observer. + * + * @param key Identifies the progress of a specific task. + + * @param observer Observer for monitoring the ongoing process. + * + * @return Returns SUCCESS on success, others on failure. + */ + virtual Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()) = 0; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_IDATAOBS_SERVICE_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/include/ikvstore_dataobs_service.h b/services/distributeddataservice/service/dataobsmgr/framework/include/ikvstore_dataobs_service.h new file mode 100644 index 0000000000000000000000000000000000000000..1b47826fa922129b63456af1f0aefb1f85db6077 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/include/ikvstore_dataobs_service.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef IKVSTORE_DATAOBS_SERVICE_H +#define IKVSTORE_DATAOBS_SERVICE_H + +#include "iremote_broker.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DataObs { +enum class IKvStoreDataInterfaceCode { GET_FEATURE_INTERFACE = 0, REGISTERCLIENTDEATHOBSERVER }; +class IKvStoreDataObsService : public IRemoteBroker { +public: + virtual sptr GetFeatureInterface(const std::string &name) = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.IKvStoreDataObsService"); +}; + +class DataObsKvServiceProxy : public IRemoteProxy { +public: + explicit DataObsKvServiceProxy(const sptr &impl); + ~DataObsKvServiceProxy() = default; + sptr GetFeatureInterface(const std::string &name) override; +}; +} // namespace DataObs +} // namespace OHOS +#endif // IKVSTORE_DATAOBS_SERVICE_H diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_proxy.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4892cdab695d87d84b893ab804e025d59f6a044 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_proxy.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "data_ability_observer_proxy.h" + +#include "dataobs_log.h" +#include "message_parcel.h" + +namespace OHOS { +namespace DataObs { +static constexpr uint32_t MESSAGE_MAX_COUNT = 50; +DataAbilityObserverProxy::DataAbilityObserverProxy(const sptr &remote) + : IRemoteProxy(remote) +{ +} +DataAbilityObserverProxy::~DataAbilityObserverProxy() +{ +} + +/** + * @brief Set the message option. + * + * @param option Indicates the option of message. + */ +void DataAbilityObserverProxy::SetMessageOption(MessageOption &option) +{ + std::lock_guard lock(countMutex_); + // Send a wakeup IPC every 50 times. Otherwise, send a non-wakeup IPC. + if (messageCount_ >= MESSAGE_MAX_COUNT) { + option = MessageOption(MessageOption::TF_ASYNC); + messageCount_ = 0; + } else { + option = MessageOption(MessageOption::TF_ASYNC | MessageOption::TF_ASYNC_WAKEUP_LATER); + messageCount_++; + } +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @param uri Indicates the path of the data to operate. + */ +void DataAbilityObserverProxy::OnChange() +{ + OHOS::MessageParcel data; + OHOS::MessageParcel reply; + MessageOption option; + SetMessageOption(option); + + if (!data.WriteInterfaceToken(DataAbilityObserverProxy::GetDescriptor())) { + LOG_ERROR("write token false"); + return; + } + + int result = SendTransactCmd(IDataAbilityObserver::DATA_ABILITY_OBSERVER_CHANGE, data, reply, option); + if (result != ERR_NONE) { + LOG_ERROR("error,result:%{public}d", result); + } +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @param changeInfo Indicates the info of the data to operate. + */ +void DataAbilityObserverProxy::OnChangeExt(const ChangeInfo &changeInfo) +{ + OHOS::MessageParcel data; + OHOS::MessageParcel reply; + MessageOption option; + SetMessageOption(option); + + if (!data.WriteInterfaceToken(DataAbilityObserverProxy::GetDescriptor())) { + LOG_ERROR("write token false"); + return; + } + + if (!ChangeInfo::Marshalling(changeInfo, data)) { + LOG_ERROR("changeInfo marshalling fail"); + return; + } + + int result = SendTransactCmd(IDataAbilityObserver::DATA_ABILITY_OBSERVER_CHANGE_EXT, data, reply, option); + if (result != ERR_NONE) { + LOG_ERROR("error result:%{public}d", result); + } +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @param uri Indicates the path of the data to operate. + */ +void DataAbilityObserverProxy::OnChangePreferences(const std::string &key) +{ + OHOS::MessageParcel data; + OHOS::MessageParcel reply; + MessageOption option; + SetMessageOption(option); + + if (!data.WriteInterfaceToken(DataAbilityObserverProxy::GetDescriptor())) { + LOG_ERROR("write token false"); + return; + } + + if (!data.WriteString(key)) { + LOG_ERROR("write string false"); + return; + } + + int result = SendTransactCmd(IDataAbilityObserver::DATA_ABILITY_OBSERVER_CHANGE_PREFERENCES, data, reply, option); + if (result != ERR_NONE) { + LOG_ERROR("error result:%{public}d", result); + } +} + +int32_t DataAbilityObserverProxy::SendTransactCmd( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERROR("null remote"); + return ERR_NULL_OBJECT; + } + + return remote->SendRequest(code, data, reply, option); +} + +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_stub.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..886df57abe07e12527df6430dbdc5805d3126062 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/data_ability_observer_stub.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "data_ability_observer_stub.h" + +#include "common_utils.h" +#include "dataobs_log.h" +#include "ipc_skeleton.h" +#include "string_ex.h" + +namespace OHOS { +namespace AAFwk { +using namespace DataObs; +const DataAbilityObserverStub::RequestFuncType DataAbilityObserverStub::HANDLES[TRANS_BUTT] = { + &DataAbilityObserverStub::OnChangeInner, + &DataAbilityObserverStub::OnChangeExtInner, + &DataAbilityObserverStub::OnChangePreferencesInner, +}; + +DataAbilityObserverStub::DataAbilityObserverStub() +{ +} + +DataAbilityObserverStub::~DataAbilityObserverStub() +{ +} + +int DataAbilityObserverStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + LOG_DEBUG("code: %{public}d, flags: %{public}d, callingPid:%{public}d", code, option.GetFlags(), + IPCSkeleton::GetCallingPid()); + std::u16string descriptor = DataAbilityObserverStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + LOG_ERROR("local descriptor≠remote, descriptor:%{public}s, " + "remoteDescriptor:%{public}s", + CommonUtils::Anonymous(Str16ToStr8(descriptor)).c_str(), + CommonUtils::Anonymous(Str16ToStr8(remoteDescriptor)).c_str()); + return ERR_INVALID_STATE; + } + + if (code < TRANS_HEAD || code >= TRANS_BUTT || HANDLES[code] == nullptr) { + LOG_ERROR("invalid code:%u, BUTT:%d", code, TRANS_BUTT); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return (this->*HANDLES[code])(data, reply); +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @return Returns 0 on success, others on failure. + */ +int32_t DataAbilityObserverStub::OnChangeInner(MessageParcel &data, MessageParcel &reply) +{ + OnChange(); + return ERR_NONE; +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @return Returns 0 on success, others on failure. + */ +int32_t DataAbilityObserverStub::OnChangeExtInner(MessageParcel &data, MessageParcel &reply) +{ + ChangeInfo changeInfo; + if (!ChangeInfo::Unmarshalling(changeInfo, data)) { + return IPC_STUB_INVALID_DATA_ERR; + } + OnChangeExt(changeInfo); + return ERR_NONE; +} + +/** + * @brief Called back to notify that the data being observed has changed. + * + * @return Returns 0 on success, others on failure. + */ +int32_t DataAbilityObserverStub::OnChangePreferencesInner(MessageParcel &data, MessageParcel &reply) +{ + std::string key = data.ReadString(); + if (key.empty()) { + return IPC_STUB_INVALID_DATA_ERR; + } + OnChangePreferences(key); + return ERR_NONE; +} + +void DataObsCallbackRecipient::OnRemoteDied(const wptr &remote) +{ + if (handler_) { + handler_(remote); + } +} + +DataObsCallbackRecipient::DataObsCallbackRecipient(RemoteDiedHandler handler) : handler_(handler) +{ +} + +DataObsCallbackRecipient::~DataObsCallbackRecipient() +{ +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_changeinfo.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_changeinfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8bf7575132392bb4bf56894ccf6150e5babc37f1 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_changeinfo.cpp @@ -0,0 +1,112 @@ +/* + * 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. + */ +#include "dataobs_mgr_changeinfo.h" + +#include + +#include "dataobs_log.h" +#include "dataobs_utils.h" +#include "securec.h" + +namespace OHOS { +namespace AAFwk { +using namespace DataObs; +using Value = std::variant>; +using VBucket = std::map; +using VBuckets = std::vector; +bool ChangeInfo::Marshalling(const ChangeInfo &input, MessageParcel &parcel) +{ + if (!parcel.WriteUint32(static_cast(input.changeType_))) { + return false; + } + + if (input.uris_.size() > std::numeric_limits::max() + || !parcel.WriteUint32(static_cast(input.uris_.size()))) { + return false; + } + + for (auto const &uri : input.uris_) { + if (!parcel.WriteString(uri.ToString())) { + return false; + } + } + + if (!parcel.WriteUint32(input.size_)) { + return false; + } + + if (!(input.size_ == 0 || parcel.WriteBuffer(input.data_, input.size_))) { + return false; + } + + if (!DataObsUtils::Marshal(parcel, input.valueBuckets_)) { + return false; + } + return true; +} + +bool ChangeInfo::Unmarshalling(ChangeInfo &output, MessageParcel &parcel) +{ + uint32_t changeType; + if (!parcel.ReadUint32(changeType)) { + LOG_ERROR("Failed to read changeType from parcel."); + return false; + } + + uint32_t len = 0; + if (!parcel.ReadUint32(len)) { + LOG_ERROR("Failed to read uris size from parcel."); + return false; + } + if (len > LIST_MAX_COUNT) { + LOG_ERROR("Uris size exceeds LIST_MAX_COUNT."); + return false; + } + + std::list uris; + for (uint32_t i = 0; i < len; i++) { + Uri uri = Uri(parcel.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("The count:%{public}d uri is empty.", i); + return false; + } + uris.emplace_back(std::move(uri)); + } + + uint32_t size = 0; + if (!parcel.ReadUint32(size)) { + LOG_ERROR("Failed to read size from parcel."); + return false; + } + + const uint8_t *data = size > 0 ? parcel.ReadBuffer(size) : nullptr; + if (size > 0 && data == nullptr) { + LOG_ERROR("Failed to read buffer from parcel."); + return false; + } + VBuckets buckets; + if (!(DataObsUtils::Unmarshal(parcel, buckets))) { + LOG_ERROR("Failed to unmarshall valueBuckets from parcel."); + return false; + } + output.changeType_ = static_cast(changeType); + std::swap(output.uris_, uris); + output.data_ = const_cast(data); + output.size_ = size; + output.valueBuckets_ = std::move(buckets); + return true; +} +} // namespace DataObs +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_client.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b903f02cc83104b0b1f9646e6187626b321f8ce7 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_client.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "dataobs_mgr_client.h" + +#include +#include + +#include "common_utils.h" +#include "dataobs_log.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "system_ability_status_change_stub.h" + +namespace OHOS { +namespace DataObs { +std::mutex DataObsMgrClient::mutex_; + +void DataObsMgrClient::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) +{ + LOG_INFO("called"); + if (systemAbilityId != DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID) { + return; + } + Status errCode = GET_DATAOBS_SERVICE_FAILED; + do { + auto [errCode, _] = GetObsMgr(); + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + } while (errCode != SUCCESS); + GetInstance()->ReRegister(); +} + +std::shared_ptr DataObsMgrClient::GetInstance() +{ + static std::shared_ptr proxy = std::make_shared(); + proxy->callback_ = new (std::nothrow) DataObsClientStatusChangeStub(proxy.get()); + return proxy; +} + +DataObsMgrClient::DataObsMgrClient() +{ +} + +DataObsMgrClient::~DataObsMgrClient() +{ + if (dataMgrService_ != nullptr) { + auto dataobsMgr = std::shared_ptr(dataObsService_); + dataobsMgr->AsObject()->RemoveDeathRecipient(deathRecipient_); + } + sptr systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemManager == nullptr) { + LOG_ERROR("null systemmgr"); + return; + } + systemManager->UnSubscribeSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, callback_); +} + +/** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ +ErrCode DataObsMgrClient::RegisterObserver( + const Uri &uri, sptr dataObserver, int userId, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + LOG_ERROR("Failed to get ObsMgr, errCode: %{public}d.", errCode); + return DATAOBS_SERVICE_NOT_CONNECTED; + } + auto status = dataObsManger->RegisterObserver(uri, dataObserver, userId, opt); + if (status != NO_ERROR) { + return status; + } + observers_.Compute(dataObserver, [&uri, userId](const auto &key, auto &value) { + value.emplace_back(uri, userId); + return true; + }); + return status; +} + +/** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ +ErrCode DataObsMgrClient::UnregisterObserver( + const Uri &uri, sptr dataObserver, int userId, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + auto status = dataObsManger->UnregisterObserver(uri, dataObserver, userId, opt); + if (status != NO_ERROR) { + return status; + } + observers_.Compute(dataObserver, [&uri, userId](const auto &key, auto &value) { + value.remove_if([&uri, userId](const auto &val) { return uri == val.uri && userId == val.userId; }); + return !value.empty(); + }); + return status; +} + +/** + * Notifies the registered observers of a change to the data resource specified + * by Uri. + * + * @param uri, Indicates the path of the data to operate. + * + * @return Returns ERR_OK on success, others on failure. + */ +ErrCode DataObsMgrClient::NotifyChange(const Uri &uri, int userId, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + return dataObsManger->NotifyChange(uri, userId, opt); +} + +sptr DataObsMgrClient::GetDistributedDataManager() +{ + auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (manager == nullptr) { + LOG_ERROR("get system ability manager failed"); + return nullptr; + } + auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); + if (remoteObject == nullptr) { + LOG_ERROR("get distributed data manager failed"); + return nullptr; + } + sptr proxy = new (std::nothrow) DataObsKvServiceProxy(remoteObject); + if (proxy == nullptr) { + LOG_ERROR("new DataObsKvServiceProxy fail."); + return nullptr; + } + return proxy; +} + +sptr DataObsMgrClient::GetDataObsManagerProxy() +{ + if (dataMgrService_ == nullptr) { + dataMgrService_ = GetDistributedDataManager(); + } + if (dataMgrService_ == nullptr) { + LOG_ERROR("Get distributed data manager failed!"); + return nullptr; + } + auto remote = dataMgrService_->GetFeatureInterface("dataobs"); + if (remote == nullptr) { + LOG_ERROR("Get DataObs service failed!"); + return nullptr; + } + return iface_cast(remote); +} +/** + * Connect dataobs manager service. + * + * @return Returns SUCCESS on success, others on failure. + */ +__attribute__((no_sanitize("cfi"))) std::pair> DataObsMgrClient::GetObsMgr() +{ + std::lock_guard lock(mutex_); + if (dataObsService_ != nullptr) { + return std::make_pair(SUCCESS, dataObsService_); + } + + sptr service = GetDataObsManagerProxy(); + if (service == nullptr) { + return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr); + } + sptr serviceBase = service; + if (deathRecipient_ == nullptr) { + deathRecipient_ = new (std::nothrow) ServiceDeathRecipient(GetInstance().get()); + } + if (!serviceBase->AsObject()->AddDeathRecipient(deathRecipient_)) { + LOG_ERROR("add death recipient failed"); + } + LOG_DEBUG("add death recipient success"); + dataObsService_ = std::shared_ptr(service.GetRefPtr(), [](const auto *) {}); + return std::make_pair(SUCCESS, dataObsService_); +} + +Status DataObsMgrClient::RegisterObserverExt( + const Uri &uri, sptr dataObserver, bool isDescendants, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + auto status = dataObsManger->RegisterObserverExt(uri, dataObserver, isDescendants, opt); + if (status != SUCCESS) { + return status; + } + observerExts_.Compute(dataObserver, [&uri, isDescendants](const auto &key, auto &value) { + value.emplace_back(uri, isDescendants); + return true; + }); + return status; +} + +Status DataObsMgrClient::UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + auto status = dataObsManger->UnregisterObserverExt(uri, dataObserver); + if (status != SUCCESS) { + return status; + } + observerExts_.Compute(dataObserver, [&uri](const auto &key, auto &value) { + value.remove_if([&uri](const auto ¶m) { return uri == param.uri; }); + return !value.empty(); + }); + return status; +} + +Status DataObsMgrClient::UnregisterObserverExt(sptr dataObserver, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + auto status = dataObsManger->UnregisterObserverExt(dataObserver, opt); + if (status != SUCCESS) { + return status; + } + observerExts_.Erase(dataObserver); + return status; +} + +Status DataObsMgrClient::NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt) +{ + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + return dataObsManger->NotifyChangeExt(changeInfo, opt); +} + +Status DataObsMgrClient::NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt) +{ + if (key.empty() || observer == nullptr) { + LOG_ERROR("Null observer, key:%{public}s", key.c_str()); + return INVALID_PARAM; + } + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + return DATAOBS_SERVICE_NOT_CONNECTED; + } + return dataObsManger->NotifyProcessObserver(key, observer, opt); +} + +void DataObsMgrClient::ResetService() +{ + std::lock_guard lock(mutex_); + dataMgrService_ = nullptr; + dataObsService_ = nullptr; +} + +void DataObsMgrClient::OnRemoteDied() +{ + std::this_thread::sleep_for(std::chrono::seconds(RESUB_INTERVAL)); + ResetService(); + auto [errCode, dataObsManger] = GetObsMgr(); + if (errCode != SUCCESS) { + sptr systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemManager == nullptr) { + LOG_ERROR("null systemmgr"); + return; + } + systemManager->SubscribeSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, callback_); + return; + } + ReRegister(); +} + +void DataObsMgrClient::ReRegister() +{ + decltype(observers_) observers(std::move(observers_)); + observers_.Clear(); + observers.ForEach([this](const auto &key, const auto &value) { + for (const auto &val : value) { + auto ret = RegisterObserver(val.uri, key, val.userId); + if (ret != SUCCESS) { + LOG_ERROR("RegisterObserver failed, uri:%{public}s, ret:%{public}d", + CommonUtils::Anonymous(val.uri.ToString()).c_str(), ret); + } + } + return false; + }); + + decltype(observerExts_) observerExts(std::move(observerExts_)); + observerExts_.Clear(); + observerExts.ForEach([this](const auto &key, const auto &value) { + for (const auto ¶m : value) { + auto ret = RegisterObserverExt(param.uri, key, param.isDescendants); + if (ret != SUCCESS) { + LOG_ERROR("RegisterObserverExt failed, param.uri:%{public}s, " + "ret:%{public}d, param.isDescendants:%{public}d", + CommonUtils::Anonymous(param.uri.ToString()).c_str(), ret, param.isDescendants); + } + } + return false; + }); +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bdc6b9aa05fc60e9173d88e4a14a7c56c0cf1d6 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2021-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. + */ +#include "dataobs_mgr_inner.h" + +#include "common_utils.h" +#include "data_ability_observer_stub.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" + +namespace OHOS { +namespace DataObs { + +DataObsMgrInner::DataObsMgrInner() +{ +} + +DataObsMgrInner::~DataObsMgrInner() +{ +} + +int DataObsMgrInner::HandleRegisterObserver(const Uri &uri, struct ObserverNode observerNode) +{ + std::lock_guard lock(innerMutex_); + + auto [obsPair, flag] = observers_.try_emplace(uri.ToString(), std::list()); + if (!flag && obsPair->second.size() > OBS_NUM_MAX) { + LOG_ERROR("subscribers num:%{public}s maxed", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_OBS_LIMMIT; + } + + for (auto obs = obsPair->second.begin(); obs != obsPair->second.end(); obs++) { + if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) { + LOG_ERROR("obs registered:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return OBS_EXIST; + } + } + + obsPair->second.push_back(observerNode); + + AddObsDeathRecipient(observerNode.observer_); + + return NO_ERROR; +} + +int DataObsMgrInner::HandleUnregisterObserver(const Uri &uri, struct ObserverNode observerNode) +{ + std::lock_guard lock(innerMutex_); + + auto obsPair = observers_.find(uri.ToString()); + if (obsPair == observers_.end()) { + LOG_WARN("uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + + LOG_DEBUG("obs num:%{public}zu:%{public}s", obsPair->second.size(), CommonUtils::Anonymous(uri.ToString()).c_str()); + auto obs = obsPair->second.begin(); + for (; obs != obsPair->second.end(); obs++) { + if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) { + break; + } + } + if (obs == obsPair->second.end()) { + LOG_WARN("uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + obsPair->second.remove(*obs); + if (obsPair->second.empty()) { + observers_.erase(obsPair); + } + + if (!HaveRegistered(observerNode.observer_)) { + RemoveObsDeathRecipient(observerNode.observer_->AsObject()); + } + + return NO_ERROR; +} + +int DataObsMgrInner::HandleNotifyChange(const Uri &uri, int32_t userId) +{ + std::list obsList; + std::lock_guard lock(innerMutex_); + { + auto obsPair = observers_.find(uri.ToString()); + if (obsPair == observers_.end()) { + LOG_DEBUG("uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + obsList = obsPair->second; + } + + for (auto &obs : obsList) { + if (obs.observer_ == nullptr) { + continue; + } + if (obs.userId_ != 0 && userId != 0 && obs.userId_ != userId) { + LOG_WARN("Not allow across user notify, %{public}d to %{public}d, %{public}s", userId, obs.userId_, + CommonUtils::Anonymous(uri.ToString()).c_str()); + continue; + } + obs.observer_->OnChange(); + } + + LOG_DEBUG("uri end:%{public}s,obs num:%{public}zu", CommonUtils::Anonymous(uri.ToString()).c_str(), obsList.size()); + return NO_ERROR; +} + +void DataObsMgrInner::AddObsDeathRecipient(sptr dataObserver) +{ + if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) { + return; + } + + auto it = obsRecipient_.find(dataObserver->AsObject()); + if (it != obsRecipient_.end()) { + LOG_WARN("called"); + return; + } else { + std::weak_ptr thisWeakPtr(shared_from_this()); + sptr deathRecipient = + new DataObsCallbackRecipient([thisWeakPtr](const wptr &remote) { + auto dataObsMgrInner = thisWeakPtr.lock(); + if (dataObsMgrInner) { + dataObsMgrInner->OnCallBackDied(remote); + } + }); + if (!dataObserver->AsObject()->AddDeathRecipient(deathRecipient)) { + LOG_ERROR("failed"); + } + obsRecipient_.emplace(dataObserver->AsObject(), deathRecipient); + } +} + +void DataObsMgrInner::RemoveObsDeathRecipient(sptr dataObserver) +{ + if (dataObserver == nullptr) { + return; + } + + auto it = obsRecipient_.find(dataObserver); + if (it != obsRecipient_.end()) { + it->first->RemoveDeathRecipient(it->second); + obsRecipient_.erase(it); + return; + } +} + +void DataObsMgrInner::OnCallBackDied(const wptr &remote) +{ + auto dataObserver = remote.promote(); + if (dataObserver == nullptr) { + return; + } + std::lock_guard lock(innerMutex_); + + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver"); + return; + } + + RemoveObs(dataObserver); +} + +// remove dataObserver of all users +void DataObsMgrInner::RemoveObs(sptr dataObserver) +{ + for (auto iter = observers_.begin(); iter != observers_.end();) { + auto &obsList = iter->second; + for (auto it = obsList.begin(); it != obsList.end(); it++) { + if ((*it).observer_->AsObject() == dataObserver) { + LOG_DEBUG("erase"); + obsList.erase(it); + break; + } + } + if (obsList.size() == 0) { + iter = observers_.erase(iter); + } else { + iter++; + } + } + RemoveObsDeathRecipient(dataObserver); +} + +bool DataObsMgrInner::HaveRegistered(sptr dataObserver) +{ + for (auto &[key, value] : observers_) { + for (struct ObserverNode &node : value) { + if (node.observer_ == dataObserver) { + return true; + } + } + } + return false; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_ext.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_ext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4d6317fc83ed1ac055fcfdae90bdfa7b9fc2e8d --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_ext.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2021-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. + */ +#include "dataobs_mgr_inner_ext.h" + +#include "common_utils.h" +#include "data_ability_observer_stub.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" + +namespace OHOS { +namespace DataObs { + +DataObsMgrInnerExt::DataObsMgrInnerExt() : root_(std::make_shared("root")) +{ +} + +DataObsMgrInnerExt::~DataObsMgrInnerExt() +{ +} + +Status DataObsMgrInnerExt::HandleRegisterObserver( + Uri &uri, sptr dataObserver, int32_t userId, bool isDescendants) +{ + if (dataObserver->AsObject() == nullptr) { + return DATA_OBSERVER_IS_NULL; + } + std::lock_guard lock(nodeMutex_); + auto deathRecipientRef = AddObsDeathRecipient(dataObserver->AsObject()); + if (deathRecipientRef == nullptr) { + return DATAOBS_SERVICE_OBS_LIMMIT; + } + + std::vector path = { uri.GetScheme(), uri.GetAuthority() }; + uri.GetPathSegments(path); + if (root_ != nullptr + && !root_->AddObserver(path, 0, Entry(dataObserver, userId, deathRecipientRef, isDescendants))) { + LOG_ERROR("subscribers:%{public}s num maxed", CommonUtils::Anonymous(uri.ToString()).c_str()); + RemoveObsDeathRecipient(dataObserver->AsObject()); + return DATAOBS_SERVICE_OBS_LIMMIT; + } + return SUCCESS; +} + +Status DataObsMgrInnerExt::HandleUnregisterObserver(Uri &uri, sptr dataObserver) +{ + if (dataObserver->AsObject() == nullptr) { + LOG_ERROR("null dataObserver, uri:%{public}s num maxed", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + std::lock_guard lock(nodeMutex_); + std::vector path = { uri.GetScheme(), uri.GetAuthority() }; + uri.GetPathSegments(path); + if (root_ != nullptr) { + root_->RemoveObserver(path, 0, dataObserver); + } + RemoveObsDeathRecipient(dataObserver->AsObject()); + return SUCCESS; +} + +Status DataObsMgrInnerExt::HandleUnregisterObserver(sptr dataObserver) +{ + if (dataObserver->AsObject() == nullptr) { + LOG_ERROR("null dataObserver"); + return DATA_OBSERVER_IS_NULL; + } + std::lock_guard lock(nodeMutex_); + if (root_ != nullptr) { + root_->RemoveObserver(dataObserver); + } + RemoveObsDeathRecipient(dataObserver->AsObject(), true); + return SUCCESS; +} + +Status DataObsMgrInnerExt::HandleNotifyChange(const ChangeInfo &changeInfo, int32_t userId) +{ + ObsMap changeRes; + std::vector path; + { + std::lock_guard lock(nodeMutex_); + for (auto &uri : changeInfo.uris_) { + path.clear(); + path.emplace_back(uri.GetScheme()); + path.emplace_back(uri.GetAuthority()); + uri.GetPathSegments(path); + root_->GetObs(path, 0, uri, userId, changeRes); + } + } + if (changeRes.empty()) { + LOG_DEBUG("uris no obs, changeType:%{public}ud, uris num:%{public}zu," + "null data:%{public}d, size:%{public}ud", + changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_); + return NO_OBS_FOR_URI; + } + for (const auto &[obs, value] : changeRes) { + if (obs != nullptr && !value.empty()) { + obs->OnChangeExt( + { changeInfo.changeType_, move(value), changeInfo.data_, changeInfo.size_, changeInfo.valueBuckets_ }); + } + } + + return SUCCESS; +} + +std::shared_ptr DataObsMgrInnerExt::AddObsDeathRecipient( + const sptr &dataObserver) +{ + auto it = obsRecipientRefs.find(dataObserver); + if (it != obsRecipientRefs.end()) { + if (std::numeric_limits::max() - 1 < it->second->ref) { + LOG_ERROR("observer num maxed"); + return nullptr; + } + } else { + std::weak_ptr thisWeakPtr(shared_from_this()); + sptr deathRecipient = + new DataObsCallbackRecipient([thisWeakPtr](const wptr &remote) { + auto DataObsMgrInnerExt = thisWeakPtr.lock(); + if (DataObsMgrInnerExt) { + DataObsMgrInnerExt->OnCallBackDied(remote); + } + }); + dataObserver->AddDeathRecipient(deathRecipient); + it = obsRecipientRefs.emplace(dataObserver, std::make_shared(deathRecipient)).first; + } + LOG_DEBUG("add observer, sum:%{public}ud", it->second->ref.load(std::memory_order_relaxed)); + return it->second; +} + +void DataObsMgrInnerExt::RemoveObsDeathRecipient(const sptr &dataObserver, bool isForce) +{ + auto it = obsRecipientRefs.find(dataObserver); + if (it == obsRecipientRefs.end()) { + return; + } + + if (isForce || it->second->ref <= 1) { + LOG_DEBUG("remove deathRecipient, sum:%{public}ud", it->second->ref.load(std::memory_order_relaxed)); + dataObserver->RemoveDeathRecipient(it->second->deathRecipient); + obsRecipientRefs.erase(it); + return; + } +} + +void DataObsMgrInnerExt::OnCallBackDied(const wptr &remote) +{ + LOG_DEBUG("observer died"); + auto dataObserver = remote.promote(); + if (dataObserver == nullptr) { + return; + } + std::lock_guard lock(nodeMutex_); + if (root_ != nullptr) { + root_->RemoveObserver(dataObserver); + } + RemoveObsDeathRecipient(dataObserver, true); +} + +DataObsMgrInnerExt::Node::Node(const std::string &name) : name_(name) +{ +} + +void DataObsMgrInnerExt::Node::GetObs( + const std::vector &path, uint32_t index, Uri &uri, int32_t userId, ObsMap &obsRes) +{ + if (path.size() == index) { + for (auto entry : entrys_) { + if (entry.userId != userId && entry.userId != 0 && userId != 0) { + LOG_WARN("Not allow across user notify, uri:%{public}s, from %{public}d to" + "%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), userId, entry.userId); + continue; + } + obsRes.try_emplace(entry.observer, std::list()).first->second.push_back(uri); + } + return; + } + + for (const auto &entry : entrys_) { + if (entry.isDescendants) { + if (entry.userId != userId && entry.userId != 0 && userId != 0) { + LOG_WARN("Not allow across user notify, uri:%{public}s, from %{public}d to" + "%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), userId, entry.userId); + continue; + } + obsRes.try_emplace(entry.observer, std::list()).first->second.push_back(uri); + } + } + + auto it = childrens_.find(path[index]); + if (it == childrens_.end()) { + return; + } + it->second->GetObs(path, ++index, uri, userId, obsRes); + + return; +} + +bool DataObsMgrInnerExt::Node::AddObserver(const std::vector &path, uint32_t index, const Entry &entry) +{ + if (path.size() == index) { + if (entrys_.size() >= OBS_NUM_MAX) { + return false; + } + entry.deathRecipientRef->ref++; + entrys_.emplace_back(entry); + return true; + } + auto it = childrens_.try_emplace(path[index], std::make_shared(path[index])).first; + return it->second->AddObserver(path, ++index, entry); +} + +bool DataObsMgrInnerExt::Node::RemoveObserver( + const std::vector &path, uint32_t index, sptr dataObserver) +{ + if (index == path.size()) { + entrys_.remove_if([dataObserver](const Entry &entry) { + if (entry.observer->AsObject() != dataObserver->AsObject()) { + return false; + } + entry.deathRecipientRef->ref--; + return true; + }); + return entrys_.empty() && childrens_.empty(); + } + auto child = childrens_.find(path[index]); + if (child != childrens_.end() && child->second->RemoveObserver(path, ++index, dataObserver)) { + childrens_.erase(child); + } + return entrys_.empty() && childrens_.empty(); +} + +// remove observer of all users +bool DataObsMgrInnerExt::Node::RemoveObserver(sptr dataObserver) +{ + for (auto child = childrens_.begin(); child != childrens_.end();) { + if (child->second->RemoveObserver(dataObserver)) { + child = childrens_.erase(child); + } else { + child++; + } + } + entrys_.remove_if([dataObserver](const Entry &entry) { + if (entry.observer->AsObject() != dataObserver) { + return false; + } + entry.deathRecipientRef->ref--; + return true; + }); + return entrys_.empty() && childrens_.empty(); +} + +inline bool DataObsMgrInnerExt::Node::RemoveObserver(sptr dataObserver) +{ + auto obs = dataObserver->AsObject(); + return obs != nullptr && RemoveObserver(obs); +} + +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_pref.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_pref.cpp new file mode 100644 index 0000000000000000000000000000000000000000..efc1b998480e7511b58f8fb5bf524443a243b005 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_inner_pref.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2021-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. + */ +#include "dataobs_mgr_inner_pref.h" + +#include "common_utils.h" +#include "data_ability_observer_stub.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" + +namespace OHOS { +namespace DataObs { + +DataObsMgrInnerPref::DataObsMgrInnerPref() +{ +} + +DataObsMgrInnerPref::~DataObsMgrInnerPref() +{ +} + +int DataObsMgrInnerPref::HandleRegisterObserver(const Uri &uri, struct ObserverNode observerNode) +{ + std::lock_guard lock(preferenceMutex_); + + auto [obsPair, flag] = observers_.try_emplace(uri.ToString(), std::list()); + if (!flag && obsPair->second.size() > OBS_NUM_MAX) { + LOG_ERROR("subscribers num:%{public}s num maxed", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_OBS_LIMMIT; + } + + for (auto obs = obsPair->second.begin(); obs != obsPair->second.end(); obs++) { + if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) { + LOG_ERROR("registered obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return OBS_EXIST; + } + } + + obsPair->second.push_back(observerNode); + + AddObsDeathRecipient(observerNode.observer_); + + return NO_ERROR; +} + +int DataObsMgrInnerPref::HandleUnregisterObserver(const Uri &uri, struct ObserverNode observerNode) +{ + std::lock_guard lock(preferenceMutex_); + + auto obsPair = observers_.find(uri.ToString()); + if (obsPair == observers_.end()) { + LOG_WARN("uris no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + + LOG_DEBUG("obs num:%{public}zu:%{public}s", obsPair->second.size(), CommonUtils::Anonymous(uri.ToString()).c_str()); + auto obs = obsPair->second.begin(); + for (; obs != obsPair->second.end(); obs++) { + if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) { + break; + } + } + if (obs == obsPair->second.end()) { + LOG_WARN("uris no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + obsPair->second.remove(*obs); + if (obsPair->second.empty()) { + observers_.erase(obsPair); + } + + if (!HaveRegistered(observerNode.observer_)) { + RemoveObsDeathRecipient(observerNode.observer_->AsObject()); + } + return NO_ERROR; +} + +int DataObsMgrInnerPref::HandleNotifyChange(const Uri &uri, int32_t userId) +{ + std::list obsList; + std::lock_guard lock(preferenceMutex_); + { + std::string uriStr = uri.ToString(); + size_t pos = uriStr.find('?'); + if (pos == std::string::npos) { + LOG_WARN("uri missing query:%{public}s", CommonUtils::Anonymous(uriStr).c_str()); + return INVALID_PARAM; + } + std::string observerKey = uriStr.substr(0, pos); + auto obsPair = observers_.find(observerKey); + if (obsPair == observers_.end()) { + LOG_DEBUG("uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + obsList = obsPair->second; + } + + for (auto &obs : obsList) { + if (obs.observer_ == nullptr) { + continue; + } + if (obs.userId_ != 0 && userId != 0 && obs.userId_ != userId) { + LOG_WARN("Not allow across user notify, %{public}d to %{public}d, %{public}s", userId, obs.userId_, + CommonUtils::Anonymous(uri.ToString()).c_str()); + continue; + } + obs.observer_->OnChangePreferences(const_cast(uri).GetQuery()); + } + + LOG_DEBUG("uri end:%{public}s,obs num:%{public}zu", CommonUtils::Anonymous(uri.ToString()).c_str(), obsList.size()); + return NO_ERROR; +} + +void DataObsMgrInnerPref::AddObsDeathRecipient(sptr dataObserver) +{ + if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) { + return; + } + + auto it = obsRecipient_.find(dataObserver->AsObject()); + if (it != obsRecipient_.end()) { + LOG_WARN("called"); + return; + } else { + std::weak_ptr thisWeakPtr(shared_from_this()); + sptr deathRecipient = + new DataObsCallbackRecipient([thisWeakPtr](const wptr &remote) { + auto dataObsMgrInner = thisWeakPtr.lock(); + if (dataObsMgrInner) { + dataObsMgrInner->OnCallBackDied(remote); + } + }); + if (!dataObserver->AsObject()->AddDeathRecipient(deathRecipient)) { + LOG_ERROR("failed"); + } + obsRecipient_.emplace(dataObserver->AsObject(), deathRecipient); + } +} + +void DataObsMgrInnerPref::RemoveObsDeathRecipient(sptr dataObserver) +{ + if (dataObserver == nullptr) { + return; + } + + auto it = obsRecipient_.find(dataObserver); + if (it != obsRecipient_.end()) { + it->first->RemoveDeathRecipient(it->second); + obsRecipient_.erase(it); + return; + } +} + +void DataObsMgrInnerPref::OnCallBackDied(const wptr &remote) +{ + auto dataObserver = remote.promote(); + if (dataObserver == nullptr) { + return; + } + std::lock_guard lock(preferenceMutex_); + + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver"); + return; + } + + RemoveObs(dataObserver); +} + +void DataObsMgrInnerPref::RemoveObs(sptr dataObserver) +{ + for (auto iter = observers_.begin(); iter != observers_.end();) { + auto &obsList = iter->second; + for (auto it = obsList.begin(); it != obsList.end(); it++) { + if ((*it).observer_->AsObject() == dataObserver) { + LOG_DEBUG("erase"); + obsList.erase(it); + break; + } + } + if (obsList.size() == 0) { + iter = observers_.erase(iter); + } else { + iter++; + } + } + RemoveObsDeathRecipient(dataObserver); +} + +bool DataObsMgrInnerPref::HaveRegistered(sptr dataObserver) +{ + for (auto &[key, value] : observers_) { + for (struct ObserverNode &node : value) { + if (node.observer_ == dataObserver) { + return true; + } + } + } + return false; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_proxy.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b61817af357de638e8d1e77a4a2ea793df51970e --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_proxy.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "dataobs_mgr_proxy.h" + +#include "common_utils.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" +#include "errors.h" +#include "idataobs_service.h" + +namespace OHOS { +namespace DataObs { +bool DataObsManagerProxy::WriteInterfaceToken(MessageParcel &data) +{ + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + LOG_ERROR("write token error"); + return false; + } + return true; +} + +bool DataObsManagerProxy::WriteParam(MessageParcel &data, const Uri &uri, sptr dataObserver) +{ + if (!data.WriteString(uri.ToString())) { + LOG_ERROR("write uri error"); + return false; + } + + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver"); + return false; + } + + if (!data.WriteRemoteObject(dataObserver->AsObject())) { + LOG_ERROR("write dataObserver error"); + return false; + } + return true; +} + +bool DataObsManagerProxy::WriteObsOpt(MessageParcel &data, DataObsOption opt) +{ + if (!data.WriteBool(opt.IsSystem())) { + LOG_ERROR("write opt error"); + return false; + } + return true; +} + +int32_t DataObsManagerProxy::RegisterObserver( + const Uri &uri, sptr dataObserver, int32_t userId, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!WriteParam(data, uri, dataObserver)) { + return INVALID_PARAM; + } + if (!data.WriteInt32(userId)) { + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::REGISTER_OBSERVER, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR( + "sendRequest error:%{public}d, uri:%{public}s", error, CommonUtils::Anonymous(uri.ToString()).c_str()); + return error; + } + + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? res : IPC_ERROR; +} + +int32_t DataObsManagerProxy::UnregisterObserver( + const Uri &uri, sptr dataObserver, int32_t userId, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!WriteParam(data, uri, dataObserver)) { + return INVALID_PARAM; + } + if (!data.WriteInt32(userId)) { + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::UNREGISTER_OBSERVER, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR( + "sendRequest error:%{public}d, uri:%{public}s", error, CommonUtils::Anonymous(uri.ToString()).c_str()); + return error; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? res : IPC_ERROR; +} + +int32_t DataObsManagerProxy::NotifyChange(const Uri &uri, int32_t userId, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + if (!data.WriteString(uri.ToString())) { + LOG_ERROR("write uri error, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return INVALID_PARAM; + } + if (!data.WriteInt32(userId)) { + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + auto error = SendTransactCmd(IDataObsMgr::NOTIFY_CHANGE, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR( + "sendRequest error:%{public}d, uri:%{public}s", error, CommonUtils::Anonymous(uri.ToString()).c_str()); + return IPC_ERROR; + } + + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? res : IPC_ERROR; +} + +Status DataObsManagerProxy::RegisterObserverExt( + const Uri &uri, sptr dataObserver, bool isDescendants, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!WriteParam(data, uri, dataObserver)) { + return INVALID_PARAM; + } + + if (!data.WriteBool(isDescendants)) { + LOG_ERROR("isDescendants error, uri:%{public}s,isDescendants:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants); + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::REGISTER_OBSERVER_EXT, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR("sendRequest error: %{public}d, uri:%{public}s, " + "isDescendants:%{public}d", + error, CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants); + return IPC_ERROR; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? static_cast(res) : IPC_ERROR; +} + +Status DataObsManagerProxy::UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!WriteParam(data, uri, dataObserver)) { + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::UNREGISTER_OBSERVER_EXT, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR( + "sendRequest error:%{public}d, uri:%{public}s", error, CommonUtils::Anonymous(uri.ToString()).c_str()); + return IPC_ERROR; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? static_cast(res) : IPC_ERROR; +} + +Status DataObsManagerProxy::UnregisterObserverExt(sptr dataObserver, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver"); + return INVALID_PARAM; + } + + if (!data.WriteRemoteObject(dataObserver->AsObject())) { + LOG_ERROR("write dataObserver error"); + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::UNREGISTER_OBSERVER_ALL_EXT, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR("sendRequest error:%{public}d", error); + return IPC_ERROR; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? static_cast(res) : IPC_ERROR; +} + +Status DataObsManagerProxy::NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!ChangeInfo::Marshalling(changeInfo, data)) { + LOG_ERROR("changeInfo marshalling error, changeType:%{public}ud, num:%{public}zu," + "null data:%{public}d, size:%{public}ud", + changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_); + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::NOTIFY_CHANGE_EXT, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR("sendRequest error: %{public}d, changeType:%{public}ud, " + "num:%{public}zu," + "null data:%{public}d, size:%{public}ud", + error, changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_); + return IPC_ERROR; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? static_cast(res) : IPC_ERROR; +} + +Status DataObsManagerProxy::NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return IPC_PARCEL_ERROR; + } + + if (!data.WriteString(key)) { + LOG_ERROR("write key error"); + return INVALID_PARAM; + } + + if (!data.WriteRemoteObject(observer)) { + LOG_ERROR("write observer error"); + return INVALID_PARAM; + } + if (!WriteObsOpt(data, opt)) { + return INVALID_PARAM; + } + + auto error = SendTransactCmd(IDataObsMgr::NOTIFY_PROCESS, data, reply, option); + if (error != NO_ERROR) { + LOG_ERROR("sendRequest error: %{public}d, key:%{public}s", error, key.c_str()); + return IPC_ERROR; + } + int32_t res = IPC_ERROR; + return reply.ReadInt32(res) ? static_cast(res) : IPC_ERROR; +} + +int32_t DataObsManagerProxy::SendTransactCmd( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERROR("null remote"); + return ERR_NULL_OBJECT; + } + + int32_t ret = remote->SendRequest(code, data, reply, option); + if (ret != NO_ERROR) { + LOG_ERROR("sendRequest errorCode:%{public}d, ret:%{public}d", code, ret); + return ret; + } + return NO_ERROR; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_service.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46b2e01119d6045d09d85855c135f7f24aaf3487 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_service.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "dataobs_mgr_service.h" + +#include + +#include +#include +#include +#include + +#include "ability_connect_callback_stub.h" +#include "ability_manager_interface.h" +#include "ability_manager_proxy.h" +#include "accesstoken_kit.h" +#include "common_utils.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" +#include "dump/dump_manager.h" +#include "if_system_ability_manager.h" +#include "in_process_call_wrapper.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "securec.h" +#include "tokenid_kit.h" +#include "want.h" +#ifdef SCENE_BOARD_ENABLE +#include "window_manager_lite.h" +#else +#include "window_manager.h" +#endif + +namespace OHOS { +namespace DataObs { +using DumpManager = OHOS::DistributedData::DumpManager; +__attribute__((used)) DataObsMgrService::Factory DataObsMgrService::factory_; + +static constexpr const char *DIALOG_APP = "com.ohos.pasteboarddialog"; +static constexpr const char *PROGRESS_ABILITY = "PasteboardProgressAbility"; +static constexpr const char *PROMPT_TEXT = "PromptText_PasteBoard_Local"; +static constexpr int32_t ABILITY_MGR_SERVICE_ID = 180; + +DataObsMgrService::Factory::Factory() +{ + FeatureSystem::GetInstance().RegisterCreator("dataobs", []() { return std::make_shared(); }); +} + +DataObsMgrService::Factory::~Factory() +{ +} + +DataObsMgrService::DataObsMgrService() +{ + dataObsMgrInner_ = std::make_shared(); + dataObsMgrInnerExt_ = std::make_shared(); + dataObsMgrInnerPref_ = std::make_shared(); +} + +DataObsMgrService::~DataObsMgrService() +{ + DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); +} + +int32_t DataObsMgrService::OnInitialize() +{ + Init(); + SetServiceReady(); + + LOG_INFO("OnInitialize dataObs service end"); + return 0; +} + +void DataObsMgrService::RegisterDataObsServiceInfo() +{ + DumpManager::Config serviceInfoConfig; + serviceInfoConfig.fullCmd = "--feature-info"; + serviceInfoConfig.abbrCmd = "-f"; + serviceInfoConfig.dumpName = "FEATURE_INFO"; + serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; + DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); +} + +void DataObsMgrService::RegisterHandler() +{ + Handler handler = [](int fd, std::map> ¶ms) { + DumpDataObsServiceInfo(fd, params); + }; + DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); +} + +void DataObsMgrService::DumpDataObsServiceInfo(int fd, std::map> ¶ms) +{ + (void)params; + std::string info; + dprintf(fd, + "-------------------------------------DataObsServiceInfo-------------" + "-----------------\n%s\n", + info.c_str()); +} + +void DataObsMgrService::Init() +{ + RegisterDataObsServiceInfo(); + RegisterHandler(); + handler_ = TaskHandlerWrap::GetFfrtHandler(); + SetServiceReady(); +} + +std::pair DataObsMgrService::ConstructObserverNode( + sptr dataObserver, int32_t userId) +{ + if (userId == -1) { + userId = GetCallingUserId(); + } + if (userId == -1) { + return std::make_pair(false, ObserverNode(dataObserver, userId)); + } + return std::make_pair(true, ObserverNode(dataObserver, userId)); +} + +int32_t DataObsMgrService::GetCallingUserId() +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); + if (type == Security::AccessToken::TOKEN_NATIVE || type == Security::AccessToken::TOKEN_SHELL) { + return 0; + } else { + Security::AccessToken::HapTokenInfo tokenInfo; + auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (result != Security::AccessToken::RET_SUCCESS) { + LOG_ERROR("token:0x%{public}x, result:%{public}d", tokenId, result); + return -1; + } + return tokenInfo.userID; + } +} + +// GetTokenType use tokenId, and IsSystemApp use fullTokenId, these are +// different +bool CheckSystemCallingPermission(DataObsOption &opt) +{ + if (!opt.IsSystem()) { + return true; + } + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID(); + Security::AccessToken::ATokenTypeEnum tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); + if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE + || tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) { + return true; + } + // IsSystemAppByFullTokenID here is not IPC + if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) { + LOG_ERROR("Not system app, token:%{public}" PRIx64 "", fullTokenId); + return false; + } + return true; +} + +int DataObsMgrService::RegisterObserver( + const Uri &uri, sptr dataObserver, int32_t userId, DataObsOption opt) +{ + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr) { + LOG_ERROR("null dataObsMgrInner, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + auto [success, observerNode] = ConstructObserverNode(dataObserver, userId); + if (!success) { + LOG_ERROR("ConstructObserverNode fail, uri:%{public}s, userId:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), userId); + return DATAOBS_INVALID_USERID; + } + int status; + if (const_cast(uri).GetScheme() == SHARE_PREFERENCES) { + status = dataObsMgrInnerPref_->HandleRegisterObserver(uri, observerNode); + } else { + status = dataObsMgrInner_->HandleRegisterObserver(uri, observerNode); + } + + if (status != NO_ERROR) { + LOG_ERROR("register failed:%{public}d, uri:%{public}s", status, CommonUtils::Anonymous(uri.ToString()).c_str()); + return status; + } + return NO_ERROR; +} + +int DataObsMgrService::UnregisterObserver( + const Uri &uri, sptr dataObserver, int32_t userId, DataObsOption opt) +{ + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr) { + LOG_ERROR("null dataObsMgrInner, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + auto [success, observerNode] = ConstructObserverNode(dataObserver, userId); + if (!success) { + LOG_ERROR("ConstructObserverNode fail, uri:%{public}s, userId:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), userId); + return DATAOBS_INVALID_USERID; + } + int status; + if (const_cast(uri).GetScheme() == SHARE_PREFERENCES) { + status = dataObsMgrInnerPref_->HandleUnregisterObserver(uri, observerNode); + } else { + status = dataObsMgrInner_->HandleUnregisterObserver(uri, observerNode); + } + + if (status != NO_ERROR) { + LOG_ERROR( + "unregister failed:%{public}d, uri:%{public}s", status, CommonUtils::Anonymous(uri.ToString()).c_str()); + return status; + } + return NO_ERROR; +} + +int DataObsMgrService::NotifyChange(const Uri &uri, int32_t userId, DataObsOption opt) +{ + if (handler_ == nullptr) { + LOG_ERROR("null handler, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_HANDLER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr || dataObsMgrInnerPref_ == nullptr) { + LOG_ERROR("null dataObsMgr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + { + std::lock_guard lck(taskCountMutex_); + if (taskCount_ >= TASK_COUNT_MAX) { + LOG_ERROR("task num reached limit, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_TASK_LIMMIT; + } + ++taskCount_; + } + + // If no user is specified, the current user is notified. + if (userId == -1) { + userId = GetCallingUserId(); + } + if (userId == -1) { + LOG_ERROR("GetCurrentUserId fail, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return GET_TOKENINFO_ERR; + } + + ChangeInfo changeInfo = { ChangeInfo::ChangeType::OTHER, { uri } }; + handler_->SubmitTask([this, uri, changeInfo, userId]() { + if (const_cast(uri).GetScheme() == SHARE_PREFERENCES) { + dataObsMgrInnerPref_->HandleNotifyChange(uri, userId); + } else { + dataObsMgrInner_->HandleNotifyChange(uri, userId); + dataObsMgrInnerExt_->HandleNotifyChange(changeInfo, userId); + } + std::lock_guard lck(taskCountMutex_); + --taskCount_; + }); + + return NO_ERROR; +} + +Status DataObsMgrService::RegisterObserverExt( + const Uri &uri, sptr dataObserver, bool isDescendants, DataObsOption opt) +{ + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver, uri:%{public}s, isDescendants:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + LOG_ERROR("null dataObsMgrInner, uri:%{public}s, isDescendants:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + int userId = GetCallingUserId(); + if (userId == -1) { + LOG_ERROR("GetCallingUserId fail, uri:%{public}s, userId:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), userId); + return DATAOBS_INVALID_USERID; + } + + auto innerUri = uri; + return dataObsMgrInnerExt_->HandleRegisterObserver(innerUri, dataObserver, userId, isDescendants); +} + +Status DataObsMgrService::UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt) +{ + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + LOG_ERROR("null dataObsMgrInner, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + auto innerUri = uri; + return dataObsMgrInnerExt_->HandleUnregisterObserver(innerUri, dataObserver); +} + +Status DataObsMgrService::UnregisterObserverExt(sptr dataObserver, DataObsOption opt) +{ + if (dataObserver == nullptr) { + LOG_ERROR("null dataObserver"); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + LOG_ERROR("null dataObsMgrInner"); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + return dataObsMgrInnerExt_->HandleUnregisterObserver(dataObserver); +} + +Status DataObsMgrService::DeepCopyChangeInfo(const ChangeInfo &src, ChangeInfo &dst) const +{ + dst = src; + if (dst.size_ == 0) { + return SUCCESS; + } + dst.data_ = new (std::nothrow) uint8_t[dst.size_]; + if (dst.data_ == nullptr) { + return DATAOBS_SERVICE_INNER_IS_NULL; + } + + errno_t ret = memcpy_s(dst.data_, dst.size_, src.data_, src.size_); + if (ret != EOK) { + delete[] static_cast(dst.data_); + dst.data_ = nullptr; + return DATAOBS_SERVICE_INNER_IS_NULL; + } + return SUCCESS; +} + +Status DataObsMgrService::NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt) +{ + if (handler_ == nullptr) { + LOG_ERROR("null handler"); + return DATAOBS_SERVICE_HANDLER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr) { + LOG_ERROR("dataObsMgrInner_:%{public}d or null dataObsMgrInnerExt", dataObsMgrInner_ == nullptr); + return DATAOBS_SERVICE_INNER_IS_NULL; + } + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + + int userId = GetCallingUserId(); + if (userId == -1) { + LOG_ERROR("GetCallingUserId fail, type:%{public}d, userId:%{public}d", changeInfo.changeType_, userId); + return DATAOBS_INVALID_USERID; + } + + ChangeInfo changes; + Status result = DeepCopyChangeInfo(changeInfo, changes); + if (result != SUCCESS) { + LOG_ERROR("copy data failed, changeType:%{public}ud,uris num:%{public}zu, " + "null data:%{public}d, size:%{public}ud", + changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_); + return result; + } + + { + std::lock_guard lck(taskCountMutex_); + if (taskCount_ >= TASK_COUNT_MAX) { + LOG_ERROR("task num maxed, changeType:%{public}ud," + "uris num:%{public}zu, null data:%{public}d, size:%{public}ud", + changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_); + return DATAOBS_SERVICE_TASK_LIMMIT; + } + ++taskCount_; + } + + handler_->SubmitTask([this, changes, userId]() { + dataObsMgrInnerExt_->HandleNotifyChange(changes, userId); + for (auto &uri : changes.uris_) { + dataObsMgrInner_->HandleNotifyChange(uri, userId); + } + delete[] static_cast(changes.data_); + std::lock_guard lck(taskCountMutex_); + --taskCount_; + }); + return SUCCESS; +} + +void DataObsMgrService::GetFocusedAppInfo(int32_t &windowId, sptr &abilityToken) const +{ + Rosen::FocusChangeInfo info; +#ifdef SCENE_BOARD_ENABLE + Rosen::WindowManagerLite::GetInstance().GetFocusWindowInfo(info); +#else + Rosen::WindowManager::GetInstance().GetFocusWindowInfo(info); +#endif + windowId = info.windowId_; + abilityToken = info.abilityToken_; +} + +sptr DataObsMgrService::GetAbilityManagerService() const +{ + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + LOG_ERROR("Failed to get ability manager."); + return nullptr; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (!remoteObject) { + LOG_ERROR("Failed to get ability manager service."); + return nullptr; + } + return remoteObject; +} + +Status DataObsMgrService::NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt) +{ + if (!CheckSystemCallingPermission(opt)) { + return DATAOBS_NOT_SYSTEM_APP; + } + auto remote = GetAbilityManagerService(); + if (remote == nullptr) { + LOG_ERROR("Get ability manager failed."); + return DATAOBS_PROXY_INNER_ERR; + } + auto abilityManager = iface_cast(remote); + + int32_t windowId; + sptr callerToken; + GetFocusedAppInfo(windowId, callerToken); + + AAFwk::Want want; + want.SetElementName(DIALOG_APP, PROGRESS_ABILITY); + want.SetAction(PROGRESS_ABILITY); + want.SetParam("promptText", std::string(PROMPT_TEXT)); + want.SetParam("remoteDeviceName", std::string()); + want.SetParam("progressKey", key); + want.SetParam("isRemote", false); + want.SetParam("windowId", windowId); + want.SetParam("ipcCallback", observer); + if (callerToken != nullptr) { + want.SetParam("tokenKey", callerToken); + } else { + LOG_WARN("CallerToken is nullptr."); + } + + int32_t status = IN_PROCESS_CALL(abilityManager->StartAbility(want)); + if (status != SUCCESS) { + LOG_ERROR("ShowProgress fail, status:%{public}d", status); + return DATAOBS_PROXY_INNER_ERR; + } + return SUCCESS; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_stub.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..997181f90da478d72296c725d161a974e1b61595 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/dataobs_mgr_stub.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021-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. + */ + +#include "dataobs_mgr_stub.h" + +#include "common_utils.h" +#include "data_ability_observer_proxy.h" +#include "dataobs_log.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_interface.h" +#include "ipc_skeleton.h" +#include "string_ex.h" + +namespace OHOS { +namespace DataObs { +using Uri = OHOS::Uri; + +const DataObsManagerStub::RequestFuncType DataObsManagerStub::HANDLES[TRANS_BUTT] = { + &DataObsManagerStub::RegisterObserverInner, &DataObsManagerStub::UnregisterObserverInner, + &DataObsManagerStub::NotifyChangeInner, &DataObsManagerStub::RegisterObserverExtInner, + &DataObsManagerStub::UnregisterObserverExtInner, &DataObsManagerStub::UnregisterObserverExtALLInner, + &DataObsManagerStub::NotifyChangeExtInner, &DataObsManagerStub::NotifyProcessObserverInner +}; + +DataObsManagerStub::DataObsManagerStub() +{ +} + +DataObsManagerStub::~DataObsManagerStub() +{ +} + +int DataObsManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) +{ + int tryTimes = TRY_TIMES; + while (!isReady_.load() && tryTimes > 0) { + tryTimes--; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + } + LOG_INFO("code: %{public}d, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); + std::u16string descriptor = DataObsManagerStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + LOG_ERROR("local descriptor≠remote, descriptor:%{public}s, " + "remoteDescriptor:%{public}s", + CommonUtils::Anonymous(Str16ToStr8(descriptor)).c_str(), + CommonUtils::Anonymous(Str16ToStr8(remoteDescriptor)).c_str()); + return ERR_INVALID_STATE; + } + + if (code < TRANS_HEAD || code >= TRANS_BUTT || HANDLES[code] == nullptr) { + LOG_ERROR("invalid code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT); + MessageOption option; + return ERR_INVALID_STATE; + } + return (this->*HANDLES[code])(data, reply); +} + +int DataObsManagerStub::RegisterObserverInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("invalid uri"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto remote = data.ReadRemoteObject(); + auto observer = remote == nullptr ? nullptr : iface_cast(remote); + int32_t userId = data.ReadInt32(); + DataObsOption opt = DataObsOption(data.ReadBool()); + int32_t result = RegisterObserver(uri, observer, userId, opt); + reply.WriteInt32(result); + return NO_ERROR; +} + +int DataObsManagerStub::UnregisterObserverInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("invalid uri"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto remote = data.ReadRemoteObject(); + auto observer = remote == nullptr ? nullptr : iface_cast(remote); + int32_t userId = data.ReadInt32(); + DataObsOption opt = DataObsOption(data.ReadBool()); + int32_t result = UnregisterObserver(uri, observer, userId, opt); + reply.WriteInt32(result); + return NO_ERROR; +} + +int DataObsManagerStub::NotifyChangeInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("invalid uri"); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t userId = data.ReadInt32(); + DataObsOption opt = DataObsOption(data.ReadBool()); + int32_t result = NotifyChange(uri, userId, opt); + reply.WriteInt32(result); + return NO_ERROR; +} + +int32_t DataObsManagerStub::RegisterObserverExtInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("invalid uri"); + return IPC_STUB_INVALID_DATA_ERR; + } + auto remote = data.ReadRemoteObject(); + auto observer = remote == nullptr ? nullptr : iface_cast(remote); + bool isDescendants = data.ReadBool(); + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(RegisterObserverExt(uri, observer, isDescendants, opt)); + return SUCCESS; +} + +int32_t DataObsManagerStub::UnregisterObserverExtInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + LOG_ERROR("invalid uri"); + return IPC_STUB_INVALID_DATA_ERR; + } + auto remote = data.ReadRemoteObject(); + auto observer = remote == nullptr ? nullptr : iface_cast(remote); + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(UnregisterObserverExt(uri, observer, opt)); + return SUCCESS; +} + +int32_t DataObsManagerStub::UnregisterObserverExtALLInner(MessageParcel &data, MessageParcel &reply) +{ + auto remote = data.ReadRemoteObject(); + auto observer = remote == nullptr ? nullptr : iface_cast(remote); + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(UnregisterObserverExt(observer, opt)); + return SUCCESS; +} + +int32_t DataObsManagerStub::NotifyChangeExtInner(MessageParcel &data, MessageParcel &reply) +{ + ChangeInfo changeInfo; + if (!ChangeInfo::Unmarshalling(changeInfo, data)) { + LOG_ERROR("Failed to unmarshall changeInfo."); + return IPC_STUB_INVALID_DATA_ERR; + } + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(NotifyChangeExt(changeInfo, opt)); + return SUCCESS; +} + +int32_t DataObsManagerStub::NotifyProcessObserverInner(MessageParcel &data, MessageParcel &reply) +{ + std::string key = data.ReadString(); + auto observer = data.ReadRemoteObject(); + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(NotifyProcessObserver(key, observer, opt)); + return SUCCESS; +} + +void DataObsManagerStub::SetServiceReady() +{ + isReady_.store(true); +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/framework/src/ikvstore_dataobs_service.cpp b/services/distributeddataservice/service/dataobsmgr/framework/src/ikvstore_dataobs_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c6f2d7314b09464d30205e6a1cf41056321a1b3 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/framework/src/ikvstore_dataobs_service.cpp @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#include "ikvstore_dataobs_service.h" + +#include "dataobs_log.h" + +namespace OHOS { +namespace DataObs { +DataObsKvServiceProxy::DataObsKvServiceProxy(const sptr &impl) + : IRemoteProxy(impl) +{ + LOG_DEBUG("Init dataobs service proxy."); +} + +sptr DataObsKvServiceProxy::GetFeatureInterface(const std::string &name) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(DataObsKvServiceProxy::GetDescriptor())) { + LOG_ERROR("Write descriptor failed"); + return nullptr; + } + if (!data.WriteString(name)) { + LOG_ERROR("Write name failed"); + return nullptr; + } + + MessageParcel reply; + MessageOption mo{ MessageOption::TF_SYNC }; + int32_t error = Remote()->SendRequest( + static_cast(IKvStoreDataInterfaceCode::GET_FEATURE_INTERFACE), data, reply, mo); + if (error != 0) { + LOG_ERROR("SendRequest returned %{public}d", error); + return nullptr; + } + auto remoteObject = reply.ReadRemoteObject(); + if (remoteObject == nullptr) { + LOG_ERROR("Remote object is nullptr!"); + return nullptr; + } + return remoteObject; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/BUILD.gn b/services/distributeddataservice/service/dataobsmgr/interfaces/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4eac5a109e1da5d2b7b4afab782df93b735b449b --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/BUILD.gn @@ -0,0 +1,67 @@ +# Copyright (c) 2021-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/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +config("dataobs_manager_public_config") { + visibility = [ ":*" ] + + include_dirs = [ + "include/", + "${dataobsmgr_path}/framework/include", + ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } +} + +ohos_shared_library("dataobs_manager") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = [ + "${dataobsmgr_path}/framework/src/data_ability_observer_proxy.cpp", + "${dataobsmgr_path}/framework/src/data_ability_observer_stub.cpp", + "${dataobsmgr_path}/framework/src/dataobs_mgr_changeinfo.cpp", + "${dataobsmgr_path}/framework/src/dataobs_mgr_client.cpp", + "${dataobsmgr_path}/framework/src/dataobs_mgr_proxy.cpp", + "${dataobsmgr_path}/framework/src/ikvstore_dataobs_service.cpp", + ] + + public_configs = [ + ":dataobs_manager_public_config", + "${dataobsmgr_path}/framework:dataobsms_config", + ] + + deps = [] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + public_external_deps = [ "ability_base:zuri" ] + innerapi_tags = [ + "platformsdk", + "sasdk", + ] + subsystem_name = "distributeddatamgr" + + part_name = "datamgr_service" +} diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_interface.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..ac5d4cd8e961735cd2e8efe0776e4d75be2b8b30 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_interface.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef DATAOBSSERVICE_DATA_ABILITY_OBSERVER_INTERFACE_H +#define DATAOBSSERVICE_DATA_ABILITY_OBSERVER_INTERFACE_H + +#include + +#include "dataobs_mgr_changeinfo.h" + +namespace OHOS { +namespace AAFwk { +class IDataAbilityObserver : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataObs.DataAbilityObserver"); + + enum { + TRANS_HEAD, + DATA_ABILITY_OBSERVER_CHANGE = TRANS_HEAD, + DATA_ABILITY_OBSERVER_CHANGE_EXT, + DATA_ABILITY_OBSERVER_CHANGE_PREFERENCES, + TRANS_BUTT, + }; + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param uri Indicates the path of the data to operate. + */ + virtual void OnChange() = 0; + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param changeInfo Indicates the info of the data to operate. + */ + virtual void OnChangeExt(const ChangeInfo &changeInfo) + { + return; + } + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param key Indicates the key that has changed. + */ + virtual void OnChangePreferences(const std::string &key) + { + return; + } +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATA_ABILITY_OBSERVER_INTERFACE_H diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_stub.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..75b646a955a74621f5e8fd3236236085bea38c7a --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/data_ability_observer_stub.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef DATAOBSSERVICE_DATA_ABILITY_OBSERVER_STUB_H +#define DATAOBSSERVICE_DATA_ABILITY_OBSERVER_STUB_H + +#include +#include + +#include +#include + +#include "data_ability_observer_interface.h" +#include "nocopyable.h" + +namespace OHOS { +namespace AAFwk { +class DataAbilityObserverStub : public IRemoteStub { +public: + DataAbilityObserverStub(); + virtual ~DataAbilityObserverStub(); + + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + /** + * @brief Called back to notify that the data being observed has changed. + * + */ + int32_t OnChangeInner(MessageParcel &data, MessageParcel &reply); + + /** + * @brief Called back to notify that the data being observed has changed. + * + */ + int32_t OnChangeExtInner(MessageParcel &data, MessageParcel &reply); + + /** + * @brief Called back to notify that the data being observed has changed. + * + */ + int32_t OnChangePreferencesInner(MessageParcel &data, MessageParcel &reply); + + using RequestFuncType = int (DataAbilityObserverStub::*)(MessageParcel &data, MessageParcel &reply); + static const RequestFuncType HANDLES[TRANS_BUTT]; + + DISALLOW_COPY_AND_MOVE(DataAbilityObserverStub); +}; + +/** + * @class DataObsCallbackRecipient + * DataObsCallbackRecipient notices IRemoteBroker died. + */ +class DataObsCallbackRecipient : public IRemoteObject::DeathRecipient { +public: + using RemoteDiedHandler = std::function &)>; + explicit DataObsCallbackRecipient(RemoteDiedHandler handler); + virtual ~DataObsCallbackRecipient(); + virtual void OnRemoteDied(const wptr &remote); + +private: + RemoteDiedHandler handler_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATA_ABILITY_OBSERVER_STUB_H diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_changeinfo.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_changeinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..9d21026506c82d9c926c67e30c597a2db535ea68 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_changeinfo.h @@ -0,0 +1,50 @@ +/* + * 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. + */ +#ifndef DATAOBSSERVICE_DATAOBS_MGR_CHANGEINFO_H +#define DATAOBSSERVICE_DATAOBS_MGR_CHANGEINFO_H + +#include +#include + +#include "message_parcel.h" +#include "uri.h" + +namespace OHOS { +namespace AAFwk { +struct ChangeInfo { + enum ChangeType : uint32_t { + INSERT = 0, + DELETE, + UPDATE, + OTHER, + INVAILD, + }; + using Value = std::variant>; + using VBucket = std::map; + using VBuckets = std::vector; + + static bool Marshalling(const ChangeInfo &input, MessageParcel &parcel); + static bool Unmarshalling(ChangeInfo &output, MessageParcel &parcel); + + ChangeType changeType_ = INVAILD; + mutable std::list uris_ = {}; + void *data_ = nullptr; + uint32_t size_ = 0; + VBuckets valueBuckets_ = {}; + static constexpr int LIST_MAX_COUNT = 3000; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_CHANGEINFO_H diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_client.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_client.h new file mode 100644 index 0000000000000000000000000000000000000000..5aa3572f2bdb4c18b5f12a0d457ec7dfcfef2192 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_client.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_CLIENT_H +#define DATAOBSSERVICE_DATAOBS_MGR_CLIENT_H + +#include + +#include "concurrent_map.h" +#include "data_ability_observer_interface.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_interface.h" +#include "dataobs_mgr_proxy.h" +#include "ikvstore_dataobs_service.h" +#include "iremote_object.h" +#include "system_ability_status_change_stub.h" +#include "uri.h" + +namespace OHOS { +namespace DataObs { +using namespace AAFwk; +/** + * @class DataObsMgrClient + * DataObsMgrClient is used to access dataobs manager services. + */ +class DataObsMgrClient { +public: + DataObsMgrClient(); + virtual ~DataObsMgrClient(); + static std::shared_ptr GetInstance(); + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode RegisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()); + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode UnregisterObserver(const Uri &uri, sptr dataObserver, int32_t userId = -1, + DataObsOption opt = DataObsOption()); + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uri. + * + * @param uri, Indicates the path of the data to operate. + * + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode NotifyChange(const Uri &uri, int32_t userId = -1, DataObsOption opt = DataObsOption()); + + /** + * Registers an observer to DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + Status RegisterObserverExt(const Uri &uri, sptr dataObserver, bool isDescendants, + DataObsOption opt = DataObsOption()); + + /** + * Deregisters an observer used for DataObsMgr specified by the given Uri. + * + * @param uri, Indicates the path of the data to operate. + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + Status UnregisterObserverExt( + const Uri &uri, sptr dataObserver, DataObsOption opt = DataObsOption()); + + /** + * Deregisters observers used for DataObsMgr specified. + * + * @param dataObserver, Indicates the IDataAbilityObserver object. + * + * @return Returns SUCCESS on success, others on failure. + */ + Status UnregisterObserverExt(sptr dataObserver, DataObsOption opt = DataObsOption()); + + /** + * Notifies the registered observers of a change to the data resource + * specified by Uris. + * + * @param changeInfo Indicates the info of the data to operate. + * + * @return Returns SUCCESS on success, others on failure. + */ + Status NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt = DataObsOption()); + + /** + * Notifies the process observer with the given progress key and cancel + observer. + * + * @param key Identifies the progress of a specific task. + + * @param observer Observer for monitoring the ongoing process. + * + * @return Returns SUCCESS on success, others on failure. + */ + Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()); + +private: + class DataObsClientStatusChangeStub : public SystemAbilityStatusChangeStub { + public: + explicit DataObsClientStatusChangeStub(DataObsMgrClient *owner) : owner_(owner) + { + } + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override + { + if (owner_ != nullptr) { + owner_->OnAddSystemAbility(systemAbilityId, deviceId); + } + } + + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override + { + } + + private: + DataObsMgrClient *owner_; + }; + /** + * Connect dataobs manager service. + * + * @return Returns SUCCESS on success, others on failure. + */ + std::pair> GetObsMgr(); + sptr GetDataObsManagerProxy(); + sptr GetDistributedDataManager(); + + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId); + void OnRemoteDied(); + void ReRegister(); + void ResetService(); + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit ServiceDeathRecipient(DataObsMgrClient *owner) : owner_(owner) + { + } + void OnRemoteDied(const wptr &object) override + { + if (owner_ != nullptr) { + owner_->OnRemoteDied(); + } + } + + private: + DataObsMgrClient *owner_; + }; + + static constexpr int SLEEP_TIME = 300; + static constexpr int RESUB_INTERVAL = 2; + static std::mutex mutex_; + std::shared_ptr dataObsService_; + sptr dataMgrService_; + struct ObserverInfo { + Uri uri; + int32_t userId; + ObserverInfo(Uri uri, int32_t userId) : uri(uri), userId(userId){}; + }; + ConcurrentMap, std::list> observers_; + + struct Param { + Param(const Uri &uri, bool isDescendants) : uri(uri), isDescendants(isDescendants){}; + Uri uri; + bool isDescendants; + }; + ConcurrentMap, std::list> observerExts_; + sptr callback_; + sptr deathRecipient_; +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_CLIENT_H diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_errors.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_errors.h new file mode 100644 index 0000000000000000000000000000000000000000..651d0464748c73a15f719be9b207351af439a736 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_mgr_errors.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_MGR_ERRORS_H +#define DATAOBSSERVICE_DATAOBS_MGR_ERRORS_H + +#include + +#include "errors.h" + +namespace OHOS { +namespace DataObs { +enum { + /** + * Module type: Dataobs Manager Service side + */ + DATAOBS_MODULE_TYPE_SERVICE = 2, +}; + +// offset of aafwk error, only be used in this file. +constexpr ErrCode AAFWK_DATAOBS_SERVICE_ERR_OFFSET = ErrCodeOffset(SUBSYS_AAFWK, DATAOBS_MODULE_TYPE_SERVICE); + +constexpr ErrCode NO_ERROR = ERR_OK; + +enum Status : int32_t { + /** + * Result(2228224) + */ + SUCCESS = NO_ERROR, + DATAOBS_SERVICE_NOT_CONNECTED = AAFWK_DATAOBS_SERVICE_ERR_OFFSET, + GET_DATAOBS_SERVICE_FAILED, + DATAOBS_PROXY_INNER_ERR, + DATA_OBSERVER_IS_NULL, + DATAOBS_SERVICE_HANDLER_IS_NULL, + DATAOBS_SERVICE_INNER_IS_NULL, + DATAOBS_SERVICE_TASK_LIMMIT, + DATAOBS_SERVICE_OBS_LIMMIT, + DATAOBS_SERVICE_POST_TASK_FAILED, + NO_OBS_FOR_URI, + OBS_EXIST, + DATAOBS_HIDUMP_ERROR, + IPC_PARCEL_ERROR, + IPC_ERROR, + INVALID_PARAM, + GET_TOKENINFO_ERR, + DATAOBS_INVALID_USERID, + DATAOBS_NOT_SYSTEM_APP, +}; +} // namespace DataObs +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_ERRORS_H diff --git a/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_utils.h b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..39b4b1a20bdd203db6b2450ce8381f21da9fef52 --- /dev/null +++ b/services/distributeddataservice/service/dataobsmgr/interfaces/include/dataobs_utils.h @@ -0,0 +1,303 @@ +/* + * 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. + */ + +#ifndef DATAOBSSERVICE_DATAOBS_UTILS_H +#define DATAOBSSERVICE_DATAOBS_UTILS_H +#include +#include +#include +#include +#include +#include +#include + +#include "iremote_object.h" +#include "message_parcel.h" +namespace OHOS { +template struct is_container : std::false_type { +}; +template struct is_container> : std::true_type { +}; +template struct is_container> : std::true_type { +}; +namespace DataObsUtils { +static inline bool Marshal(MessageParcel &data) +{ + return true; +} + +static inline bool Unmarshal(MessageParcel &data) +{ + return true; +} + +static inline bool Marshalling(int64_t input, MessageParcel &data) +{ + return data.WriteInt64(input); +} + +static inline bool Unmarshalling(int64_t &output, MessageParcel &data) +{ + return data.ReadInt64(output); +} + +static inline bool Marshalling(double input, MessageParcel &data) +{ + return data.WriteDouble(input); +} + +static inline bool Unmarshalling(double &output, MessageParcel &data) +{ + return data.ReadDouble(output); +} + +static inline bool Marshalling(bool input, MessageParcel &data) +{ + return data.WriteBool(input); +} + +static inline bool Unmarshalling(bool &output, MessageParcel &data) +{ + return data.ReadBool(output); +} + +static inline bool Marshalling(const std::monostate &input, MessageParcel &data) +{ + return true; +} + +static inline bool Unmarshalling(std::monostate &output, MessageParcel &data) +{ + return true; +} + +static inline bool Marshalling(const std::string &input, MessageParcel &data) +{ + return data.WriteString(input); +} + +static inline bool Unmarshalling(std::string &output, MessageParcel &data) +{ + return data.ReadString(output); +} + +static inline bool Marshalling(const std::vector &input, MessageParcel &data) +{ + return data.WriteUInt8Vector(input); +} + +static inline bool Unmarshalling(std::vector &output, MessageParcel &data) +{ + return data.ReadUInt8Vector(&output); +} + +template bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); +template +bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data); + +template bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); +template +bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data); + +template bool Marshalling(const std::variant<_Types...> &input, MessageParcel &data); +template bool Unmarshalling(std::variant<_Types...> &output, MessageParcel &data); + +template bool Marshalling(const std::map &result, MessageParcel &parcel); +template bool Unmarshalling(std::map &val, MessageParcel &parcel); + +template bool Marshalling(const std::vector &val, MessageParcel &parcel); +template bool Unmarshalling(std::vector &val, MessageParcel &parcel); + +template bool Marshalling(const T &input, MessageParcel &data); +template bool Unmarshalling(T &output, MessageParcel &data); + +template{}, int>::type = 0> +bool MarshalToContainer(const T &val, MessageParcel &parcel); +template{}, int>::type = 0> +bool UnmarshalFromContainer(T &val, MessageParcel &parcel); + +template bool Marshal(MessageParcel &parcel, const T &first, const Types &... others); + +template bool Unmarshal(MessageParcel &parcel, T &first, Types &... others); +} // namespace DataObsUtils + +template +bool DataObsUtils::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) +{ + return false; +} + +template +bool DataObsUtils::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data) +{ + if (step == index) { + _First value{}; + auto success = DataObsUtils::Unmarshalling(value, data); + output = value; + return success; + } + return DataObsUtils::ReadVariant<_OutTp, _Rest...>(step + 1, index, output, data); +} + +template bool DataObsUtils::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) +{ + return false; +} + +template +bool DataObsUtils::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data) +{ + if (step == input.index()) { + return DataObsUtils::Marshalling(std::get<_First>(input), data); + } + return DataObsUtils::WriteVariant<_InTp, _Rest...>(step + 1, input, data); +} + +template bool DataObsUtils::Marshalling(const std::variant<_Types...> &input, MessageParcel &data) +{ + uint32_t index = static_cast(input.index()); + if (!data.WriteUint32(index)) { + return false; + } + + return DataObsUtils::WriteVariant(0, input, data); +} + +template bool DataObsUtils::Unmarshalling(std::variant<_Types...> &output, MessageParcel &data) +{ + uint32_t index = data.ReadUint32(); + if (index >= sizeof...(_Types)) { + return false; + } + + return DataObsUtils::ReadVariant(0, index, output, data); +} + +template bool DataObsUtils::Marshalling(const std::map &result, MessageParcel &parcel) +{ + if (!parcel.WriteInt32(static_cast(result.size()))) { + return false; + } + for (const auto &entry : result) { + if (!DataObsUtils::Marshalling(entry.first, parcel)) { + return false; + } + if (!DataObsUtils::Marshalling(entry.second, parcel)) { + return false; + } + } + return true; +} + +template bool DataObsUtils::Unmarshalling(std::map &val, MessageParcel &parcel) +{ + int32_t size = 0; + if (!parcel.ReadInt32(size)) { + return false; + } + if (size < 0) { + return false; + } + + size_t readAbleSize = parcel.GetReadableBytes(); + if ((static_cast(size) > readAbleSize) || static_cast(size) > val.max_size()) { + return false; + } + + for (int32_t i = 0; i < size; i++) { + K key; + if (!DataObsUtils::Unmarshalling(key, parcel)) { + return false; + } + if (!DataObsUtils::Unmarshalling(val[key], parcel)) { + return false; + } + } + return true; +} + +template bool DataObsUtils::Marshalling(const std::vector &val, MessageParcel &parcel) +{ + return DataObsUtils::MarshalToContainer(val, parcel); +} + +template bool DataObsUtils::Unmarshalling(std::vector &val, MessageParcel &parcel) +{ + return DataObsUtils::UnmarshalFromContainer(val, parcel); +} + +template{}, int>::type> +bool DataObsUtils::MarshalToContainer(const T &val, MessageParcel &parcel) +{ + if (val.size() > INT_MAX) { + return false; + } + + if (!parcel.WriteInt32(static_cast(val.size()))) { + return false; + } + + for (auto &v : val) { + if (!DataObsUtils::Marshalling(v, parcel)) { + return false; + } + } + return true; +} + +template{}, int>::type> +bool DataObsUtils::UnmarshalFromContainer(T &val, MessageParcel &parcel) +{ + int32_t len = parcel.ReadInt32(); + if (len < 0) { + return false; + } + + size_t readAbleSize = parcel.GetReadableBytes(); + size_t size = static_cast(len); + if ((size > readAbleSize) || (size > val.max_size())) { + return false; + } + + val.clear(); + for (size_t i = 0; i < size; i++) { + typename T::value_type value; + if (!DataObsUtils::Unmarshalling(value, parcel)) { + return false; + } + val.emplace_back(std::move(value)); + } + return true; +} + +template +bool DataObsUtils::Marshal(MessageParcel &parcel, const T &first, const Types &... others) +{ + if (!DataObsUtils::Marshalling(first, parcel)) { + return false; + } + return DataObsUtils::Marshal(parcel, others...); +} + +template +bool DataObsUtils::Unmarshal(MessageParcel &parcel, T &first, Types &... others) +{ + if (!DataObsUtils::Unmarshalling(first, parcel)) { + return false; + } + return DataObsUtils::Unmarshal(parcel, others...); +} +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_UTILS_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 0fcf6423bd2ff122dc8267e68f8c0db557fb508f..1aebfdf4a27bff9692e65d41a57a979f821dc0a4 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -1003,7 +1003,6 @@ ohos_unittest("DataShareServiceImplTest") { "ability_base:base", "ability_base:want", "ability_base:zuri", - "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", @@ -1041,6 +1040,7 @@ ohos_unittest("DataShareServiceImplTest") { "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service:distributeddatasvc", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] } @@ -1935,6 +1935,14 @@ group("unittest") { ":PermissionValidatorTest", ":PermitDelegateMockTest", ":ValueProxyServiceTest", + "dataobsmgr/data_ability_observer_proxy_test:data_ability_observer_proxy_test", + "dataobsmgr/data_ability_observer_stub_test:data_ability_observer_stub_test", + "dataobsmgr/dataobs_mgr_inner_ext_test:dataobs_mgr_inner_ext_test", + "dataobsmgr/dataobs_mgr_inner_pref_test:dataobs_mgr_inner_pref_test", + "dataobsmgr/dataobs_mgr_inner_test:dataobs_mgr_inner_test", + "dataobsmgr/dataobs_mgr_service_second_test:dataobs_mgr_service_second_test", + "dataobsmgr/dataobs_mgr_service_test:dataobs_mgr_service_test", + "dataobsmgr/dataobs_mgr_stub_test:dataobs_mgr_stub_test", ] } ############################################################################### diff --git a/services/distributeddataservice/service/test/dataobsmgr/cfi_blocklist.txt b/services/distributeddataservice/service/test/dataobsmgr/cfi_blocklist.txt new file mode 100644 index 0000000000000000000000000000000000000000..7e6de6f7f15cc4c84d3a5653d0b591620c20bf4b --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/cfi_blocklist.txt @@ -0,0 +1,16 @@ +# 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. + +[cfi] +src:*/third_party/googletest/googletest/include/gtest/* +src:*/third_party/googletest/googlemock/include/gmock/* \ No newline at end of file diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d434a85f550ec3e02d04706a4da60f3bdef20d54 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2021 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_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("data_ability_observer_proxy_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "data_ability_observer_proxy_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ "${dataobsmgr_path}/interfaces:dataobs_manager" ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "eventhandler:libeventhandler", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/data_ability_observer_proxy_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/data_ability_observer_proxy_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5191a5eae20091faca03dd7739faf94acb735ae7 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/data_ability_observer_proxy_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021 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 + +#include +#include "data_ability_observer_proxy.h" +#include "mock_data_obs_manager_onchange_callback.h" + +using namespace testing::ext; +using namespace testing; +namespace OHOS { +namespace DataObs { +class DataAbilityObserverProxyTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr proxy_ = nullptr; +}; + +void DataAbilityObserverProxyTest::SetUpTestCase(void) +{ +} +void DataAbilityObserverProxyTest::TearDownTestCase(void) +{ +} +void DataAbilityObserverProxyTest::SetUp() +{ +} +void DataAbilityObserverProxyTest::TearDown() +{ +} + +/* + * Feature: DataAbilityObserverProxy. + * Function: DataObsManagerProxy::OnChange is called. + * SubFunction: NA. + * FunctionPoints: NA. + * EnvConditions: NA. + * CaseDescription: NA. + */ +HWTEST_F(DataAbilityObserverProxyTest, DataAbilityObserverProxy_OnChangeInner_001, TestSize.Level1) +{ + // 1.stub define + sptr mockDataAbilityObserverStub(new MockDataObsManagerOnChangeCallBack()); + + // 2.obsver1 define + sptr proxy(new DataAbilityObserverProxy(mockDataAbilityObserverStub)); + + EXPECT_CALL(*mockDataAbilityObserverStub, OnChange()).Times(1); + + if (proxy != nullptr) { + proxy->OnChange(); + } +} + +/* + * Feature: DataAbilityObserverProxy. + * Function: DataObsManagerProxy::OnChangeExt is called. + * SubFunction: NA. + * FunctionPoints: NA. + * EnvConditions: NA. + * CaseDescription: NA. + */ +HWTEST_F(DataAbilityObserverProxyTest, DataAbilityObserverProxy_OnChangeExt_001, TestSize.Level1) +{ + // 1.stub define + sptr mockDataAbilityObserverStub(new MockDataObsManagerOnChangeCallBack()); + + // 2.obsver1 define + sptr proxy(new DataAbilityObserverProxy(mockDataAbilityObserverStub)); + + ChangeInfo changeInfo; + changeInfo.data_ = new int(0); + changeInfo.size_ = sizeof(int); + + EXPECT_CALL(*mockDataAbilityObserverStub, OnChangeExt(testing::_)).Times(1); + + if (proxy != nullptr) { + proxy->OnChangeExt(changeInfo); + } + if (changeInfo.data_ != nullptr) { + free(changeInfo.data_); + changeInfo.data_ = nullptr; + } +} + +/* + * Feature: DataAbilityObserverProxy. + * Function: DataObsManagerProxy::OnChangePreferences is called. + * SubFunction: NA. + * FunctionPoints: NA. + * EnvConditions: NA. + * CaseDescription: NA. + */ +HWTEST_F(DataAbilityObserverProxyTest, DataAbilityObserverProxy_OnChangePreferences_001, TestSize.Level1) +{ + // 1.stub define + sptr mockDataAbilityObserverStub(new MockDataObsManagerOnChangeCallBack()); + + // 2.obsver1 define + sptr proxy(new DataAbilityObserverProxy(mockDataAbilityObserverStub)); + + std::string key = "test"; + EXPECT_CALL(*mockDataAbilityObserverStub, OnChangePreferences(key)).Times(1); + + if (proxy != nullptr) { + proxy->OnChangePreferences(key); + } +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/mock_data_obs_manager_onchange_callback.h b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/mock_data_obs_manager_onchange_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..bdfd9449244b48435b90a1ce8207030a3f333b7d --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_proxy_test/mock_data_obs_manager_onchange_callback.h @@ -0,0 +1,57 @@ + +/* + * Copyright (c) 2021 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. + */ + +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H + +#include + +#include + +#include "data_ability_observer_stub.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace DataObs { +class MockDataObsManagerOnChangeCallBack : public DataAbilityObserverStub { +public: + MOCK_METHOD0(OnChange, void()); + MOCK_METHOD1(OnChangeExt, void(const ChangeInfo &)); + MOCK_METHOD1(OnChangePreferences, void(const std::string &)); + + void Wait() + { + sem_.Wait(); + } + + int Post() + { + sem_.Post(); + return 0; + } + + void PostVoid() + { + sem_.Post(); + } + +private: + Semaphore sem_; +}; +} // namespace DataObs +} // namespace OHOS + +#endif // UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..40ff7e339bf5caa40f5b7b2138a1f07fd62a4e90 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2021 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_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("data_ability_observer_stub_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "data_ability_observer_stub_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ "${dataobsmgr_path}/interfaces:dataobs_manager" ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "eventhandler:libeventhandler", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/data_ability_observer_stub_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/data_ability_observer_stub_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfbf765576bfb56633a599020ef07b96bca91408 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/data_ability_observer_stub_test.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 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 + +#include + +#include "mock_data_obs_manager_onchange_callback.h" +#include "data_ability_observer_proxy.h" +#include "dataobs_mgr_interface.h" +#include "string_ex.h" + +using namespace testing::ext; +using namespace testing; + +namespace OHOS { +namespace DataObs { +class DataAbilityObserverStubTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DataAbilityObserverStubTest::SetUpTestCase(void) +{ +} +void DataAbilityObserverStubTest::TearDownTestCase(void) +{ +} +void DataAbilityObserverStubTest::SetUp() +{ +} +void DataAbilityObserverStubTest::TearDown() +{ +} + +/* + * Feature: DataAbilityObserverStub. + * Function: DataAbilityObserverStub::UnregisterObserverInner is called. + * SubFunction: UnregisterObserverInner. + * FunctionPoints: NA. + * EnvConditions: NA. + * CaseDescription: NA. + */ +HWTEST_F(DataAbilityObserverStubTest, DataAbilityObserverStub_remoteDescriptor_001, TestSize.Level1) +{ + sptr mockDataObsManagerOnChangeStub(new MockDataObsManagerOnChangeCallBack()); + + MessageParcel data; + MessageParcel reply; + MessageOption option; + + data.WriteInterfaceToken(Str8ToStr16(std::string("descrip_test"))); + + EXPECT_CALL(*mockDataObsManagerOnChangeStub, OnChange()).Times(0); + int res = mockDataObsManagerOnChangeStub->OnRemoteRequest( + IDataAbilityObserver::DATA_ABILITY_OBSERVER_CHANGE, data, reply, option); + EXPECT_EQ(res, ERR_INVALID_STATE); +} +/* + * Feature: DataAbilityObserverStub. + * Function: DataAbilityObserverStub::UnregisterObserverInner is called. + * SubFunction: UnregisterObserverInner. + * FunctionPoints: NA. + * EnvConditions: NA. + * CaseDescription: NA. + */ +HWTEST_F(DataAbilityObserverStubTest, DataAbilityObserverStub_OnChange_001, TestSize.Level1) +{ + sptr mockDataObsManagerOnChangeStub(new MockDataObsManagerOnChangeCallBack()); + + MessageParcel data; + MessageParcel reply; + MessageOption option; + + data.WriteInterfaceToken(DataAbilityObserverProxy::GetDescriptor()); + + EXPECT_CALL(*mockDataObsManagerOnChangeStub, OnChange()).Times(1); + + int res = mockDataObsManagerOnChangeStub->OnRemoteRequest( + IDataAbilityObserver::DATA_ABILITY_OBSERVER_CHANGE, data, reply, option); + EXPECT_EQ(res, ERR_OK); +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/mock_data_obs_manager_onchange_callback.h b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/mock_data_obs_manager_onchange_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..0bdd2cc8bada6c470dca812979094b603bd5ea3c --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/data_ability_observer_stub_test/mock_data_obs_manager_onchange_callback.h @@ -0,0 +1,55 @@ + +/* + * Copyright (c) 2021 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. + */ + +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H + +#include + +#include + +#include "data_ability_observer_stub.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace AAFwk { +class MockDataObsManagerOnChangeCallBack : public DataAbilityObserverStub { +public: + MOCK_METHOD0(OnChange, void()); + + void Wait() + { + sem_.Wait(); + } + + int Post() + { + sem_.Post(); + return 0; + } + + void PostVoid() + { + sem_.Post(); + } + +private: + Semaphore sem_; +}; +} // namespace DataObs +} // namespace OHOS + +#endif // UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MANAGER_ONCHANGE_CALLBACK_STUB_H diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..97e3428b74c83f52e1c0d1b222c877224b37cedb --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021-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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_inner_ext_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_inner_ext_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/dataobs_mgr_inner_ext_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/dataobs_mgr_inner_ext_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf59e15dc1776ff105c4fe6c51ca2a60cc72bf9a --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/dataobs_mgr_inner_ext_test.cpp @@ -0,0 +1,815 @@ +/* + * Copyright (c) 2021 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 + +#include +#include + +#include "uri.h" +#include "data_ability_observer_proxy.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_inner_ext.h" +#include "mock.h" + +using namespace OHOS; +using namespace testing::ext; +using namespace testing; + +using Uri = OHOS::Uri; + +namespace OHOS { +namespace DataObsMgrInnerExtTest { +using namespace DataObs; +class DataObsMgrInnerExtTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + void RegisterObserverUtil(std::shared_ptr &dataObsMgrInnerExt, Uri &uri, + const sptr &callback, uint32_t times, bool isFuzzy); + + bool UrisEqual(std::list uri1, std::list uri2); + + bool ChangeInfoEqual(const ChangeInfo &changeInfo1, const ChangeInfo &changeInfo2); +}; + +static constexpr int64_t USER_TEST = 100; + +void DataObsMgrInnerExtTest::SetUpTestCase(void) +{ +} +void DataObsMgrInnerExtTest::TearDownTestCase(void) +{ +} +void DataObsMgrInnerExtTest::SetUp() +{ +} +void DataObsMgrInnerExtTest::TearDown() +{ +} + +void DataObsMgrInnerExtTest::RegisterObserverUtil(std::shared_ptr &dataObsMgrInnerExt, Uri &uri, + const sptr &callback, uint32_t times, bool isFuzzy) +{ + while (times-- > 0) { + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri, callback, USER_TEST, isFuzzy), SUCCESS); + } +} + +bool DataObsMgrInnerExtTest::UrisEqual(std::list uri1, std::list uri2) +{ + if (uri1.size() != uri2.size()) { + return false; + } + auto cmp = [](const Uri &first, const Uri &second) { return first.ToString() < second.ToString(); }; + uri1.sort(cmp); + uri2.sort(cmp); + auto it1 = uri1.begin(); + auto it2 = uri2.begin(); + for (; it1 != uri1.end() && it2 != uri2.end(); it1++, it2++) { + if (!it1->Equals(*it2)) { + return false; + } + } + return true; +} + +bool DataObsMgrInnerExtTest::ChangeInfoEqual(const ChangeInfo &changeInfo1, const ChangeInfo &changeInfo2) +{ + if (changeInfo1.changeType_ != changeInfo2.changeType_) { + return false; + } + + if (!UrisEqual(changeInfo1.uris_, changeInfo2.uris_)) { + return false; + } + + if (changeInfo1.size_ != changeInfo2.size_) { + return false; + } + + return strncmp(reinterpret_cast(changeInfo1.data_), + reinterpret_cast(changeInfo2.data_), changeInfo2.size_) == 0; +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register one non-fuzzy observer one times + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person"); + Uri uri2(uriBase + "/Person/2"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer, USER_TEST), SUCCESS); + + ChangeInfo changeInfo = { ChangeInfo::ChangeType::OTHER, { uri1 } }; + dataObsMgrInnerExt->HandleNotifyChange(changeInfo, USER_TEST); + EXPECT_TRUE(ChangeInfoEqual(observer->changeInfo_, changeInfo)); + + changeInfo.uris_ = { uri1 }; + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange(changeInfo, USER_TEST); + EXPECT_TRUE(ChangeInfoEqual(observer->changeInfo_, changeInfo)); + + changeInfo.uris_ = { uri2 }; + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange(changeInfo, USER_TEST); + EXPECT_TRUE(ChangeInfoEqual(observer->changeInfo_, {})); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0200 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register one non-fuzzy observer mutiple times + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person"); + Uri uri2(uriBase + "/Person/2"); + Uri uri3(uriBase + "/Person/3"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer, 1, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri2, observer, DataObsMgrInnerExt::OBS_NUM_MAX - 1, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri3, observer, DataObsMgrInnerExt::OBS_NUM_MAX, false); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer->changeInfo_.uris_, { uri1 })); + + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri2 } }, USER_TEST); + EXPECT_EQ(observer->onChangeCall_, DataObsMgrInnerExt::OBS_NUM_MAX - 1); + + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri3 } }, USER_TEST); + EXPECT_EQ(observer->onChangeCall_, DataObsMgrInnerExt::OBS_NUM_MAX); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0300 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register mutiple non-fuzzy observer mutiple times + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person"); + Uri uri2(uriBase + "/Person/2"); + Uri uri3(uriBase + "/Person/3"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer3(new (std::nothrow) MockDataAbilityObserverStub()); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer1, USER_TEST), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer2, USER_TEST), SUCCESS); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer2, USER_TEST), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer3, USER_TEST), SUCCESS); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri3, observer3, USER_TEST), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri3, observer1, USER_TEST), SUCCESS); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri1 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, { uri1 })); + EXPECT_TRUE(UrisEqual(observer3->changeInfo_.uris_, {})); + + observer1->ReSet(); + observer2->ReSet(); + observer3->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri2, uri3 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri3 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, { uri2 })); + EXPECT_TRUE(UrisEqual(observer3->changeInfo_.uris_, { uri2, uri3 })); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0400 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register one fuzzy observer one times + * Person1 <-obs + * 2 4 + * 3 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0400, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri123(uriBase + "/Person1/2/3"); + Uri uri14(uriBase + "/Person1/4"); + Uri uri2(uriBase + "/Person2"); + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer, USER_TEST, true), SUCCESS); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer->changeInfo_.uris_, { uri1 })); + + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri12, uri123, uri14, uri2 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer->changeInfo_.uris_, { uri12, uri123, uri14 })); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0500 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register one fuzzy observer mutiple times + * Person1 <-obs + * 2 4 <-2*obs + * 3 5 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0500, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri123(uriBase + "/Person1/2/3"); + Uri uri14(uriBase + "/Person1/4"); + Uri uri145(uriBase + "/Person1/4/5"); + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer, 1, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri14, observer, 2, true); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer->changeInfo_.uris_, { uri1 })); + + observer->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri14, uri145, uri12, uri123 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer->changeInfo_.uris_, { uri14, uri14, uri14, uri145, uri145, uri145, uri12, uri123 })); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0600 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register mutiple fuzzy observer mutiple times + * Person1 <-obs1 + * 2 4 <-obs2 + * obs1->3 5 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0600, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri123(uriBase + "/Person1/2/3"); + Uri uri14(uriBase + "/Person1/4"); + Uri uri145(uriBase + "/Person1/4/5"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer1, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri123, observer1, USER_TEST, true), SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, true), SUCCESS); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri1 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, {})); + + observer1->ReSet(); + observer2->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri14, uri145, uri12, uri123 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri14, uri145, uri12, uri123, uri123 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, { uri14, uri145 })); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0700 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register mix observer mutiple times + * Person1 <-obs1(fuzzy) + * 2 4 <-obs2(fuzzy and nofuzzy) + * 3 5 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0700, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri123(uriBase + "/Person1/2/3"); + Uri uri14(uriBase + "/Person1/4"); + Uri uri145(uriBase + "/Person1/4/5"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer1, USER_TEST, true), SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, false), SUCCESS); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri1 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, {})); + + observer1->ReSet(); + observer2->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri14, uri145, uri12, uri123 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri14, uri145, uri12, uri123 })); + EXPECT_TRUE(UrisEqual(observer2->changeInfo_.uris_, { uri14, uri14, uri145 })); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleUnregisterObserver test + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:UnRegister observer + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleUnregisterObserver_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase1 = "datashare://Authority1/com.domainname.dataability.persondata"; + std::string uriBase2 = "datashare://Authority2/com.domainname.dataability.persondata"; + + Uri uri1(uriBase1 + "/Person1"); + Uri uri12(uriBase1 + "/Person1/2"); + Uri uri2(uriBase2 + "/Person2"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer1, USER_TEST, true), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_TRUE(UrisEqual(observer1->changeInfo_.uris_, { uri1 })); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer1), SUCCESS); + observer1->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_EQ(observer1->onChangeCall_, 0); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleUnregisterObserver test + * SubFunction: 0200 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:UnRegister one observers mutiple times + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleUnregisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 0); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.find(observer)->second->ref, 2); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer, USER_TEST, false), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.find(observer)->second->ref, 3); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 0); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 0); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1 } }, USER_TEST); + EXPECT_EQ(observer->onChangeCall_, 2); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleUnregisterObserver test + * SubFunction: 0300 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:UnRegister mutiple observers on mutiple uri + * Person1 + * 2 3<-2*obs1、obs2 + * obs1->4 5<-obs2 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleUnregisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri13(uriBase + "/Person1/3"); + Uri uri134(uriBase + "/Person1/3/4"); + Uri uri135(uriBase + "/Person1/3/5"); + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri13, observer, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri13, observer, USER_TEST, false), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri134, observer, USER_TEST, false), SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri13, observer2, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri135, observer2, USER_TEST, true), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 2); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.find(observer2)->second->ref, 3); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri135, observer), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri135, observer2), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 2); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.find(observer2)->second->ref, 2); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri135 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri13, observer2), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri135 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri13, observer), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri13 } }, USER_TEST); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri134, observer), SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 0); + EXPECT_TRUE(dataObsMgrInnerExt->root_->childrens_.empty()); + EXPECT_EQ(observer->onChangeCall_, 2); + EXPECT_EQ(observer2->onChangeCall_, 1); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: Register and UnRegister test + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register and UnRegister when observers over limmit + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_RegisterAndUnRegister_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person1"); + Uri uri2(uriBase + "/Person2"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer1, 50, false); + auto obsRecipientRef1 = dataObsMgrInnerExt->obsRecipientRefs.find(observer1); + EXPECT_TRUE(obsRecipientRef1 != dataObsMgrInnerExt->obsRecipientRefs.end() && obsRecipientRef1->second->ref == 51); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer2) == dataObsMgrInnerExt->obsRecipientRefs.end()); + EXPECT_EQ( + dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer1, USER_TEST, false), DATAOBS_SERVICE_OBS_LIMMIT); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer2, USER_TEST, true), DATAOBS_SERVICE_OBS_LIMMIT); + EXPECT_EQ(obsRecipientRef1->second->ref, 51); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer2) == dataObsMgrInnerExt->obsRecipientRefs.end()); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer1), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer1), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer2), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer1) == dataObsMgrInnerExt->obsRecipientRefs.end()); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer2) == dataObsMgrInnerExt->obsRecipientRefs.end()); + EXPECT_EQ(observer1->onChangeCall_, 50); + EXPECT_EQ(observer2->onChangeCall_, 0); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: Register and UnRegister test + * SubFunction: 0200 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Register and UnRegister when observers over limmit + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_RegisterAndUnRegister_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person1"); + Uri uri2(uriBase + "/Person2"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri2, observer1, 20, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri2, observer2, 30, false); + auto obsRecipientRef1 = dataObsMgrInnerExt->obsRecipientRefs.find(observer1); + auto obsRecipientRef2 = dataObsMgrInnerExt->obsRecipientRefs.find(observer2); + EXPECT_TRUE(obsRecipientRef1 != dataObsMgrInnerExt->obsRecipientRefs.end() && obsRecipientRef1->second->ref == 21); + EXPECT_TRUE(obsRecipientRef2 != dataObsMgrInnerExt->obsRecipientRefs.end() && obsRecipientRef2->second->ref == 31); + EXPECT_EQ( + dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer1, USER_TEST, false), DATAOBS_SERVICE_OBS_LIMMIT); + EXPECT_EQ( + dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer2, USER_TEST, false), DATAOBS_SERVICE_OBS_LIMMIT); + EXPECT_EQ(obsRecipientRef1->second->ref, 21); + EXPECT_EQ(obsRecipientRef2->second->ref, 31); + + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer1), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer1), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer2), SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer1) == dataObsMgrInnerExt->obsRecipientRefs.end()); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.find(observer2) == dataObsMgrInnerExt->obsRecipientRefs.end()); + EXPECT_EQ(observer1->onChangeCall_, 40); + EXPECT_EQ(observer2->onChangeCall_, 90); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleUnregisterObserver no uri + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:HandleUnregisterObserver one observers on all uri + * Person1<-5*obs1(fuzzy)+25*obs2 + * 10、20->2 3<-15*obs1+15*obs2 + * 20*obs1->4 5<-25*obs1+5*obs2 + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleUnregisterObserverAll_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri13(uriBase + "/Person1/3"); + Uri uri134(uriBase + "/Person1/3/4"); + Uri uri135(uriBase + "/Person1/3/5"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer1, 5, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri12, observer1, 10, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri13, observer1, 15, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri134, observer1, 20, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri135, observer1, 25, false); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer2, 25, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri12, observer2, 20, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri13, observer2, 15, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri134, observer2, 10, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri135, observer2, 5, false); + + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri1, uri12, uri13, uri134, uri135 } }, USER_TEST); + EXPECT_EQ(observer1->onChangeCall_, 95); + EXPECT_EQ(observer2->onChangeCall_, 205); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(observer1), SUCCESS); + observer1->ReSet(); + observer2->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri1, uri12, uri13, uri134, uri135 } }, USER_TEST); + EXPECT_EQ(observer1->onChangeCall_, 0); + EXPECT_EQ(observer2->onChangeCall_, 205); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(observer2), SUCCESS); + EXPECT_TRUE(dataObsMgrInnerExt->root_->childrens_.empty()); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: DeathRecipient test + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:DeathRecipient + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_DeathRecipient_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri1(uriBase + "/Person1"); + Uri uri12(uriBase + "/Person1/2"); + Uri uri13(uriBase + "/Person1/3"); + Uri uri134(uriBase + "/Person1/3/4"); + Uri uri135(uriBase + "/Person1/3/5"); + + sptr observer1(new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer1, 5, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri12, observer1, 10, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri13, observer1, 15, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri134, observer1, 20, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri135, observer1, 25, false); + + RegisterObserverUtil(dataObsMgrInnerExt, uri1, observer2, 25, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri12, observer2, 20, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri13, observer2, 15, true); + RegisterObserverUtil(dataObsMgrInnerExt, uri134, observer2, 10, false); + RegisterObserverUtil(dataObsMgrInnerExt, uri135, observer2, 5, false); + + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 2); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri1, uri12, uri13, uri134, uri135 } }, USER_TEST); + EXPECT_EQ(observer1->onChangeCall_, 95); + EXPECT_EQ(observer2->onChangeCall_, 205); + + auto it = dataObsMgrInnerExt->obsRecipientRefs.find(observer1->AsObject()); + EXPECT_TRUE(it != dataObsMgrInnerExt->obsRecipientRefs.end() && it->second->deathRecipient != nullptr); + it->second->deathRecipient->OnRemoteDied(observer1->AsObject()); + + observer1->ReSet(); + observer2->ReSet(); + dataObsMgrInnerExt->HandleNotifyChange( + { ChangeInfo::ChangeType::INSERT, { uri1, uri12, uri13, uri134, uri135 } }, USER_TEST); + EXPECT_EQ(observer1->onChangeCall_, 0); + EXPECT_EQ(observer2->onChangeCall_, 205); + dataObsMgrInnerExt->OnCallBackDied(observer2->AsObject()); + EXPECT_TRUE(dataObsMgrInnerExt->root_->childrens_.empty()); + EXPECT_TRUE(dataObsMgrInnerExt->obsRecipientRefs.empty()); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: DeathRecipient test + * SubFunction: 0200 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:DeathRecipient when dataObsMgrInnerExt release + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_DeathRecipient_0200, TestSize.Level1) +{ + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri(uriBase + "/Person1"); + + sptr deathRecipient = nullptr; + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + { + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri, observer, USER_TEST, false), SUCCESS); + + auto it = dataObsMgrInnerExt->obsRecipientRefs.find(observer->AsObject()); + EXPECT_TRUE(it != dataObsMgrInnerExt->obsRecipientRefs.end() && it->second->deathRecipient != nullptr); + deathRecipient = it->second->deathRecipient; + } + + deathRecipient->OnRemoteDied(observer->AsObject()); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: AddObsDeathRecipient test + * SubFunction: 0800 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:Add obs death recipient over max + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_AddObsDeathRecipientOverMax_0800, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri(uriBase + "/Person1"); + + sptr observer = (new (std::nothrow) MockDataAbilityObserverStub()); + auto deathRecipientRef = std::make_shared(nullptr); + deathRecipientRef->ref = std::numeric_limits::max() - 1; + + dataObsMgrInnerExt->obsRecipientRefs.emplace(observer, deathRecipientRef); + + EXPECT_TRUE(dataObsMgrInnerExt->AddObsDeathRecipient(observer)); + deathRecipientRef->ref++; + EXPECT_FALSE(dataObsMgrInnerExt->AddObsDeathRecipient(observer)); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri, observer, USER_TEST), DATAOBS_SERVICE_OBS_LIMMIT); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleRegisterObserver test + * SubFunction: 0800 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:HandleRegisterObserver muti threads + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleRegisterObserver_0800, TestSize.Level1) +{ + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + std::vector uris; + uris.emplace_back(uriBase + "/1"); + uris.emplace_back(uriBase + "/2"); + uris.emplace_back(uriBase + "/1/3"); + uris.emplace_back(uriBase + "/2/4"); + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + + auto func = [](std::vector &uris, std::shared_ptr obsMgr, + sptr &obs) { + for (uint32_t i = 0; i < uris.size() * 5; ++i) { + EXPECT_EQ(obsMgr->HandleRegisterObserver(uris[i % uris.size()], obs, USER_TEST, false), SUCCESS); + } + obs->Notify(); + }; + + sptr observer1 = (new (std::nothrow) MockDataAbilityObserverStub()); + std::thread thread1(std::bind(func, uris, dataObsMgrInnerExt, observer1)); + thread1.detach(); + + sptr observer2 = (new (std::nothrow) MockDataAbilityObserverStub()); + std::thread thread2(std::bind(func, uris, dataObsMgrInnerExt, observer2)); + thread2.detach(); + + observer1->Wait(); + observer2->Wait(); + + EXPECT_EQ( + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uris[0], uris[1] } }, USER_TEST), + SUCCESS); + EXPECT_EQ(observer1->onChangeCall_, 10); + EXPECT_EQ(observer2->onChangeCall_, 10); + dataObsMgrInnerExt->HandleUnregisterObserver(observer1); + + observer1->ReSet(); + observer2->ReSet(); + EXPECT_EQ( + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uris[2], uris[3] } }, USER_TEST), + SUCCESS); + EXPECT_EQ(observer1->onChangeCall_, 0); + EXPECT_EQ(observer2->onChangeCall_, 10); +} + +/* + * Feature: DataObsMgrInnerExt + * Function: HandleNotifyChange test + * SubFunction: 0100 + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:RegisterObserver when NotifyChange + */ +HWTEST_F(DataObsMgrInnerExtTest, DataObsMgrInnerExt_HandleNotifyChange_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInnerExt = std::make_shared(); + std::string uriBase = "datashare://Authority1/com.domainname.dataability.persondata"; + Uri uri(uriBase + "/Person"); + auto sch = uri.GetScheme(); + + sptr observer1 = (new (std::nothrow) MockDataAbilityObserverStub()); + sptr observer2 = (new (std::nothrow) MockDataAbilityObserverStub()); + dataObsMgrInnerExt->HandleRegisterObserver(uri, observer1, USER_TEST); + + observer1->func = [&dataObsMgrInnerExt, &observer2, &uri]() { + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri, observer2, USER_TEST), SUCCESS); + }; + EXPECT_EQ(dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri } }, USER_TEST), SUCCESS); + EXPECT_EQ(observer1->onChangeCall_, 1); + observer1->func = nullptr; + EXPECT_EQ(dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri } }, USER_TEST), SUCCESS); + EXPECT_EQ(observer2->onChangeCall_, 1); +} + +} // namespace DataObsMgrInnerExtTest +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/mock.h b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/mock.h new file mode 100644 index 0000000000000000000000000000000000000000..16e195ed2d97a089e690a5c0ba0ca9acbc1ccc74 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/mock.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_DATAOBS_MGR_INNER_EXT_TEST_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_DATAOBS_MGR_INNER_EXT_TEST_H +#include + +#include "data_ability_observer_stub.h" +#include "dataobs_mgr_inner_ext.h" +#include "gmock/gmock.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace DataObsMgrInnerExtTest { +class MockDataAbilityObserverStub : public DataObs::DataAbilityObserverStub { +public: + void OnChange() override + { + } + + void OnChangeExt(const AAFwk::ChangeInfo &changeInfo) override + { + onChangeCall_ += changeInfo.uris_.size(); + changeInfo_ = changeInfo; + if (func) { + func(); + } + } + + void ReSet() + { + onChangeCall_.store(0); + changeInfo_ = {}; + } + + void Wait() + { + std::unique_lock lck(mtx_); + while (!flag_) { + cv_.wait(lck); + } + } + + void Notify() + { + std::unique_lock lck(mtx_); + flag_ = true; + cv_.notify_one(); + } + +private: + std::atomic_int onChangeCall_ = 0; + AAFwk::ChangeInfo changeInfo_; + std::mutex mtx_; + std::condition_variable cv_; + bool flag_ = false; + std::function func; +}; + +} // namespace DataObsMgrInnerExtTest +} // namespace OHOS + +#endif // UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..afaba7f07f17ed82e43a5a8326763e985e0ef6f2 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/BUILD.gn @@ -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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_inner_pref_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_inner_pref_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/dataobs_mgr_inner_pref_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/dataobs_mgr_inner_pref_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e0939912e5b70483653cc0ef596ed8d67bda98b --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/dataobs_mgr_inner_pref_test.cpp @@ -0,0 +1,352 @@ +/* + * 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. + */ +#include + +#include +#include +#include + +#include "dataobs_mgr_inner_common.h" +#include "uri.h" +#include "data_ability_observer_proxy.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_inner_pref.h" +#include "mock_data_ability_observer_stub.h" + +using namespace OHOS; +using namespace testing::ext; +using namespace testing; + +namespace OHOS { +namespace DataObs { +using Uri = OHOS::Uri; +using ObsListType = std::list; +using ObsRecipientMapType = OHOS::DataObs::DataObsMgrInnerPref::ObsRecipientMapType; +class DataObsMgrInnerPrefTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr dataObsMgrInnerPref_ = nullptr; +}; +void DataObsMgrInnerPrefTest::SetUpTestCase(void) +{ +} +void DataObsMgrInnerPrefTest::TearDownTestCase(void) +{ +} +void DataObsMgrInnerPrefTest::SetUp() +{ + dataObsMgrInnerPref_ = std::make_shared(); +} +void DataObsMgrInnerPrefTest::TearDown() +{ +} + +static constexpr int64_t USER_TEST = 100; + +/* + * Feature: DataObsMgrInnerPref + * Function: Register and unregister function test + * SubFunction: HandleRegisterObserver/HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleRegisterObserver_0100, TestSize.Level1) +{ + if (dataObsMgrInnerPref_ == nullptr) { + return; + } + + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInnerPref_->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + + EXPECT_EQ(dataObsMgrInnerPref_->HaveRegistered(callback), true); + dataObsMgrInnerPref_->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(dataObsMgrInnerPref_->HaveRegistered(callback), false); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Register function test + * SubFunction: HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleRegisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, OBS_EXIST); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Register function test + * SubFunction: HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleRegisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback1(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback1, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, OBS_EXIST); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleUnregisterObserver_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInner->observers_.clear(); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_OBS_FOR_URI); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleUnregisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleUnregisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback2(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + obsList.push_back(ObserverNode(callback2, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + dataObsMgrInner->observers_.emplace("exit", obsList); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Notify function test + * SubFunction: HandleNotifyChange + * FunctionPoints: When the data changes, call the OnChangePreferences function + * of the registered dataabilityobserver EnvConditions: NA CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleNotifyChange_0100, TestSize.Level1) +{ + if (dataObsMgrInnerPref_ == nullptr) { + return; + } + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr mockDataAbilityObserverStub(new (std::nothrow) MockDataAbilityObserverStub()); + + Uri notifyUri("sharepreferences://data/preferences/preferences_test?key"); + dataObsMgrInnerPref_->HandleRegisterObserver(uri, ObserverNode(mockDataAbilityObserverStub, USER_TEST)); + dataObsMgrInnerPref_->HandleNotifyChange(notifyUri, USER_TEST); + EXPECT_EQ("key", mockDataAbilityObserverStub->key_); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Notify function test + * SubFunction: HandleNotifyChange + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleNotifyChange_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test?key"); + dataObsMgrInner->observers_.clear(); + int res = dataObsMgrInner->HandleNotifyChange(uri, USER_TEST); + EXPECT_EQ(res, NO_OBS_FOR_URI); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Notify function test + * SubFunction: HandleNotifyChange + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_HandleNotifyChange_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("sharepreferences://data/preferences/preferences_test"); + ObsListType obsList; + obsList.push_back(ObserverNode(nullptr, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + Uri notifyUri("sharepreferences://data/preferences/preferences_test?key"); + int res = dataObsMgrInner->HandleNotifyChange(notifyUri, USER_TEST); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: GetObsListFromMap/RemoveObs/HaveRegistered function test + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_RemoveObs_HaveRegistered_0100, TestSize.Level1) +{ + if (dataObsMgrInnerPref_ == nullptr) { + return; + } + Uri uri("sharepreferences://data/preferences/preferences_test"); + sptr mockDataAbilityObserverStub(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(mockDataAbilityObserverStub)); + dataObsMgrInnerPref_->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + + sptr mockDataAbilityObserverStub2(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback2( + new (std::nothrow) DataAbilityObserverProxy(mockDataAbilityObserverStub2)); + + dataObsMgrInnerPref_->HandleRegisterObserver(uri, ObserverNode(callback2, USER_TEST)); + auto obsPair = dataObsMgrInnerPref_->observers_.find(uri.ToString()); + EXPECT_EQ((std::size_t)2, obsPair->second.size()); + EXPECT_EQ(true, dataObsMgrInnerPref_->HaveRegistered(callback)); + EXPECT_EQ(true, dataObsMgrInnerPref_->HaveRegistered(callback2)); + + dataObsMgrInnerPref_->RemoveObs(callback->AsObject()); + EXPECT_EQ(false, dataObsMgrInnerPref_->HaveRegistered(callback)); + obsPair->second.clear(); + obsPair = dataObsMgrInnerPref_->observers_.find(uri.ToString()); + EXPECT_EQ(false, dataObsMgrInnerPref_->HaveRegistered(callback)); + + dataObsMgrInnerPref_->RemoveObs(callback2->AsObject()); + EXPECT_EQ(false, dataObsMgrInnerPref_->HaveRegistered(callback2)); + obsPair->second.clear(); + obsPair = dataObsMgrInnerPref_->observers_.find(uri.ToString()); + EXPECT_EQ(false, dataObsMgrInnerPref_->HaveRegistered(callback2)); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: AddObsDeathRecipient/RemoveObsDeathRecipient function test + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_AddRemove_ObsDeathRecipient_0100, TestSize.Level1) +{ + if (dataObsMgrInnerPref_ == nullptr) { + return; + } + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInnerPref_->AddObsDeathRecipient(callback); + dataObsMgrInnerPref_->AddObsDeathRecipient(nullptr); + + ObsRecipientMapType::const_iterator it; + it = dataObsMgrInnerPref_->obsRecipient_.find(observer); + EXPECT_EQ(true, it != dataObsMgrInnerPref_->obsRecipient_.end()); + + dataObsMgrInnerPref_->RemoveObsDeathRecipient(callback->AsObject()); + dataObsMgrInnerPref_->RemoveObsDeathRecipient(nullptr); + it = dataObsMgrInnerPref_->obsRecipient_.find(observer); + EXPECT_EQ(false, it != dataObsMgrInnerPref_->obsRecipient_.end()); + + dataObsMgrInnerPref_->obsRecipient_.clear(); + dataObsMgrInnerPref_->RemoveObsDeathRecipient(callback->AsObject()); +} + +/* + * Feature: DataObsMgrInnerPref + * Function: Unregister function test + * SubFunction: RemoveObs + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerPrefTest, DataObsMgrInnerPref_RemoveObs_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + ASSERT_NE(dataObsMgrInner, nullptr); + std::string uri1 = "uri1"; + std::string uri2 = "uri2"; + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback1(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback2(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList1; + ObsListType obsList2; + ObsListType obsList3; + obsList1.push_back(ObserverNode(callback1, USER_TEST)); + obsList2.push_back(ObserverNode(callback1, USER_TEST)); + obsList2.push_back(ObserverNode(callback2, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri1, obsList1); + dataObsMgrInner->observers_.emplace(uri2, obsList2); + dataObsMgrInner->RemoveObs(callback2->AsObject()); +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/mock_data_ability_observer_stub.h b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/mock_data_ability_observer_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..8a07f9092116150b72e2d7cf53278f64d6940441 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/mock_data_ability_observer_stub.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H +#include + +#include "data_ability_observer_stub.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace DataObs { +class MockDataAbilityObserverStub : public DataAbilityObserverStub { +public: + MOCK_METHOD0(OnChange, void()); + MOCK_METHOD1(OnChangeExt, void(const ChangeInfo &)); + + void OnChangePreferences(const std::string &key) + { + key_ = key; + } + + void Wait() + { + sem_.Wait(); + } + + int Post() + { + sem_.Post(); + return 0; + } + + void PostVoid() + { + sem_.Post(); + } + +private: + std::string key_; + Semaphore sem_; +}; +} // namespace DataObs +} // namespace OHOS + +#endif // UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..48c0fa73e84821eabb77c835e41f7b6b06b9ca09 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021-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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_inner_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_inner_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/dataobs_mgr_inner_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/dataobs_mgr_inner_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2c38614900e03d7ced97fdfc7ca5fc4cf2ba84e --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/dataobs_mgr_inner_test.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2021 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 + +#include +#include +#include + +#include "uri.h" +#include "data_ability_observer_proxy.h" +#include "dataobs_mgr_errors.h" +#include "dataobs_mgr_inner.h" +#include "mock_data_ability_observer_stub.h" + +using namespace OHOS; +using namespace testing::ext; +using namespace testing; + +namespace OHOS { +namespace DataObs { +using Uri = OHOS::Uri; +using ObsListType = std::list; +using ObsRecipientMapType = OHOS::DataObs::DataObsMgrInner::ObsRecipientMapType; +class DataObsMgrInnerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr dataObsMgrInner_ = nullptr; +}; +void DataObsMgrInnerTest::SetUpTestCase(void) +{ +} +void DataObsMgrInnerTest::TearDownTestCase(void) +{ +} +void DataObsMgrInnerTest::SetUp() +{ + dataObsMgrInner_ = std::make_shared(); +} +void DataObsMgrInnerTest::TearDown() +{ +} + +static constexpr int64_t USER_TEST = 100; + +/* + * Feature: DataObsMgrInner + * Function: Register and unregister function test + * SubFunction: HandleRegisterObserver/HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleRegisterObserver_0100, TestSize.Level1) +{ + if (dataObsMgrInner_ == nullptr) { + return; + } + + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInner_->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + + EXPECT_EQ(dataObsMgrInner_->HaveRegistered(callback), true); + dataObsMgrInner_->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(dataObsMgrInner_->HaveRegistered(callback), false); +} + +/* + * Feature: DataObsMgrInner + * Function: Register function test + * SubFunction: HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleRegisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, OBS_EXIST); +} + +/* + * Feature: DataObsMgrInner + * Function: Register function test + * SubFunction: HandleRegisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleRegisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback1(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback1, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, OBS_EXIST); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleUnregisterObserver_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInner->observers_.clear(); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_OBS_FOR_URI); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleUnregisterObserver_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleUnregisterObserver_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback2(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList; + obsList.push_back(ObserverNode(callback, USER_TEST)); + obsList.push_back(ObserverNode(callback2, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + dataObsMgrInner->observers_.emplace("exit", obsList); + int res = dataObsMgrInner->HandleUnregisterObserver(uri, ObserverNode(callback, USER_TEST)); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInner + * Function: Register and unregister function test + * SubFunction: OnChange + * FunctionPoints: When the data changes, call the OnChange function of the + * registered dataabilityobserver EnvConditions: NA CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleNotifyChange_0100, TestSize.Level1) +{ + if (dataObsMgrInner_ == nullptr) { + return; + } + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr mockDataAbilityObserverStub(new (std::nothrow) MockDataAbilityObserverStub()); + + EXPECT_CALL(*mockDataAbilityObserverStub, OnChange()).Times(1); + + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(mockDataAbilityObserverStub)); + dataObsMgrInner_->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + dataObsMgrInner_->HandleNotifyChange(uri, USER_TEST); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleNotifyChange_0200, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + dataObsMgrInner->observers_.clear(); + int res = dataObsMgrInner->HandleNotifyChange(uri, USER_TEST); + EXPECT_EQ(res, NO_OBS_FOR_URI); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: HandleUnregisterObserver + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_HandleNotifyChange_0300, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + ObsListType obsList; + obsList.push_back(ObserverNode(nullptr, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri.ToString(), obsList); + int res = dataObsMgrInner->HandleNotifyChange(uri, USER_TEST); + EXPECT_EQ(res, NO_ERROR); +} + +/* + * Feature: DataObsMgrInner + * Function: GetObsListFromMap/RemoveObs/HaveRegistered function test + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_RemoveObs_HaveRegistered_0100, TestSize.Level1) +{ + if (dataObsMgrInner_ == nullptr) { + return; + } + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + sptr mockDataAbilityObserverStub(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback(new (std::nothrow) DataAbilityObserverProxy(mockDataAbilityObserverStub)); + dataObsMgrInner_->HandleRegisterObserver(uri, ObserverNode(callback, USER_TEST)); + + sptr mockDataAbilityObserverStub2(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback2( + new (std::nothrow) DataAbilityObserverProxy(mockDataAbilityObserverStub2)); + + dataObsMgrInner_->HandleRegisterObserver(uri, ObserverNode(callback2, USER_TEST)); + auto obsPair = dataObsMgrInner_->observers_.find(uri.ToString()); + EXPECT_EQ((std::size_t)2, obsPair->second.size()); + EXPECT_EQ(true, dataObsMgrInner_->HaveRegistered(callback)); + EXPECT_EQ(true, dataObsMgrInner_->HaveRegistered(callback2)); + + dataObsMgrInner_->RemoveObs(callback->AsObject()); + EXPECT_EQ(false, dataObsMgrInner_->HaveRegistered(callback)); + obsPair->second.clear(); + obsPair = dataObsMgrInner_->observers_.find(uri.ToString()); + EXPECT_EQ(false, dataObsMgrInner_->HaveRegistered(callback)); + + dataObsMgrInner_->RemoveObs(callback2->AsObject()); + EXPECT_EQ(false, dataObsMgrInner_->HaveRegistered(callback2)); + obsPair->second.clear(); + obsPair = dataObsMgrInner_->observers_.find(uri.ToString()); + EXPECT_EQ(false, dataObsMgrInner_->HaveRegistered(callback2)); +} + +/* + * Feature: DataObsMgrInner + * Function: AddObsDeathRecipient/RemoveObsDeathRecipient function test + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_AddRemove_ObsDeathRecipient_0100, TestSize.Level1) +{ + if (dataObsMgrInner_ == nullptr) { + return; + } + + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + sptr callback(new (std::nothrow) DataAbilityObserverProxy(observer)); + dataObsMgrInner_->AddObsDeathRecipient(callback); + dataObsMgrInner_->AddObsDeathRecipient(nullptr); + + ObsRecipientMapType::const_iterator it; + it = dataObsMgrInner_->obsRecipient_.find(observer); + EXPECT_EQ(true, it != dataObsMgrInner_->obsRecipient_.end()); + + dataObsMgrInner_->RemoveObsDeathRecipient(callback->AsObject()); + dataObsMgrInner_->RemoveObsDeathRecipient(nullptr); + it = dataObsMgrInner_->obsRecipient_.find(observer); + EXPECT_EQ(false, it != dataObsMgrInner_->obsRecipient_.end()); + + dataObsMgrInner_->obsRecipient_.clear(); + dataObsMgrInner_->RemoveObsDeathRecipient(callback->AsObject()); +} + +/* + * Feature: DataObsMgrInner + * Function: Unregister function test + * SubFunction: RemoveObs + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription:NA + */ +HWTEST_F(DataObsMgrInnerTest, DataObsMgrInner_RemoveObs_0100, TestSize.Level1) +{ + std::shared_ptr dataObsMgrInner = std::make_shared(); + ASSERT_NE(dataObsMgrInner, nullptr); + std::string uri1 = "uri1"; + std::string uri2 = "uri2"; + sptr observer(new (std::nothrow) MockDataAbilityObserverStub()); + const sptr callback1(new (std::nothrow) DataAbilityObserverProxy(observer)); + const sptr callback2(new (std::nothrow) DataAbilityObserverProxy(observer)); + ObsListType obsList1; + ObsListType obsList2; + ObsListType obsList3; + obsList1.push_back(ObserverNode(callback1, USER_TEST)); + obsList2.push_back(ObserverNode(callback1, USER_TEST)); + obsList2.push_back(ObserverNode(callback2, USER_TEST)); + dataObsMgrInner->observers_.emplace(uri1, obsList1); + dataObsMgrInner->observers_.emplace(uri2, obsList2); + dataObsMgrInner->RemoveObs(callback2->AsObject()); +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/mock_data_ability_observer_stub.h b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/mock_data_ability_observer_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..e48eea982a450da9a92f3450b9ef15ebd5e217f6 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/mock_data_ability_observer_stub.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H +#include + +#include "data_ability_observer_stub.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace DataObs { +class MockDataAbilityObserverStub : public DataAbilityObserverStub { +public: + MOCK_METHOD0(OnChange, void()); + MOCK_METHOD1(OnChangeExt, void(const ChangeInfo &)); + + void Wait() + { + sem_.Wait(); + } + + int Post() + { + sem_.Post(); + return 0; + } + + void PostVoid() + { + sem_.Post(); + } + +private: + Semaphore sem_; +}; +} // namespace DataObs +} // namespace OHOS + +#endif // UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_CALL_H diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..cbef11e91a88f5e6595ce4032262f99b5c8ad372 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/BUILD.gn @@ -0,0 +1,61 @@ +# 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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_service_second_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_service_second_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:task_handler_wrap", + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:datamgr_common", + "safwk:api_cache_manager", + "safwk:system_ability_fwk", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/dataobs_mgr_service_second_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/dataobs_mgr_service_second_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..637876b3ebd71f7e2f14515a0bd0cb73bc014277 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/dataobs_mgr_service_second_test.cpp @@ -0,0 +1,306 @@ +/* + * 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. + */ +#include + +#include "dataobs_log.h" +#include "dataobs_mgr_service.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace OHOS { +namespace DataObs { +using namespace testing::ext; +class DataObsMgrServiceSecondTest : public testing::Test { +public: + DataObsMgrServiceSecondTest() = default; + virtual ~DataObsMgrServiceSecondTest() = default; + + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +void DataObsMgrServiceSecondTest::SetUpTestCase(void) +{ +} +void DataObsMgrServiceSecondTest::TearDownTestCase(void) +{ +} +void DataObsMgrServiceSecondTest::SetUp() +{ +} +void DataObsMgrServiceSecondTest::TearDown() +{ +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChange_0100, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0100 start"); + const int testVal = static_cast(NO_ERROR); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + dataObsMgrServer->Init(); + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0100 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChange_0200, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0200 start"); + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = std::make_shared(); + dataObsMgrServer->Init(); + auto tmp = dataObsMgrServer->dataObsMgrInner_; + dataObsMgrServer->dataObsMgrInner_ = nullptr; + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + dataObsMgrServer->dataObsMgrInner_ = tmp; + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0200 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChange_0300, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0300 start"); + const int testVal = static_cast(DATAOBS_SERVICE_TASK_LIMMIT); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = std::make_shared(); + dataObsMgrServer->Init(); + auto tmp = dataObsMgrServer->taskCount_; + dataObsMgrServer->taskCount_ = DataObsMgrService::TASK_COUNT_MAX; + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + dataObsMgrServer->taskCount_ = tmp; + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChange_0300 end"); +} + +/* + * Feature: DataObsMgrService + * Function: DeepCopyChangeInfo + * SubFunction: NA + * FunctionPoints: DataObsMgrService DeepCopyChangeInfo + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService DeepCopyChangeInfo is + * normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0100, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0100 start"); + const int testVal = static_cast(SUCCESS); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + ChangeInfo src; + ChangeInfo dst; + + EXPECT_EQ(testVal, dataObsMgrServer->DeepCopyChangeInfo(src, dst)); + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0100 end"); +} + +/* + * Feature: DataObsMgrService + * Function: DeepCopyChangeInfo + * SubFunction: NA + * FunctionPoints: DataObsMgrService DeepCopyChangeInfo + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService DeepCopyChangeInfo is + * normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0200, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0200 start"); + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + ChangeInfo src; + ChangeInfo dst; + src.size_ = std::numeric_limits::max(); + + EXPECT_EQ(testVal, dataObsMgrServer->DeepCopyChangeInfo(src, dst)); + src.size_ = 0; + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0200 end"); +} + +/* + * Feature: DataObsMgrService + * Function: DeepCopyChangeInfo + * SubFunction: NA + * FunctionPoints: DataObsMgrService DeepCopyChangeInfo + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService DeepCopyChangeInfo is + * normal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0300, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0300 start"); + const int testVal = static_cast(SUCCESS); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + ChangeInfo src; + src.size_ = 1; + src.data_ = new uint8_t[src.size_]; + ChangeInfo dst; + + EXPECT_EQ(testVal, dataObsMgrServer->DeepCopyChangeInfo(src, dst)); + delete[] static_cast(src.data_); + src.data_ = nullptr; + src.size_ = 0; + delete[] static_cast(dst.data_); + dst.data_ = nullptr; + dst.size_ = 0; + LOG_INFO("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0300 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChangeExt_0100, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0100 start"); + const int testVal = static_cast(SUCCESS); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + dataObsMgrServer->Init(); + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt({ ChangeInfo::ChangeType::UPDATE, { uri } })); + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0100 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChangeExt_0200, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0200 start"); + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = std::make_shared(); + dataObsMgrServer->Init(); + auto tmp = dataObsMgrServer->dataObsMgrInnerExt_; + dataObsMgrServer->dataObsMgrInnerExt_ = nullptr; + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt({ ChangeInfo::ChangeType::UPDATE, { uri } })); + dataObsMgrServer->dataObsMgrInnerExt_ = tmp; + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0200 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChangeExt_0300, TestSize.Level1) + +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0300 start"); + const int testVal = static_cast(DATAOBS_SERVICE_TASK_LIMMIT); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = std::make_shared(); + dataObsMgrServer->Init(); + auto tmp = dataObsMgrServer->taskCount_; + dataObsMgrServer->taskCount_ = DataObsMgrService::TASK_COUNT_MAX; + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt({ ChangeInfo::ChangeType::UPDATE, { uri } })); + dataObsMgrServer->taskCount_ = tmp; + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0300 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyChangeExt_0400, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0400 start"); + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + dataObsMgrServer->Init(); + ChangeInfo changeInfo; + auto tmp = changeInfo.size_; + changeInfo.size_ = std::numeric_limits::max(); + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt(changeInfo)); + changeInfo.size_ = tmp; + LOG_INFO("DataObsMgrServiceSecondTest_NotifyChangeExt_0400 end"); +} + +/* + * Feature: DataObsMgrService + * Function: NotifyProcessObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyProcessObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyProcessObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceSecondTest, DataObsMgrServiceSecondTest_NotifyProcessObserver_0100, TestSize.Level1) +{ + LOG_INFO("DataObsMgrServiceSecondTest_NotifyProcessObserver_0100 start"); + const int testVal = static_cast(DATAOBS_PROXY_INNER_ERR); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + const std::string key; + const sptr observer; + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyProcessObserver(key, observer)); + LOG_INFO("DataObsMgrServiceSecondTest_NotifyProcessObserver_0100 end"); +} + +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..01fcf125f3eab521eb8914acd25d3d738e8db942 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2021-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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_service_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_service_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:task_handler_wrap", + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:datamgr_common", + "safwk:api_cache_manager", + "safwk:system_ability_fwk", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/dataobs_mgr_service_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/dataobs_mgr_service_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00f38d3fbc6954847aa6795c6d18a0016b24f7b9 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/dataobs_mgr_service_test.cpp @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2021 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 + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "mock_data_ability_observer_stub.h" +#include "dataobs_mgr_service.h" + +namespace OHOS { +namespace DataObs { +using namespace testing::ext; +class DataObsMgrServiceTest : public testing::Test { +public: + DataObsMgrServiceTest() = default; + virtual ~DataObsMgrServiceTest() = default; + + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +void DataObsMgrServiceTest::SetUpTestCase(void) +{ +} +void DataObsMgrServiceTest::TearDownTestCase(void) +{ +} +void DataObsMgrServiceTest::SetUp() +{ +} +void DataObsMgrServiceTest::TearDown() +{ +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_RegisterObserver_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0100 start"; + const int testVal = static_cast(NO_ERROR); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserver(*uri, dataobsAbility)); + + testing::Mock::AllowLeak(dataobsAbility); + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_RegisterObserver_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0200 start"; + const int testVal = static_cast(DATA_OBSERVER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserver(*uri, nullptr)); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0200 end"; +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_RegisterObserver_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0300 start"; + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInner_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserver(*uri, dataobsAbility)); + dataObsMgrServer->dataObsMgrInner_ = std::make_shared(); + + testing::Mock::AllowLeak(dataobsAbility); + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_RegisterObserver_0300 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserver is + * normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_UnregisterObserver_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0100 start"; + const int testVal = static_cast(NO_ERROR); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserver(*uri, dataobsAbility)); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserver(*uri, dataobsAbility)); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_UnregisterObserver_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0200 start"; + const int testVal = static_cast(DATA_OBSERVER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserver(*uri, nullptr)); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0200 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserver + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_UnregisterObserver_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0300 start"; + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInner_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserver(*uri, dataobsAbility)); + dataObsMgrServer->dataObsMgrInner_ = std::make_shared(); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_UnregisterObserver_0300 end"; +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_NotifyChange_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0100 start"; + const int testVal = static_cast(DATAOBS_SERVICE_HANDLER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_NotifyChange_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0300 start"; + const int testVal = static_cast(DATAOBS_SERVICE_HANDLER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInner_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + dataObsMgrServer->dataObsMgrInner_ = std::make_shared(); + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0300 end"; +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChange is abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataShare_DataObsMgrServiceTest_NotifyChange_0400, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0400 start"; + const int testVal = static_cast(DATAOBS_SERVICE_HANDLER_IS_NULL); + std::shared_ptr uri = std::make_shared("dataability://device_id/" + "com.domainname.dataability.persondata/person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->taskCount_ = 50; + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChange(*uri)); + dataObsMgrServer->taskCount_ = 0; + + GTEST_LOG_(INFO) << "DataShare_DataObsMgrServiceTest_NotifyChange_0400 end"; +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_RegisterObserverExt_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0100 start"; + const int testVal = static_cast(NO_ERROR); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, dataobsAbility, false)); + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, dataobsAbility, true)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_RegisterObserverExt_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0200 start"; + const int testVal = static_cast(DATA_OBSERVER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, nullptr, true)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0200 end"; +} + +/* + * Feature: DataObsMgrService + * Function: RegisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService RegisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService RegisterObserver is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_RegisterObserverExt_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0300 start"; + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInnerExt_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, dataobsAbility, true)); + dataObsMgrServer->dataObsMgrInnerExt_ = std::make_shared(); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_RegisterObserverExt_0300 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0100 start"; + const int testVal = static_cast(NO_ERROR); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, dataobsAbility, true)); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(uri, dataobsAbility)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0200 start"; + const int testVal = static_cast(NO_ERROR); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->RegisterObserverExt(uri, dataobsAbility, true)); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(dataobsAbility)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0200 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0300 start"; + const int testVal = static_cast(DATA_OBSERVER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(uri, nullptr)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0300 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0400, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0400 start"; + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInnerExt_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(uri, dataobsAbility)); + dataObsMgrServer->dataObsMgrInnerExt_ = std::make_shared(); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0400 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0500, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0500 start"; + const int testVal = static_cast(DATA_OBSERVER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(nullptr)); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0500 end"; +} + +/* + * Feature: DataObsMgrService + * Function: UnregisterObserverExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService UnregisterObserverExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService UnregisterObserverExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_UnregisterObserverExt_0600, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0600 start"; + const int testVal = static_cast(DATAOBS_SERVICE_INNER_IS_NULL); + const sptr dataobsAbility(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInnerExt_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->UnregisterObserverExt(dataobsAbility)); + dataObsMgrServer->dataObsMgrInnerExt_ = std::make_shared(); + + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_UnregisterObserverExt_0600 end"; +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is normal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_NotifyChangeExt_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_NotifyChangeExt_0100 start"; + const int testVal = static_cast(DATAOBS_SERVICE_HANDLER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt({ ChangeInfo::ChangeType::UPDATE, { uri } })); + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_NotifyChangeExt_0100 end"; +} + +/* + * Feature: DataObsMgrService + * Function: NotifyChangeExt + * SubFunction: NA + * FunctionPoints: DataObsMgrService NotifyChangeExt + * EnvConditions: NA + * CaseDescription: Verify that the DataObsMgrService NotifyChangeExt is + * abnormal. + */ +HWTEST_F(DataObsMgrServiceTest, DataObsMgrServiceTest_NotifyChangeExt_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_NotifyChangeExt_0300 start"; + const int testVal = static_cast(DATAOBS_SERVICE_HANDLER_IS_NULL); + Uri uri("dataobs://authority/com.domainname.dataability.persondata/ person/10"); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + + dataObsMgrServer->dataObsMgrInner_.reset(); + EXPECT_EQ(testVal, dataObsMgrServer->NotifyChangeExt({ ChangeInfo::ChangeType::UPDATE, { uri } })); + dataObsMgrServer->dataObsMgrInner_ = std::make_shared(); + GTEST_LOG_(INFO) << "DataObsMgrServiceTest_NotifyChangeExt_0300 end"; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/mock_data_ability_observer_stub.h b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/mock_data_ability_observer_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..46ebc675f2d5b1fcb45d274e07fc0fb1c3f0eca7 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/mock_data_ability_observer_stub.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_H +#include + +#include "data_ability_observer_stub.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace OHOS { +namespace AAFwk { +class MockDataAbilityObserverStub : public DataObs::DataAbilityObserverStub { +public: + MockDataAbilityObserverStub() = default; + virtual ~MockDataAbilityObserverStub() = default; + MOCK_METHOD0(OnChange, void(void)); +}; +} // namespace DataObs +} // namespace OHOS +#endif /* UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_ABILITY_OBSERVER_STUB_H */ diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/BUILD.gn b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..fddb86ed4257f4e3a5bd7fcc3e3d323fd9a5de2a --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021-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. +import("//build/ohos_var.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +ohos_unittest("dataobs_mgr_stub_test") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../cfi_blocklist.txt" + } + module_out_path = module_output_path + + include_dirs = [] + + sources = [ "dataobs_mgr_stub_test.cpp" ] + + configs = [ "${dataobsmgr_path}/framework:dataobsms_config" ] + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/framework:dataobsms_static", + "${dataobsmgr_path}/interfaces:dataobs_manager", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "c_utils:utils", + "eventhandler:libeventhandler", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:datamgr_common", + ] +} diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/dataobs_mgr_stub_test.cpp b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/dataobs_mgr_stub_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e6273879c092648cf9ba1a22b41888c48459c40 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/dataobs_mgr_stub_test.cpp @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2021 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 + +#include "dataobs_mgr_proxy.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "mock_data_obs_mgr_stub.h" + +namespace OHOS { +namespace DataObs { +using namespace testing::ext; +class DataObsManagerStubTest : public testing::Test { +public: + DataObsManagerStubTest() = default; + virtual ~DataObsManagerStubTest() = default; + + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +void DataObsManagerStubTest::SetUpTestCase(void) +{ +} +void DataObsManagerStubTest::TearDownTestCase(void) +{ +} +void DataObsManagerStubTest::SetUp() +{ +} +void DataObsManagerStubTest::TearDown() +{ +} + +/* + * Feature: DataObsManagerStub + * Function: OnRemoteRequest + * SubFunction: NA + * FunctionPoints: DataObsManagerStub OnRemoteRequest + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub OnRemoteRequest is + * normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_OnRemoteRequest_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_OnRemoteRequest_0100 start"; + std::shared_ptr dataobs = std::make_shared(); + uint32_t code = IDataObsMgr::TRANS_BUTT + 1; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + + const int retval = dataobs->OnRemoteRequest(code, data, reply); + + EXPECT_EQ(TEST_RETVAL_ONREMOTEREQUEST, retval); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_OnRemoteRequest_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: OnRemoteRequest + * SubFunction: NA + * FunctionPoints: DataObsManagerStub OnRemoteRequest + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub OnRemoteRequest is + * normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_RegisterObserver_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_RegisterObserver_0100 start"; + const int testVal1 = static_cast(NO_ERROR); + const int testVal2 = static_cast(TEST_RETVAL_ONREMOTEREQUEST); + std::shared_ptr dataobs = std::make_shared(); + sptr dataObserver(new (std::nothrow) MockDataAbilityObserverStub()); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + uint32_t code = IDataObsMgr::REGISTER_OBSERVER; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + if (dataObserver == nullptr) { + return; + } + + if (!data.WriteParcelable(dataObserver->AsObject())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(dataObserver->AsObject()) retval " + "is false end"; + return; + } + + EXPECT_CALL(*dataobs, RegisterObserver(testing::_, testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_RegisterObserver_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: UnregisterObserver + * SubFunction: NA + * FunctionPoints: DataObsManagerStub UnregisterObserver + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub UnregisterObserver is + * normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_UnregisterObserver_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_UnregisterObserver_0100 start"; + const int testVal1 = static_cast(NO_ERROR); + const int testVal2 = static_cast(TEST_RETVAL_ONREMOTEREQUEST); + std::shared_ptr dataobs = std::make_shared(); + sptr dataObserver(new (std::nothrow) MockDataAbilityObserverStub()); + + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + uint32_t code = IDataObsMgr::UNREGISTER_OBSERVER; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + if (dataObserver == nullptr) { + return; + } + + if (!data.WriteParcelable(dataObserver->AsObject())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(dataObserver->AsObject()) retval " + "is false end"; + return; + } + + EXPECT_CALL(*dataobs, UnregisterObserver(testing::_, testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_UnregisterObserver_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: NotifyChange + * SubFunction: NA + * FunctionPoints: DataObsManagerStub NotifyChange + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub NotifyChange is normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_NotifyChange_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_NotifyChange_0100 start"; + std::shared_ptr dataobs = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + const int testVal1 = static_cast(NO_ERROR); + const int testVal2 = static_cast(TEST_RETVAL_ONREMOTEREQUEST); + uint32_t code = IDataObsMgr::NOTIFY_CHANGE; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + + EXPECT_CALL(*dataobs, + NotifyChange(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_NotifyChange_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: RegisterObserverExtInner + * SubFunction: NA + * FunctionPoints: DataObsManagerStub RegisterObserverExtInner + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub RegisterObserverExtInner + * is normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_RegisterObserverExtInner_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_RegisterObserverExtInner_0100 start"; + std::shared_ptr dataobs = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + const int testVal1 = static_cast(NO_ERROR); + const Status testVal2 = SUCCESS; + uint32_t code = IDataObsMgr::REGISTER_OBSERVER_EXT; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + + EXPECT_CALL(*dataobs, RegisterObserverExt(testing::_, testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_RegisterObserverExtInner_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: UnregisterObserverExtInner + * SubFunction: NA + * FunctionPoints: DataObsManagerStub UnregisterObserverExtInner + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub + * UnregisterObserverExtInner is normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_UnregisterObserverExtInner_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_" + "UnregisterObserverExtInner_0100 start"; + std::shared_ptr dataobs = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + const int testVal1 = static_cast(NO_ERROR); + const Status testVal2 = SUCCESS; + uint32_t code = IDataObsMgr::UNREGISTER_OBSERVER_EXT; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + + EXPECT_CALL(*dataobs, UnregisterObserverExt(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_UnregisterObserverExtInner_0100 end"; +} + +/* + * Feature: DataObsManagerStub + * Function: UnregisterObserverExtALLInner + * SubFunction: NA + * FunctionPoints: DataObsManagerStub UnregisterObserverExtALLInner + * EnvConditions: NA + * CaseDescription: Verify that the DataObsManagerStub + * UnregisterObserverExtALLInner is normal. + */ +HWTEST_F(DataObsManagerStubTest, DataShare_DataObsManagerStubTest_UnregisterObserverExtALLInner_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_" + "UnregisterObserverExtALLInner_0100 start"; + std::shared_ptr dataobs = std::make_shared(); + Uri uri("dataability://device_id/com.domainname.dataability.persondata/" + "person/10"); + const int testVal1 = static_cast(NO_ERROR); + const Status testVal2 = SUCCESS; + uint32_t code = IDataObsMgr::UNREGISTER_OBSERVER_ALL_EXT; + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(DataObsManagerProxy::GetDescriptor())) { + GTEST_LOG_(ERROR) << "---------- WriteInterfaceToken(data) retval is false end"; + return; + } + if (!data.WriteString(uri.ToString())) { + GTEST_LOG_(ERROR) << "---------- data.WriteParcelable(uri) retval is false end"; + return; + } + + EXPECT_CALL(*dataobs, UnregisterObserverExt(testing::_, testing::_)).Times(1).WillOnce(testing::Return(testVal2)); + + const int retval1 = dataobs->OnRemoteRequest(code, data, reply); + const int retval2 = reply.ReadInt32(); + + EXPECT_EQ(testVal1, retval1); + EXPECT_EQ(testVal2, retval2); + GTEST_LOG_(INFO) << "DataShare_DataObsManagerStubTest_" + "UnregisterObserverExtALLInner_0100 end"; +} +} // namespace DataObs +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/mock_data_obs_mgr_stub.h b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/mock_data_obs_mgr_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..3d97c42b1e51e4dca2cabdd030218fa964ac45c0 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/mock_data_obs_mgr_stub.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MGR_STUB_H +#define UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MGR_STUB_H +#include + +#include "data_ability_observer_stub.h" +#include "dataobs_mgr_stub.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#define TEST_RETVAL_ONREMOTEREQUEST 1000 + +namespace OHOS { +int IPCObjectStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + return TEST_RETVAL_ONREMOTEREQUEST; +} +} // namespace OHOS + +namespace OHOS { +namespace DataObs { +class MockDataObsMgrStub : public DataObsManagerStub { +public: + MOCK_METHOD4(RegisterObserver, int(const Uri &, sptr, int32_t userId, DataObsOption opt)); + MOCK_METHOD4(UnregisterObserver, int(const Uri &, sptr, int32_t userId, DataObsOption opt)); + MOCK_METHOD3(NotifyChange, int(const Uri &, int32_t userId, DataObsOption opt)); + + MOCK_METHOD4(RegisterObserverExt, Status(const Uri &, sptr, bool, DataObsOption opt)); + MOCK_METHOD3(UnregisterObserverExt, Status(const Uri &, sptr, DataObsOption opt)); + MOCK_METHOD2(UnregisterObserverExt, Status(sptr, DataObsOption opt)); + MOCK_METHOD2(NotifyChangeExt, Status(const ChangeInfo &, DataObsOption opt)); + MOCK_METHOD3(NotifyProcessObserver, Status(const std::string &, const sptr &, DataObsOption opt)); +}; + +class MockDataAbilityObserverStub : public DataObs::DataAbilityObserverStub { +public: + MockDataAbilityObserverStub() = default; + virtual ~MockDataAbilityObserverStub() = default; + MOCK_METHOD0(OnChange, void(void)); + MOCK_METHOD1(OnChangeExt, void(const ChangeInfo &)); +}; +} // namespace DataObs +} // namespace OHOS +#endif /* UNITTEST_OHOS_ABILITY_RUNTIME_MOCK_DATA_OBS_MGR_STUB_H */ diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn index d365536bdd22ba3d297fb48fb3d1f1ea95ef2948..d23ef0bfde6793483ddf7539aa320fb6f901dc36 100644 --- a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -103,13 +103,13 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/adapter/communicator:distributeddata_communicator", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service:distributeddatasvc", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:base", "ability_base:want", "ability_base:zuri", - "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", diff --git a/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn index a9c5923adf166905d05da9184af41bb7b9a6f296..9f3a25c474abd5b2cf524d830953c645cbbf1dec 100644 --- a/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn @@ -40,13 +40,13 @@ ohos_fuzztest("DumpHelperFuzzTest") { "${data_service_path}/adapter/account:distributeddata_account", "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtoken_setproc", "access_token:libtokenid_sdk", diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn index 9d8dc61bfa86f3220dff7b431c5c1d866269200c..c5494968c88b0b7c61c870193f8a4ccbd6f25946 100644 --- a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -93,13 +93,13 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service:distributeddatasvc", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn index 1fa88f886e60a2cacc991f413cc3a2c9d02453c7..2c1b93ae9b8b31b71a3e33a41ce9e6cc1eae59f1 100755 --- a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -82,13 +82,13 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service:distributeddatasvc", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn index 90e0d2f23426e8779d06577a872acbb8365c4773..d0ee10021e7aab166a84de30ccee5b0d5c850818 100644 --- a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn @@ -48,13 +48,13 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "${data_service_path}/adapter/account:distributeddata_account", "${data_service_path}/adapter/utils:distributeddata_utils", "${data_service_path}/framework:distributeddatasvcfwk", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn index 23fe264db5717c5da8cd8248cfbc63e2eb131c03..6874323c1a4225ae7986d531776792b9db6a0095 100644 --- a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -64,13 +64,13 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/service/cloud:distributeddata_cloud", "${data_service_path}/service/common:distributeddata_common", "${data_service_path}/service/rdb:distributeddata_rdb", + "${dataobsmgr_path}/interfaces:dataobs_manager", ] external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base",