From 8e8f0f4b6e9deba6671d3a4972bd28418506f62c Mon Sep 17 00:00:00 2001 From: zqz Date: Wed, 28 May 2025 16:47:43 +0800 Subject: [PATCH] Signed-off-by: zqz Change-Id: I1a3ac35dacdf2a8902c46b894cb27b40b9d3956a Signed-off-by: zqz Change-Id: Ic9fd142b34379ffbcb2e64ed0940b8c60697e634 Signed-off-by: zqz --- bundle.json | 10 +- datamgr_service.gni | 4 + .../distributeddataservice/service/BUILD.gn | 4 + .../service/data_share/BUILD.gn | 1 + .../data_share/data_share_service_impl.cpp | 4 +- .../service/datashareobs/BUILD.gn | 129 +++ .../service/datashareobs/datashareobsms.gni | 23 + .../include/datashareobs_mgr_inner.h | 59 ++ .../include/datashareobs_mgr_inner_common.h | 40 + .../include/datashareobs_mgr_inner_ext.h | 99 +++ .../include/datashareobs_mgr_inner_pref.h | 58 ++ .../include/datashareobs_mgr_interface.h | 135 +++ .../include/datashareobs_mgr_service.h | 97 +++ .../include/datashareobs_mgr_stub.h | 71 ++ .../src/datashareobs_mgr_inner.cpp | 209 +++++ .../src/datashareobs_mgr_inner_ext.cpp | 273 ++++++ .../src/datashareobs_mgr_inner_pref.cpp | 214 +++++ .../src/datashareobs_mgr_service.cpp | 500 +++++++++++ .../src/datashareobs_mgr_stub.cpp | 184 ++++ .../service/test/BUILD.gn | 13 +- .../service/test/dataobsmgr/cfi_blocklist.txt | 16 + .../dataobs_mgr_inner_ext_test/BUILD.gn | 60 ++ .../dataobs_mgr_inner_ext_test.cpp | 817 ++++++++++++++++++ .../dataobs_mgr_inner_ext_test/mock.h | 75 ++ .../dataobs_mgr_inner_pref_test/BUILD.gn | 60 ++ .../dataobs_mgr_inner_pref_test.cpp | 354 ++++++++ .../mock_data_ability_observer_stub.h | 59 ++ .../dataobs_mgr_inner_test/BUILD.gn | 60 ++ .../dataobs_mgr_inner_test.cpp | 363 ++++++++ .../mock_data_ability_observer_stub.h | 53 ++ .../dataobs_mgr_service_second_test/BUILD.gn | 63 ++ .../dataobs_mgr_service_second_test.cpp | 308 +++++++ .../dataobs_mgr_service_test/BUILD.gn | 65 ++ .../dataobs_mgr_service_test.cpp | 504 +++++++++++ .../mock_data_ability_observer_stub.h | 33 + .../dataobsmgr/dataobs_mgr_stub_test/BUILD.gn | 60 ++ .../dataobs_mgr_stub_test.cpp | 348 ++++++++ .../mock_data_obs_mgr_stub.h | 59 ++ .../datashareservicestub_fuzzer/BUILD.gn | 2 +- .../test/fuzztest/dumphelper_fuzzer/BUILD.gn | 1 - .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 1 - .../objectservicestub_fuzzer/BUILD.gn | 1 - .../fuzztest/rdbresultsetstub_fuzzer/BUILD.gn | 1 - .../fuzztest/rdbservicestub_fuzzer/BUILD.gn | 1 - 44 files changed, 5480 insertions(+), 11 deletions(-) create mode 100644 services/distributeddataservice/service/datashareobs/BUILD.gn create mode 100644 services/distributeddataservice/service/datashareobs/datashareobsms.gni create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_common.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_ext.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_pref.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_interface.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_service.h create mode 100644 services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_stub.h create mode 100644 services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner.cpp create mode 100644 services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_ext.cpp create mode 100644 services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_pref.cpp create mode 100644 services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_service.cpp create mode 100644 services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_stub.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/cfi_blocklist.txt create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/dataobs_mgr_inner_ext_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/mock.h create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/dataobs_mgr_inner_pref_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/mock_data_ability_observer_stub.h create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/dataobs_mgr_inner_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/mock_data_ability_observer_stub.h create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/dataobs_mgr_service_second_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/dataobs_mgr_service_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/mock_data_ability_observer_stub.h create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/BUILD.gn create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/dataobs_mgr_stub_test.cpp create mode 100644 services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/mock_data_obs_mgr_stub.h diff --git a/bundle.json b/bundle.json index eb78c8cf7..c0a8d2192 100644 --- a/bundle.json +++ b/bundle.json @@ -45,7 +45,8 @@ "datamgr_service_rdb", "datamgr_service_kvdb", "datamgr_service_object", - "datamgr_service_data_share" + "datamgr_service_data_share", + "datamgr_service_datashareobs" ], "adapted_system_type": [ "standard" @@ -69,6 +70,7 @@ "device_manager", "dfs_service", "dsoftbus", + "ffrt", "hicollie", "hilog", "hisysevent", @@ -77,6 +79,8 @@ "kv_store", "image_framework", "ipc", + "json", + "jsoncpp", "memmgr", "napi", "netmanager_base", @@ -89,6 +93,7 @@ "screenlock_mgr", "time_service", "udmf", + "window_manager", "app_file_service", "file_api", "openssl", @@ -110,7 +115,8 @@ "//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/datashareobs:build_module" ], "inner_kits": [ { diff --git a/datamgr_service.gni b/datamgr_service.gni index 7b327ccea..0df10f1b9 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" +datashareobs_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/datashareobs" + ipc_core_path = "//foundation/communication/ipc/interfaces/innerkits/ipc_core" device_manager_path = "//foundation/distributedhardware/device_manager" @@ -67,4 +69,6 @@ declare_args() { datamgr_service_object = true datamgr_service_data_share = true + + datamgr_service_datashareobs = true } diff --git a/services/distributeddataservice/service/BUILD.gn b/services/distributeddataservice/service/BUILD.gn index f75ebfcd3..247ba62b2 100644 --- a/services/distributeddataservice/service/BUILD.gn +++ b/services/distributeddataservice/service/BUILD.gn @@ -116,6 +116,10 @@ ohos_shared_library("distributeddatasvc") { deps += [ "${data_service_path}/service/data_share:data_share_service" ] } + if (datamgr_service_datashareobs) { + deps += [ "${data_service_path}/service/datashareobs:datashareobsms" ] + } + if (datamgr_service_object) { deps += [ "${data_service_path}/service/object:distributeddata_object" ] } diff --git a/services/distributeddataservice/service/data_share/BUILD.gn b/services/distributeddataservice/service/data_share/BUILD.gn index 68e54c60c..4d098f9bd 100644 --- a/services/distributeddataservice/service/data_share/BUILD.gn +++ b/services/distributeddataservice/service/data_share/BUILD.gn @@ -126,6 +126,7 @@ ohos_source_set("data_share_service") { "c_utils:utils", "data_share:datashare_common", "data_share:datashare_common_lite", + "data_share:datashareobs_manager", "device_manager:devicemanagersdk", "hicollie:libhicollie", "hilog:libhilog", 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 3c1a3ded3..73d753b41 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -27,9 +27,9 @@ #include "concurrent_task_client.h" #include "data_ability_observer_interface.h" #include "data_share_profile_config.h" -#include "dataobs_mgr_client.h" #include "datashare_errno.h" #include "datashare_radar_reporter.h" +#include "datashareobs_mgr_client.h" #include "device_manager_adapter.h" #include "datashare_template.h" #include "directory/directory_manager.h" @@ -145,7 +145,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 = DataObsMgrClient::GetInstance(); if (obsMgrClient == nullptr) { ZLOGE("obsMgrClient is nullptr"); report.SetError(RadarReporter::DATA_OBS_EMPTY_ERROR); diff --git a/services/distributeddataservice/service/datashareobs/BUILD.gn b/services/distributeddataservice/service/datashareobs/BUILD.gn new file mode 100644 index 000000000..089d56e9b --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/BUILD.gn @@ -0,0 +1,129 @@ +# 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/datashareobs/datashareobsms.gni") + +group("build_module") { + deps = [ ":datashareobsms" ] +} + +config("datashareobsms_config") { + include_dirs = [ "include/" ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } +} + +ohos_source_set("datashareobsms") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = datashareobsms_files + + public_configs = [ ":datashareobsms_config" ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service/common:distributeddata_common", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "ability_runtime:task_handler_wrap", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "data_share:datashareobs_manager", + "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("datashareobsms_static") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = datashareobsms_files + + configs = [ ":datashareobsms_config" ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "ability_runtime:task_handler_wrap", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "data_share:datashareobs_manager", + "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/datashareobs/datashareobsms.gni b/services/distributeddataservice/service/datashareobs/datashareobsms.gni new file mode 100644 index 000000000..a45df3d4d --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/datashareobsms.gni @@ -0,0 +1,23 @@ +# 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") + +datashareobsms_files = [ + "src/datashareobs_mgr_inner.cpp", + "src/datashareobs_mgr_inner_ext.cpp", + "src/datashareobs_mgr_inner_pref.cpp", + "src/datashareobs_mgr_stub.cpp", + "src/datashareobs_mgr_service.cpp", +] diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner.h new file mode 100644 index 000000000..33ef2851b --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_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 "datashareobs_mgr_inner_common.h" + +namespace OHOS { +namespace DataShare { +class DataObsMgrInner : public std::enable_shared_from_this { +public: + using ObsMapType = std::map>; + using ObsRecipientMapType = std::map, sptr>; + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_H diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_common.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_common.h new file mode 100644 index 000000000..daa6ac7bc --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_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 DataShare { +struct ObserverNode { + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_COMMON_H \ No newline at end of file diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_ext.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_ext.h new file mode 100644 index 000000000..b86d6550f --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_ext.h @@ -0,0 +1,99 @@ +/* + * 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 "datashareobs_mgr_errors.h" +#include "datashareobs_mgr_inner_common.h" +#include "iremote_object.h" +#include "refbase.h" + +namespace OHOS { +namespace DataShare { +class DataObsMgrInnerExt : public std::enable_shared_from_this { +public: + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + using ChangeInfo = AAFwk::ChangeInfo; + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INNER_H diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_pref.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_inner_pref.h new file mode 100644 index 000000000..984cb142e --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_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 "datashareobs_mgr_inner_common.h" + +namespace OHOS { +namespace DataShare { +class DataObsMgrInnerPref : public std::enable_shared_from_this { +public: + using ObsMapType = std::map>; + using ObsRecipientMapType = std::map, sptr>; + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_PREFERENCES_H diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_interface.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_interface.h new file mode 100644 index 000000000..f1659e14b --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_interface.h @@ -0,0 +1,135 @@ +/* + * 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_changeinfo.h" +#include "datashareobs_mgr_errors.h" +#include "idatashareobs_service.h" +#include "uri.h" + +namespace OHOS { +namespace DataShare { +using Uri = OHOS::Uri; + +/** + * @class IDataObsMgr + * IDataObsMgr interface is used to access dataobs manager services. + */ +class IDataObsMgr { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataObsService") + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + using ChangeInfo = AAFwk::ChangeInfo; + + /** + * 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 DATAOBS_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 DATAOBS_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 DATAOBS_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 DATAOBS_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 DATAOBS_SUCCESS on success, others on failure. + */ + virtual Status NotifyProcessObserver( + const std::string &key, const sptr &observer, DataObsOption opt = DataObsOption()) = 0; +}; +} // namespace DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_INTERFACE_H diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_service.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_service.h new file mode 100644 index 000000000..1d9926c18 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_service.h @@ -0,0 +1,97 @@ +/* + * 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 "datashareobs_mgr_inner.h" +#include "datashareobs_mgr_inner_ext.h" +#include "datashareobs_mgr_inner_pref.h" +#include "datashareobs_mgr_stub.h" +#include "idatashareobs_service.h" +#include "iremote_object.h" +#include "system_ability.h" +#include "task_handler_wrap.h" +#include "uri.h" + +namespace OHOS { +namespace DataShare { +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> &)>; + using IDataAbilityObserver = AAFwk::IDataAbilityObserver; + using ChangeInfo = AAFwk::ChangeInfo; + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_SERVICE_H diff --git a/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_stub.h b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_stub.h new file mode 100644 index 000000000..811128635 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/include/datashareobs_mgr_stub.h @@ -0,0 +1,71 @@ +/* + * 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 "datashareobs_mgr_errors.h" +#include "datashareobs_mgr_interface.h" +#include "feature/feature_system.h" + +namespace OHOS { +namespace DataShare { +/** + * @class DataObsManagerStub + * DataObsManagerStub. + */ +class DataObsManagerStub : public IDataObsMgr, public DistributedData::FeatureSystem::Feature { +public: + 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, + }; + 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 DataShare +} // namespace OHOS +#endif // DATAOBSSERVICE_DATAOBS_MGR_STUB_H diff --git a/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner.cpp b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner.cpp new file mode 100644 index 000000000..dcb273fde --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner.cpp @@ -0,0 +1,209 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsMgrInner" +#include "datashareobs_mgr_inner.h" + +#include "datashareobs_common_utils.h" +#include "data_ability_observer_stub.h" +#include "log_print.h" +#include "datashareobs_mgr_errors.h" + +namespace OHOS { +namespace DataShare { +using DataObsCallbackRecipient = AAFwk::DataObsCallbackRecipient; +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) { + ZLOGE("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()) { + ZLOGE("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()) { + ZLOGW("uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + + ZLOGD("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()) { + ZLOGW("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()) { + ZLOGD("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) { + ZLOGW("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(); + } + + ZLOGD("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()) { + ZLOGW("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)) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGD("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 DataShare +} // namespace OHOS diff --git a/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_ext.cpp b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_ext.cpp new file mode 100644 index 000000000..04cb91793 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_ext.cpp @@ -0,0 +1,273 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsMgrInnerExt" +#include "datashareobs_mgr_inner_ext.h" + +#include "datashareobs_common_utils.h" +#include "data_ability_observer_stub.h" +#include "log_print.h" +#include "datashareobs_mgr_errors.h" + +namespace OHOS { +namespace DataShare { +using DataObsCallbackRecipient = AAFwk::DataObsCallbackRecipient; +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))) { + ZLOGE("subscribers:%{public}s num maxed", CommonUtils::Anonymous(uri.ToString()).c_str()); + RemoveObsDeathRecipient(dataObserver->AsObject()); + return DATAOBS_SERVICE_OBS_LIMMIT; + } + return DATAOBS_SUCCESS; +} + +Status DataObsMgrInnerExt::HandleUnregisterObserver(Uri &uri, sptr dataObserver) +{ + if (dataObserver->AsObject() == nullptr) { + ZLOGE("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 DATAOBS_SUCCESS; +} + +Status DataObsMgrInnerExt::HandleUnregisterObserver(sptr dataObserver) +{ + if (dataObserver->AsObject() == nullptr) { + ZLOGE("null dataObserver"); + return DATA_OBSERVER_IS_NULL; + } + std::lock_guard lock(nodeMutex_); + if (root_ != nullptr) { + root_->RemoveObserver(dataObserver); + } + RemoveObsDeathRecipient(dataObserver->AsObject(), true); + return DATAOBS_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()) { + ZLOGD("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 DATAOBS_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) { + ZLOGE("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; + } + ZLOGD("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) { + ZLOGD("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) +{ + ZLOGD("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) { + ZLOGW("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) { + ZLOGW("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 DataShare +} // namespace OHOS diff --git a/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_pref.cpp b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_pref.cpp new file mode 100644 index 000000000..c8fe51495 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_inner_pref.cpp @@ -0,0 +1,214 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsMgrInnerPref" +#include "datashareobs_mgr_inner_pref.h" + +#include "datashareobs_common_utils.h" +#include "data_ability_observer_stub.h" +#include "log_print.h" +#include "datashareobs_mgr_errors.h" + +namespace OHOS { +namespace DataShare { +using DataObsCallbackRecipient = AAFwk::DataObsCallbackRecipient; +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) { + ZLOGE("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()) { + ZLOGE("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()) { + ZLOGW("uris no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return NO_OBS_FOR_URI; + } + + ZLOGD("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()) { + ZLOGW("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) { + ZLOGW("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()) { + ZLOGD("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) { + ZLOGW("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()); + } + + ZLOGD("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()) { + ZLOGW("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)) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGD("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 DataShare +} // namespace OHOS diff --git a/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_service.cpp b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_service.cpp new file mode 100644 index 000000000..cfd704078 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_service.cpp @@ -0,0 +1,500 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsMgrService" +#include "datashareobs_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 "datashareobs_common_utils.h" +#include "log_print.h" +#include "datashareobs_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 DataShare { +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(); + + ZLOGI("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(); +} + +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) { + ZLOGE("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)) { + ZLOGE("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) { + ZLOGE("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE( + "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) { + ZLOGE("null handler, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATAOBS_SERVICE_HANDLER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr || dataObsMgrInnerPref_ == nullptr) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE("null dataObserver, uri:%{public}s, isDescendants:%{public}d", + CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + ZLOGE("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) { + ZLOGE("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) { + ZLOGE("null dataObserver, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + ZLOGE("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) { + ZLOGE("null dataObserver"); + return DATA_OBSERVER_IS_NULL; + } + + if (dataObsMgrInnerExt_ == nullptr) { + ZLOGE("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 DATAOBS_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 DATAOBS_SUCCESS; +} + +Status DataObsMgrService::NotifyChangeExt(const ChangeInfo &changeInfo, DataObsOption opt) +{ + if (handler_ == nullptr) { + ZLOGE("null handler"); + return DATAOBS_SERVICE_HANDLER_IS_NULL; + } + + if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr) { + ZLOGE("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) { + ZLOGE("GetCallingUserId fail, type:%{public}d, userId:%{public}d", changeInfo.changeType_, userId); + return DATAOBS_INVALID_USERID; + } + + ChangeInfo changes; + Status result = DeepCopyChangeInfo(changeInfo, changes); + if (result != DATAOBS_SUCCESS) { + ZLOGE("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) { + ZLOGE("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 DATAOBS_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) { + ZLOGE("Failed to get ability manager."); + return nullptr; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (!remoteObject) { + ZLOGE("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) { + ZLOGE("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 { + ZLOGW("CallerToken is nullptr."); + } + + int32_t status = IN_PROCESS_CALL(abilityManager->StartAbility(want)); + if (status != DATAOBS_SUCCESS) { + ZLOGE("ShowProgress fail, status:%{public}d", status); + return DATAOBS_PROXY_INNER_ERR; + } + return DATAOBS_SUCCESS; +} +} // namespace DataShare +} // namespace OHOS diff --git a/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_stub.cpp b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_stub.cpp new file mode 100644 index 000000000..7c43f0b71 --- /dev/null +++ b/services/distributeddataservice/service/datashareobs/src/datashareobs_mgr_stub.cpp @@ -0,0 +1,184 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsManagerStub" +#include "datashareobs_mgr_stub.h" + +#include "datashareobs_common_utils.h" +#include "data_ability_observer_proxy.h" +#include "log_print.h" +#include "datashareobs_mgr_errors.h" +#include "datashareobs_mgr_interface.h" +#include "ipc_skeleton.h" +#include "string_ex.h" + +namespace OHOS { +namespace DataShare { +using Uri = OHOS::Uri; +using ChangeInfo = AAFwk::ChangeInfo; + +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)); + } + ZLOGI("code: %{public}d, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); + std::u16string descriptor = DataObsManagerStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + ZLOGE("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) { + ZLOGE("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()) { + ZLOGE("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()) { + ZLOGE("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()) { + ZLOGE("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()) { + ZLOGE("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 DATAOBS_SUCCESS; +} + +int32_t DataObsManagerStub::UnregisterObserverExtInner(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(data.ReadString()); + if (uri.ToString().empty()) { + ZLOGE("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 DATAOBS_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 DATAOBS_SUCCESS; +} + +int32_t DataObsManagerStub::NotifyChangeExtInner(MessageParcel &data, MessageParcel &reply) +{ + ChangeInfo changeInfo; + if (!ChangeInfo::Unmarshalling(changeInfo, data)) { + ZLOGE("Failed to unmarshall changeInfo."); + return IPC_STUB_INVALID_DATA_ERR; + } + DataObsOption opt = DataObsOption(data.ReadBool()); + reply.WriteInt32(NotifyChangeExt(changeInfo, opt)); + return DATAOBS_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 DATAOBS_SUCCESS; +} + +void DataObsManagerStub::SetServiceReady() +{ + isReady_.store(true); +} +} // namespace DataShare +} // namespace OHOS diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 142b49211..8ce154dbd 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -1013,7 +1013,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", @@ -1026,6 +1025,7 @@ ohos_unittest("DataShareServiceImplTest") { "data_share:datashare_common", "data_share:datashare_common_lite", "data_share:datashare_consumer", + "data_share:datashareobs_manager", "device_manager:devicemanagersdk", "googletest:gtest_main", "hicollie:libhicollie", @@ -2012,6 +2012,17 @@ group("unittest") { deps += [ ":DataShareServiceImplTest" ] } + if (datamgr_service_datashareobs) { + deps += [ + "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", + ] + } + deps += [ ":BootStrapMockTest", ":CryptoManagerTest", 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 000000000..7e6de6f7f --- /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/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 000000000..1a6ab62e4 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/BUILD.gn @@ -0,0 +1,60 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${datashareobs_path}:datashareobsms_static", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..0b1cb4878 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_ext_test/dataobs_mgr_inner_ext_test.cpp @@ -0,0 +1,817 @@ +/* + * 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 "datashareobs_mgr_errors.h" +#include "datashareobs_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 DataShare; +using ChangeInfo = AAFwk::ChangeInfo; +using IDataAbilityObserver = AAFwk::IDataAbilityObserver; +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), DATAOBS_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), DATAOBS_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), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri1, observer2, USER_TEST), DATAOBS_SUCCESS); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer2, USER_TEST), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri2, observer3, USER_TEST), DATAOBS_SUCCESS); + + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri3, observer3, USER_TEST), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri3, observer1, USER_TEST), DATAOBS_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), DATAOBS_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), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri123, observer1, USER_TEST, true), DATAOBS_SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, true), DATAOBS_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), DATAOBS_SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, true), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri14, observer2, USER_TEST, false), DATAOBS_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), DATAOBS_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), DATAOBS_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), DATAOBS_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), DATAOBS_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), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 0); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri1, observer), DATAOBS_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), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri13, observer, USER_TEST, false), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri134, observer, USER_TEST, false), DATAOBS_SUCCESS); + + sptr observer2(new (std::nothrow) MockDataAbilityObserverStub()); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri13, observer2, USER_TEST, true), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleRegisterObserver(uri135, observer2, USER_TEST, true), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 2); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.find(observer2)->second->ref, 3); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri135, observer), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri135, observer2), DATAOBS_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), DATAOBS_SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri135 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri13, observer), DATAOBS_SUCCESS); + EXPECT_EQ(dataObsMgrInnerExt->obsRecipientRefs.size(), 1); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri13 } }, USER_TEST); + + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri134, observer), DATAOBS_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), DATAOBS_SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer1), DATAOBS_SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer2), DATAOBS_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), DATAOBS_SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer1), DATAOBS_SUCCESS); + dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri1, uri2 } }, USER_TEST); + EXPECT_EQ(dataObsMgrInnerExt->HandleUnregisterObserver(uri2, observer2), DATAOBS_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), DATAOBS_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), DATAOBS_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), DATAOBS_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), DATAOBS_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), + DATAOBS_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), + DATAOBS_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), DATAOBS_SUCCESS); + }; + EXPECT_EQ(dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri } }, USER_TEST), DATAOBS_SUCCESS); + EXPECT_EQ(observer1->onChangeCall_, 1); + observer1->func = nullptr; + EXPECT_EQ(dataObsMgrInnerExt->HandleNotifyChange({ ChangeInfo::ChangeType::INSERT, { uri } }, USER_TEST), DATAOBS_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 000000000..6eef74b2d --- /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 "datashareobs_mgr_inner_ext.h" +#include "gmock/gmock.h" +#include "semaphore_ex.h" + +namespace OHOS { +namespace DataObsMgrInnerExtTest { +class MockDataAbilityObserverStub : public AAFwk::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 000000000..3a51eede8 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/BUILD.gn @@ -0,0 +1,60 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${datashareobs_path}:datashareobsms_static", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..40fa5d676 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/dataobs_mgr_inner_pref_test.cpp @@ -0,0 +1,354 @@ +/* + * 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 "datashareobs_mgr_inner_common.h" +#include "uri.h" +#include "data_ability_observer_proxy.h" +#include "datashareobs_mgr_errors.h" +#include "datashareobs_mgr_inner_pref.h" +#include "mock_data_ability_observer_stub.h" + +using namespace OHOS; +using namespace testing::ext; +using namespace testing; + +namespace OHOS { +namespace DataShare { +using Uri = OHOS::Uri; +using ObsListType = std::list; +using ObsRecipientMapType = DataObsMgrInnerPref::ObsRecipientMapType; +using DataAbilityObserverProxy = AAFwk::DataAbilityObserverProxy; +using IDataAbilityObserver = AAFwk::IDataAbilityObserver; +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 DataShare +} // 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 000000000..ce3761b2e --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_pref_test/mock_data_ability_observer_stub.h @@ -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. + */ + +#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 DataShare { +using ChangeInfo = AAFwk::ChangeInfo; +class MockDataAbilityObserverStub : public AAFwk::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 DataShare +} // 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 000000000..47b527927 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/BUILD.gn @@ -0,0 +1,60 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${datashareobs_path}:datashareobsms_static", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..a704d67ae --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/dataobs_mgr_inner_test.cpp @@ -0,0 +1,363 @@ +/* + * 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 "datashareobs_mgr_errors.h" +#include "datashareobs_mgr_inner.h" +#include "mock_data_ability_observer_stub.h" + +using namespace OHOS; +using namespace testing::ext; +using namespace testing; + +namespace OHOS { +namespace DataShare { +using Uri = OHOS::Uri; +using ObsListType = std::list; +using ObsRecipientMapType = DataObsMgrInner::ObsRecipientMapType; +using DataAbilityObserverProxy = AAFwk::DataAbilityObserverProxy; +using IDataAbilityObserver = AAFwk::IDataAbilityObserver; +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 DataShare +} // 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 000000000..cf09a4ba8 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_inner_test/mock_data_ability_observer_stub.h @@ -0,0 +1,53 @@ +/* + * 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 DataShare { +using ChangeInfo = AAFwk::ChangeInfo; +class MockDataAbilityObserverStub : public AAFwk::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 DataShare +} // 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 000000000..a5f04c62b --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/BUILD.gn @@ -0,0 +1,63 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${datashareobs_path}:datashareobsms_static", + "${data_service_path}/service/common:distributeddata_common", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "ability_runtime:task_handler_wrap", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..e58074160 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_second_test/dataobs_mgr_service_second_test.cpp @@ -0,0 +1,308 @@ +/* + * 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. + */ +#define LOG_TAG "DataObsMgrServiceSecondTest" +#include + +#include "log_print.h" +#include "datashareobs_mgr_service.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace OHOS { +namespace DataShare { +using namespace testing::ext; +using ChangeInfo = AAFwk::ChangeInfo; +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) +{ + ZLOGI("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)); + ZLOGI("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) +{ + ZLOGI("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; + ZLOGI("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) +{ + ZLOGI("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; + ZLOGI("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) +{ + ZLOGI("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0100 start"); + const int testVal = static_cast(DATAOBS_SUCCESS); + auto dataObsMgrServer = DelayedSingleton::GetInstance(); + ChangeInfo src; + ChangeInfo dst; + + EXPECT_EQ(testVal, dataObsMgrServer->DeepCopyChangeInfo(src, dst)); + ZLOGI("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) +{ + ZLOGI("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; + ZLOGI("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) +{ + ZLOGI("DataObsMgrServiceSecondTest_DeepCopyChangeInfo_0300 start"); + const int testVal = static_cast(DATAOBS_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; + ZLOGI("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) +{ + ZLOGI("DataObsMgrServiceSecondTest_NotifyChangeExt_0100 start"); + const int testVal = static_cast(DATAOBS_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 } })); + ZLOGI("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) +{ + ZLOGI("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; + ZLOGI("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) + +{ + ZLOGI("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; + ZLOGI("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) +{ + ZLOGI("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; + ZLOGI("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) +{ + ZLOGI("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)); + ZLOGI("DataObsMgrServiceSecondTest_NotifyProcessObserver_0100 end"); +} + +} // namespace DataShare +} // 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 000000000..2191f4a57 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/BUILD.gn @@ -0,0 +1,65 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${datashareobs_path}:datashareobsms_static", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "ability_runtime:task_handler_wrap", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..27aa95a36 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_service_test/dataobs_mgr_service_test.cpp @@ -0,0 +1,504 @@ +/* + * 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 "datashareobs_mgr_service.h" + +namespace OHOS { +namespace DataShare { +using namespace testing::ext; +using ChangeInfo = AAFwk::ChangeInfo; +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 DataShare +} // 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 000000000..8440ff7ee --- /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 DataShare { +class MockDataAbilityObserverStub : public AAFwk::DataAbilityObserverStub { +public: + MockDataAbilityObserverStub() = default; + virtual ~MockDataAbilityObserverStub() = default; + MOCK_METHOD0(OnChange, void(void)); +}; +} // namespace DataShare +} // 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 000000000..27f21c642 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/BUILD.gn @@ -0,0 +1,60 @@ +# 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 = [ "${datashareobs_path}:datashareobsms_config" ] + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${datashareobs_path}:datashareobsms_static", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "data_share:datashareobs_manager", + "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 000000000..72033a784 --- /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 "datashareobs_mgr_proxy.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "mock_data_obs_mgr_stub.h" + +namespace OHOS { +namespace DataShare { +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 = DataObsManagerStub::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 = DataObsManagerStub::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 = DataObsManagerStub::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 = DataObsManagerStub::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 = DATAOBS_SUCCESS; + uint32_t code = DataObsManagerStub::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 = DATAOBS_SUCCESS; + uint32_t code = DataObsManagerStub::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 = DATAOBS_SUCCESS; + uint32_t code = DataObsManagerStub::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 DataShare +} // 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 000000000..e687ab5a2 --- /dev/null +++ b/services/distributeddataservice/service/test/dataobsmgr/dataobs_mgr_stub_test/mock_data_obs_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 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 "datashareobs_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 DataShare { +using ChangeInfo = AAFwk::ChangeInfo; +using IDataAbilityObserver = AAFwk::IDataAbilityObserver; +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 AAFwk::DataAbilityObserverStub { +public: + MockDataAbilityObserverStub() = default; + virtual ~MockDataAbilityObserverStub() = default; + MOCK_METHOD0(OnChange, void(void)); + MOCK_METHOD1(OnChangeExt, void(const ChangeInfo &)); +}; +} // namespace DataShare +} // 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 227596c5f..04bafd8a6 100644 --- a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -111,7 +111,6 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "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", @@ -122,6 +121,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "data_share:datashare_consumer", + "data_share:datashareobs_manager", "device_manager:devicemanagersdk", "hicollie:libhicollie", "hilog:libhilog", diff --git a/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn index a9c5923ad..b61a71956 100644 --- a/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn @@ -46,7 +46,6 @@ ohos_fuzztest("DumpHelperFuzzTest") { "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 9d8dc61bf..990375b8d 100644 --- a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -99,7 +99,6 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "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 1fa88f886..ade34a10d 100755 --- a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -88,7 +88,6 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "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 90e0d2f23..017d968bb 100644 --- a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn @@ -54,7 +54,6 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "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 23fe264db..daff2c156 100644 --- a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -70,7 +70,6 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "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", -- Gitee