From 3a034c0ff5a8a623c7b1b1e1119de4e3f8a05ab5 Mon Sep 17 00:00:00 2001 From: illybyy Date: Mon, 28 Feb 2022 20:50:48 +0800 Subject: [PATCH 01/10] support multiuser Signed-off-by: illybyy --- .../innerkits/distributeddata/include/types.h | 13 + .../distributeddata/include/visibility.h | 12 +- .../adapter/account/BUILD.gn | 3 +- .../account/src/account_delegate_impl.cpp | 25 +- .../adapter/auth/BUILD.gn | 43 +++ .../adapter/auth/src/auth_delegate.cpp | 158 +++++++++++ .../adapter/autils/BUILD.gn | 4 +- .../adapter/autils/test/BUILD.gn | 2 +- .../adapter/communicator/BUILD.gn | 2 +- .../src/process_communicator_impl.cpp | 43 ++- .../adapter/communicator/test/BUILD.gn | 6 +- .../adapter/dfx/test/BUILD.gn | 4 +- .../include/account/account_delegate.h | 2 + .../adapter/include/account/visibility.h | 20 +- .../adapter/include/auth/auth_delegate.h | 103 +++++++ .../adapter/include/autils/visibility.h | 12 +- .../adapter/include/broadcaster/visibility.h | 12 +- .../communicator/process_communicator_impl.h | 16 +- .../include/communicator/route_head_handler.h | 32 +++ .../adapter/include/dfx/visibility.h | 12 +- .../adapter/include/log/visibility.h | 12 +- .../adapter/test/BUILD.gn | 2 +- services/distributeddataservice/app/BUILD.gn | 11 + .../app/src/executor_factory.cpp | 46 +++ .../app/src/executor_factory.h | 36 +++ .../app/src/kvstore_account_observer.cpp | 5 +- .../app/src/kvstore_app_manager.cpp | 30 +- .../app/src/kvstore_app_manager.h | 3 + .../app/src/kvstore_data_service.cpp | 251 ++++++++++++---- .../app/src/kvstore_data_service.h | 13 +- .../app/src/kvstore_meta_manager.cpp | 81 +++--- .../app/src/kvstore_meta_manager.h | 23 +- .../app/src/kvstore_user_manager.cpp | 14 + .../app/src/kvstore_user_manager.h | 3 + .../route_head_handler_impl.cpp | 268 ++++++++++++++++++ .../session_manager/route_head_handler_impl.h | 84 ++++++ .../src/session_manager/session_manager.cpp | 78 +++++ .../app/src/session_manager/session_manager.h | 54 ++++ .../src/session_manager/upgrade_manager.cpp | 148 ++++++++++ .../app/src/session_manager/upgrade_manager.h | 42 +++ .../app/src/single_kvstore_impl.cpp | 34 +++ .../app/src/single_kvstore_impl.h | 4 + .../app/src/uninstaller/BUILD.gn | 2 + .../session_manager/session_manager_test.cpp | 79 ++++++ .../distributeddataservice/framework/BUILD.gn | 4 + .../include/metadata/capability_meta_data.h | 37 +++ .../include/metadata/secret_key_meta_data.h | 7 +- .../include/metadata/store_meta_data.h | 35 ++- .../include/metadata/strategy_meta_data.h | 34 +++ .../include/metadata/user_meta_data.h | 50 ++++ .../include/serializable/serializable.h | 15 + .../metadata/capability_meta_data.cpp | 42 +++ .../metadata/secret_key_meta_data.cpp | 3 + .../framework/metadata/store_meta_data.cpp | 44 ++- .../framework/metadata/strategy_meta_data.cpp | 43 +++ .../framework/metadata/user_meta_data.cpp | 64 +++++ .../config/src/model/directory_config.cpp | 4 +- .../directory/include/directory_manager.h | 6 +- .../directory/include/kvstore_context.h | 9 +- .../service/kv/user_delegate.cpp | 176 ++++++++++++ .../service/kv/user_delegate.h | 62 ++++ 61 files changed, 2288 insertions(+), 194 deletions(-) create mode 100644 services/distributeddataservice/adapter/auth/BUILD.gn create mode 100644 services/distributeddataservice/adapter/auth/src/auth_delegate.cpp create mode 100644 services/distributeddataservice/adapter/include/auth/auth_delegate.h create mode 100644 services/distributeddataservice/adapter/include/communicator/route_head_handler.h create mode 100644 services/distributeddataservice/app/src/executor_factory.cpp create mode 100644 services/distributeddataservice/app/src/executor_factory.h create mode 100644 services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h create mode 100644 services/distributeddataservice/app/src/session_manager/session_manager.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/session_manager.h create mode 100644 services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/upgrade_manager.h create mode 100644 services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp create mode 100644 services/distributeddataservice/framework/include/metadata/capability_meta_data.h create mode 100644 services/distributeddataservice/framework/include/metadata/strategy_meta_data.h create mode 100644 services/distributeddataservice/framework/include/metadata/user_meta_data.h create mode 100644 services/distributeddataservice/framework/metadata/capability_meta_data.cpp create mode 100644 services/distributeddataservice/framework/metadata/strategy_meta_data.cpp create mode 100644 services/distributeddataservice/framework/metadata/user_meta_data.cpp create mode 100644 services/distributeddataservice/service/kv/user_delegate.cpp create mode 100644 services/distributeddataservice/service/kv/user_delegate.h diff --git a/interfaces/innerkits/distributeddata/include/types.h b/interfaces/innerkits/distributeddata/include/types.h index 4e2b0fe1f..5903077d5 100755 --- a/interfaces/innerkits/distributeddata/include/types.h +++ b/interfaces/innerkits/distributeddata/include/types.h @@ -82,6 +82,19 @@ struct KvStoreTuple { std::string userId; std::string appId; std::string storeId; + + KvStoreTuple() = default; + KvStoreTuple(std::string userId, std::string appId) : userId(std::move(userId)), appId(std::move(appId)) + { + } + KvStoreTuple(std::string userId, std::string appId, std::string storeId) + : userId(std::move(userId)), appId(std::move(appId)), storeId(std::move(storeId)) + { + } + bool operator<(const KvStoreTuple &that) const + { + return this->userId < that.userId || this->appId < that.appId || this->storeId < that.storeId; + } }; struct AppThreadInfo { diff --git a/interfaces/innerkits/distributeddata/include/visibility.h b/interfaces/innerkits/distributeddata/include/visibility.h index 502eda59b..1438f876c 100644 --- a/interfaces/innerkits/distributeddata/include/visibility.h +++ b/interfaces/innerkits/distributeddata/include/visibility.h @@ -13,10 +13,14 @@ * limitations under the License. */ +#ifndef OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H +#define OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H + +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif -#ifndef API_EXPORT -#define API_EXPORT __attribute__((visibility ("default"))) -#endif \ No newline at end of file +#endif // OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/BUILD.gn b/services/distributeddataservice/adapter/account/BUILD.gn index ec49f1aa7..ab44e1fe4 100755 --- a/services/distributeddataservice/adapter/account/BUILD.gn +++ b/services/distributeddataservice/adapter/account/BUILD.gn @@ -19,6 +19,7 @@ ohos_static_library("distributeddata_account_static") { ] include_dirs = [ + "../include/log", "../include/account", "../include/permission", "../include/utils", @@ -37,7 +38,6 @@ ohos_static_library("distributeddata_account_static") { deps = [ "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", "//utils/native/base:utils", ] @@ -50,5 +50,6 @@ ohos_static_library("distributeddata_account_static") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "os_account_standard:libaccountkits", + "os_account_standard:os_account_innerkits", ] } diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp index 4c0dab823..61c6ec96b 100755 --- a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp @@ -24,6 +24,7 @@ #include #include "constant.h" #include "ohos_account_kits.h" +#include "os_account_manager.h" #include "permission_validator.h" #include "utils/crypto.h" @@ -42,19 +43,17 @@ void EventSubscriber::OnReceiveEvent(const CommonEventData &event) std::string action = want.GetAction(); ZLOGI("Want Action is %s", action.c_str()); - if (action == CommonEventSupport::COMMON_EVENT_HWID_LOGIN) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_LOGIN; - } else if (action == CommonEventSupport::COMMON_EVENT_HWID_LOGOUT) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_LOGOUT; - } else if (action == CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_DELETE; - } else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) { + if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) { accountEventInfo.status = AccountStatus::DEVICE_ACCOUNT_DELETE; accountEventInfo.deviceAccountId = std::to_string(want.GetIntParam(CommonEventSupport::COMMON_EVENT_USER_REMOVED, -1)); if (accountEventInfo.deviceAccountId == "-1") { return; } + } else if (action == CommonEventSupport::COMMON_EVENT_USER_SWITCHED) { + accountEventInfo.status = AccountStatus::DEVICE_ACCOUNT_SWITCHED; + accountEventInfo.deviceAccountId = + std::to_string(want.GetIntParam(CommonEventSupport::COMMON_EVENT_USER_SWITCHED, -1)); } else { return; } @@ -93,10 +92,8 @@ void AccountDelegateImpl::SubscribeAccountEvent() { ZLOGI("Subscribe account event listener start."); MatchingSkills matchingSkills; - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_LOGIN); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_LOGOUT); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED); CommonEventSubscribeInfo info(matchingSkills); eventSubscriber_ = std::make_shared(info); eventSubscriber_->SetEventCallback([&](AccountEventInfo &account) { @@ -149,7 +146,13 @@ std::string AccountDelegateImpl::GetCurrentAccountId(const std::string &bundleNa std::string AccountDelegateImpl::GetDeviceAccountIdByUID(int32_t uid) const { - return std::to_string(AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid)); + int userId = 0; + auto ret = AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId); + if (ret != 0) { + ZLOGE("failed get os account local id from uid, ret:%{public}d", ret); + return {}; + } + return std::to_string(userId); } void AccountDelegateImpl::NotifyAccountChanged(const AccountEventInfo &accountEventInfo) diff --git a/services/distributeddataservice/adapter/auth/BUILD.gn b/services/distributeddataservice/adapter/auth/BUILD.gn new file mode 100644 index 000000000..155c3a2d1 --- /dev/null +++ b/services/distributeddataservice/adapter/auth/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/ohos.gni") + +ohos_static_library("distributeddata_auth_static") { + sources = [ "src/auth_delegate.cpp" ] + + include_dirs = [ + "../include", + "../include/autils", + "../include/communicator", + "../include/log", + "//third_party/json/single_include", + "//utils/native/base/include", + "//foundation/distributeddatamgr/distributeddatamgr/frameworks/common", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", + ] + + cflags_cc = [ "-fvisibility=hidden" ] + + configs = [ "//build/config/compiler:exceptions" ] + + deps = [ + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", + "//utils/native/base:utils", + ] + + external_deps = [ + "deviceauth_standard:deviceauth_sdk", + "hiviewdfx_hilog_native:libhilog", + ] +} diff --git a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp new file mode 100644 index 000000000..28fc05d92 --- /dev/null +++ b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AuthHandler" +#include "auth/auth_delegate.h" + +#include "checker/checker_manager.h" +#include "communication_provider.h" +#include "device_auth.h" +#include "device_auth_defines.h" +#include "log_print.h" + +namespace OHOS::DistributedData { +bool AuthHandler::CheckAccess( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) +{ + auto group = GetGroupInfo(localUserId, appId, peerDeviceId); + if (group.groupType < GroupType::ALL_GROUP) { + ZLOGE("failed to parse group %{public}s)", group.groupId.c_str()); + return false; + } + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->checkAccessToGroup == nullptr) { + ZLOGE("failed to get group manager"); + return false; + } + auto ret = groupManager->checkAccessToGroup(localUserId, appId.c_str(), group.groupId.c_str()); + ZLOGD("check access to group ret:%{public}d", ret); + return ret == HC_SUCCESS; +} + +int32_t AuthHandler::GetGroupType( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) +{ + auto group = GetGroupInfo(localUserId, appId, peerDeviceId); + if (group.groupType < GroupType::ALL_GROUP) { + ZLOGE("failed to parse group json(%{public}d)", group.groupType); + } + return group.groupType; +} + +AuthHandler::RelatedGroup AuthHandler::GetGroupInfo( + int32_t localUserId, const std::string &appId, const std::string &peerDeviceId) +{ + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr) { + ZLOGE("failed to get group manager"); + return {}; + } + char *groupInfo = nullptr; + uint32_t groupNum = 0; + ZLOGI("get related groups, user:%{public}d, app:%{public}s", localUserId, appId.c_str()); + auto ret = groupManager->getRelatedGroups(localUserId, appId.c_str(), peerDeviceId.c_str(), &groupInfo, &groupNum); + if (groupInfo == nullptr) { + ZLOGE("failed to get related groups, ret:%{public}d", ret); + return {}; + } + ZLOGI("get related group json :%{public}s", groupInfo); + std::vector groups; + RelatedGroup::Unmarshall(groupInfo, groups); + free(groupInfo); + + // same account has priority + std::sort(groups.begin(), groups.end(), + [](const RelatedGroup &group1, const RelatedGroup &group2) { return group1.groupType < group2.groupType; }); + if (!groups.empty()) { + ZLOGI("get group type:%{public}d", groups.front().groupType); + return groups.front(); + } + ZLOGD("there is no group to access to peer device:%{public}s", peerDeviceId.c_str()); + return {}; +} + +std::vector AuthHandler::GetTrustedDevicesByType( + AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId) +{ + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr + || groupManager->getTrustedDevices == nullptr) { + ZLOGE("failed to get group manager"); + return {}; + } + + char *groupsJson = nullptr; + uint32_t groupNum = 0; + ZLOGI("get joined groups, user:%{public}d, app:%{public}s, type:%{public}d", localUserId, appId.c_str(), type); + auto ret = groupManager->getJoinedGroups(localUserId, appId.c_str(), type, &groupsJson, &groupNum); + if (groupsJson == nullptr) { + ZLOGE("failed to get joined groups, ret:%{public}d", ret); + return {}; + } + ZLOGI("get joined group json :%{public}s", groupsJson); + std::vector groups; + RelatedGroup::Unmarshall(groupsJson, groups); + free(groupsJson); + + std::vector trustedDevices; + for (const auto &group : groups) { + if (group.groupType != type) { + continue; + } + char *devicesJson = nullptr; + uint32_t devNum = 0; + ret = groupManager->getTrustedDevices(localUserId, appId.c_str(), group.groupId.c_str(), &devicesJson, &devNum); + if (devicesJson == nullptr) { + ZLOGE("failed to get trusted devicesJson, ret:%{public}d", ret); + return {}; + } + ZLOGI("get trusted device json:%{public}s", devicesJson); + std::vector devices; + TrustDevice::Unmarshall(devicesJson, devices); + free(devicesJson); + for (const auto &item : devices) { + auto &provider = AppDistributedKv::CommunicationProvider::GetInstance(); + auto networkId = provider.ToNodeId(item.authId); + auto uuid = provider.GetUuidByNodeId(networkId); + trustedDevices.push_back(uuid); + } + } + + return trustedDevices; +} + +bool AuthHandlerStub::CheckAccess( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) +{ + auto checker = CheckerManager::GetInstance().GetChecker("SystemChecker"); + if (checker == nullptr) { + ZLOGE("get system checker failed"); + return false; + } + bool isSystemApp = checker->IsValid(UID_CAPACITY * localUserId, appId); + if (isSystemApp) { + ZLOGE("system app:%{public}s", appId.c_str()); + return peerUserId == SYSTEM_USER; + } + return peerUserId != SYSTEM_USER; +} + +AuthHandler *AuthDelegate::GetInstance() +{ + // change auth way in the future + static AuthHandlerStub instance; + return &instance; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/adapter/autils/BUILD.gn b/services/distributeddataservice/adapter/autils/BUILD.gn index b51d7a4a1..9b2fca5fb 100755 --- a/services/distributeddataservice/adapter/autils/BUILD.gn +++ b/services/distributeddataservice/adapter/autils/BUILD.gn @@ -32,9 +32,7 @@ ohos_static_library("distributeddata_autils_static") { cflags_cc = [ "-fvisibility=hidden" ] - deps = [ - "//utils/native/base:utils", - ] + deps = [ "//utils/native/base:utils" ] external_deps = [ "bytrace_standard:bytrace_core", diff --git a/services/distributeddataservice/adapter/autils/test/BUILD.gn b/services/distributeddataservice/adapter/autils/test/BUILD.gn index 0012bb19b..42d22679d 100755 --- a/services/distributeddataservice/adapter/autils/test/BUILD.gn +++ b/services/distributeddataservice/adapter/autils/test/BUILD.gn @@ -34,7 +34,7 @@ ohos_unittest("KvStoreThreadPoolTest") { deps = [ "../../autils:distributeddata_autils_static", "//third_party/googletest:gtest_main", - ] + ] } group("unittest") { diff --git a/services/distributeddataservice/adapter/communicator/BUILD.gn b/services/distributeddataservice/adapter/communicator/BUILD.gn index 6ff2901f8..1b4a50999 100755 --- a/services/distributeddataservice/adapter/communicator/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/BUILD.gn @@ -43,8 +43,8 @@ ohos_static_library("distributeddata_communicator_static") { cflags_cc = [ "-fvisibility=hidden" ] deps = [ - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/libs/distributeddb:distributeddb", "../dfx:distributeddata_dfx_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/libs/distributeddb:distributeddb", "//utils/native/base:utils", ] diff --git a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index 797a27f76..8631d985f 100755 --- a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -26,6 +26,11 @@ ProcessCommunicatorImpl::ProcessCommunicatorImpl() { } +ProcessCommunicatorImpl::ProcessCommunicatorImpl(RouteHeadHandlerCreator handlerCreator) + : routeHeadHandlerCreator_(std::move(handlerCreator)) +{ +} + ProcessCommunicatorImpl::~ProcessCommunicatorImpl() { ZLOGE("destructor."); @@ -187,5 +192,39 @@ void ProcessCommunicatorImpl::OnDeviceChanged(const DeviceInfo &info, const Devi devInfo.identifier = info.deviceId; onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); } -} // namespace AppDistributedKv -} // namespace OHOS + +std::shared_ptr ProcessCommunicatorImpl::GetExtendHeaderHandle(const ExtendInfo &info) +{ + if (routeHeadHandlerCreator_ != nullptr) { + return routeHeadHandlerCreator_(info); + } + return {}; +} + +DBStatus ProcessCommunicatorImpl::CheckAndGetDataHeadInfo( + const uint8_t *data, uint32_t dataLen, uint32_t &headLen, std::vector &users) +{ + ZLOGD("begin"); + if (routeHeadHandlerCreator_ == nullptr) { + ZLOGE("header handler creator not registered"); + return DBStatus::DB_ERROR; + } + auto handler = routeHeadHandlerCreator_({}); + if (handler == nullptr) { + ZLOGE("failed to get header handler"); + return DBStatus::DB_ERROR; + } + auto ret = handler->ParseHeadData(data, dataLen, headLen, users); + if (!ret) { + ZLOGD("illegal head format"); + return DBStatus::INVALID_FORMAT; + } + if (users.empty()) { + ZLOGW("no valid user"); + return DBStatus::NO_PERMISSION; + } + ZLOGD("ok, result:%{public}u, user:%{public}s", users.size(), users.front().c_str()); + return DBStatus::OK; +} +} // namespace AppDistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/adapter/communicator/test/BUILD.gn b/services/distributeddataservice/adapter/communicator/test/BUILD.gn index 919d22167..448e99229 100755 --- a/services/distributeddataservice/adapter/communicator/test/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/test/BUILD.gn @@ -29,9 +29,9 @@ ohos_unittest("CommunicationProviderTest") { "../src", ] external_deps = [ + "dsoftbus_standard:softbus_client", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", - "dsoftbus_standard:softbus_client", ] deps = [ "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", @@ -61,8 +61,6 @@ group("unittest") { deps = [] - deps += [ - ":CommunicationProviderTest", - ] + deps += [ ":CommunicationProviderTest" ] } ############################################################################### diff --git a/services/distributeddataservice/adapter/dfx/test/BUILD.gn b/services/distributeddataservice/adapter/dfx/test/BUILD.gn index 0f939e1ee..feb3251a5 100755 --- a/services/distributeddataservice/adapter/dfx/test/BUILD.gn +++ b/services/distributeddataservice/adapter/dfx/test/BUILD.gn @@ -46,9 +46,9 @@ ohos_unittest("DistributeddataDfxMSTTest") { ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ "../../autils:distributeddata_autils_static", - "//third_party/openssl:libcrypto_static", "../../dfx:distributeddata_dfx_static", "//third_party/googletest:gtest_main", + "//third_party/openssl:libcrypto_static", "//utils/native/base:utils", ] } @@ -102,8 +102,8 @@ ohos_unittest("DistributeddataDfxUTTest") { ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ "../../autils:distributeddata_autils_static", - "//third_party/openssl:libcrypto_static", "//third_party/googletest:gtest_main", + "//third_party/openssl:libcrypto_static", "//utils/native/base:utils", ] } diff --git a/services/distributeddataservice/adapter/include/account/account_delegate.h b/services/distributeddataservice/adapter/include/account/account_delegate.h index 617e56f56..e3e17b339 100755 --- a/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/services/distributeddataservice/adapter/include/account/account_delegate.h @@ -28,6 +28,7 @@ enum class AccountStatus { HARMONY_ACCOUNT_LOGOUT, // the openHarmony account is logged out HARMONY_ACCOUNT_DELETE, // the openHarmony account is deleted DEVICE_ACCOUNT_DELETE, // the device account is deleted + DEVICE_ACCOUNT_SWITCHED, // the device account is switched }; struct AccountEventInfo { @@ -53,6 +54,7 @@ public: KVSTORE_API virtual std::string GetDeviceAccountIdByUID(int32_t uid) const = 0; KVSTORE_API virtual void SubscribeAccountEvent() = 0; KVSTORE_API static AccountDelegate *GetInstance(); + private: using BaseInstance = AccountDelegate *(*)(); static BaseInstance getInstance_; diff --git a/services/distributeddataservice/adapter/include/account/visibility.h b/services/distributeddataservice/adapter/include/account/visibility.h index 2ffb65244..50f688ff9 100644 --- a/services/distributeddataservice/adapter/include/account/visibility.h +++ b/services/distributeddataservice/adapter/include/account/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,16 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef KVSTORE_API -#ifdef _WIN32 - #ifdef DB_DLL_EXPORT - #define KVSTORE_API __declspec(dllexport) - #else - #define KVSTORE_API - #endif -#else - #define KVSTORE_API __attribute__ ((visibility ("default"))) +#ifndef DISTRIBUTEDDATAMGR_ACCOUNT_VISIBILITY_H +#define DISTRIBUTEDDATAMGR_ACCOUNT_VISIBILITY_H +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) #endif +#ifndef KVSTORE_API +#define KVSTORE_API API_EXPORT #endif - +#endif // DISTRIBUTEDDATAMGR_ACCOUNT_VISIBILITY_H diff --git a/services/distributeddataservice/adapter/include/auth/auth_delegate.h b/services/distributeddataservice/adapter/include/auth/auth_delegate.h new file mode 100644 index 000000000..b4af68d9e --- /dev/null +++ b/services/distributeddataservice/adapter/include/auth/auth_delegate.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_AUTH_DELEGATE_H +#define DISTRIBUTEDDATAMGR_AUTH_DELEGATE_H + +#include + +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +enum AUTH_GROUP_TYPE { + ALL_GROUP = 0, + IDENTICAL_ACCOUNT_GROUP = 1, + PEER_TO_PEER_GROUP = 256, + COMPATIBLE_GROUP = 512, + ACROSS_ACCOUNT_AUTHORIZE_GROUP = 1282 +}; + +class AuthHandler { +public: + virtual bool CheckAccess( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId); + virtual int32_t GetGroupType( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId); + virtual std::vector GetTrustedDevicesByType( + AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId); + +private: + struct RelatedGroup final : public Serializable { + int32_t groupType = -1; + std::string groupId; + RelatedGroup() + { + } + ~RelatedGroup() + { + } + RelatedGroup(const RelatedGroup &) = default; + RelatedGroup &operator=(const RelatedGroup &) = default; + bool Marshal(json &node) const override + { + SetValue(node[GET_NAME(groupType)], groupType); + SetValue(node[GET_NAME(groupId)], groupId); + return true; + } + + bool Unmarshal(const json &node) override + { + GetValue(node, GET_NAME(groupType), groupType); + GetValue(node, GET_NAME(groupId), groupId); + return true; + } + }; + + struct TrustDevice final : public Serializable { + std::string authId; // udid + TrustDevice() = default; + TrustDevice(const TrustDevice &) = default; + TrustDevice &operator=(const TrustDevice &) = default; + bool Marshal(json &node) const override + { + SetValue(node[GET_NAME(authId)], authId); + return true; + } + + bool Unmarshal(const json &node) override + { + GetValue(node, GET_NAME(authId), authId); + return true; + } + }; + static RelatedGroup GetGroupInfo(int32_t localUserId, const std::string &appId, const std::string &peerDeviceId); +}; + +class AuthHandlerStub : public AuthHandler { +public: + // override for mock auth in current version, need remove in the future + bool CheckAccess( + int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) override; + +private: + static constexpr pid_t UID_CAPACITY = 10000; + static constexpr int SYSTEM_USER = 0; +}; + +class AuthDelegate { +public: + API_EXPORT static AuthHandler *GetInstance(); +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_AUTH_DELEGATE_H diff --git a/services/distributeddataservice/adapter/include/autils/visibility.h b/services/distributeddataservice/adapter/include/autils/visibility.h index 10bc02f92..92575c65d 100644 --- a/services/distributeddataservice/adapter/include/autils/visibility.h +++ b/services/distributeddataservice/adapter/include/autils/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#ifndef DISTRIBUTEDDATAMGR_AUTILS_VISIBILITY_H +#define DISTRIBUTEDDATAMGR_AUTILS_VISIBILITY_H +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif - +#endif // DISTRIBUTEDDATAMGR_AUTILS_VISIBILITY_H \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/broadcaster/visibility.h b/services/distributeddataservice/adapter/include/broadcaster/visibility.h index 10bc02f92..babdec0b1 100644 --- a/services/distributeddataservice/adapter/include/broadcaster/visibility.h +++ b/services/distributeddataservice/adapter/include/broadcaster/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#ifndef DISTRIBUTEDDATAMGR_BROADCAST_VISIBILITY_H +#define DISTRIBUTEDDATAMGR_BROADCAST_VISIBILITY_H +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif - +#endif // DISTRIBUTEDDATAMGR_BROADCAST_VISIBILITY_H diff --git a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index a4bee389d..c56b1c1af 100755 --- a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -17,8 +17,10 @@ #define PROCESS_COMMUNICATOR_IMPL_H #include -#include "iprocess_communicator.h" + #include "communication_provider.h" +#include "iprocess_communicator.h" +#include "route_head_handler.h" namespace OHOS { namespace AppDistributedKv { @@ -30,7 +32,11 @@ public: using OnDeviceChange = DistributedDB::OnDeviceChange; using OnDataReceive = DistributedDB::OnDataReceive; using DeviceInfos = DistributedDB::DeviceInfos; + using RouteHeadHandlerCreator = + std::function(const DistributedDB::ExtendInfo &info)>; + KVSTORE_API ProcessCommunicatorImpl(); + KVSTORE_API explicit ProcessCommunicatorImpl(RouteHeadHandlerCreator handlerCreator); KVSTORE_API ~ProcessCommunicatorImpl() override; KVSTORE_API DBStatus Start(const std::string &processLabel) override; @@ -45,6 +51,12 @@ public: KVSTORE_API DeviceInfos GetLocalDeviceInfos() override; KVSTORE_API std::vector GetRemoteOnlineDeviceInfosList() override; KVSTORE_API bool IsSameProcessLabelStartedOnPeerDevice(const DeviceInfos &peerDevInfo) override; + + API_EXPORT std::shared_ptr GetExtendHeaderHandle( + const DistributedDB::ExtendInfo &info) override; + API_EXPORT DBStatus CheckAndGetDataHeadInfo( + const uint8_t *data, uint32_t dataLen, uint32_t &headLen, std::vector &users) override; + private: void OnMessage(const DeviceInfo &info, const uint8_t *ptr, const int size, const PipeInfo &pipeInfo) const override; @@ -53,6 +65,8 @@ private: std::string thisProcessLabel_; OnDeviceChange onDeviceChangeHandler_; OnDataReceive onDataReceiveHandler_; + RouteHeadHandlerCreator routeHeadHandlerCreator_; // route header handler creator + mutable std::mutex onDeviceChangeMutex_; mutable std::mutex onDataReceiveMutex_; diff --git a/services/distributeddataservice/adapter/include/communicator/route_head_handler.h b/services/distributeddataservice/adapter/include/communicator/route_head_handler.h new file mode 100644 index 000000000..f31eea2db --- /dev/null +++ b/services/distributeddataservice/adapter/include/communicator/route_head_handler.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_EXTEND_HEAD_HANDLER_H +#define DISTRIBUTEDDATAMGR_EXTEND_HEAD_HANDLER_H +#include + +#include "iprocess_communicator.h" + +namespace OHOS::DistributedData { +class RouteHeadHandler : public DistributedDB::ExtendHeaderHandle { +public: + using ExtendInfo = DistributedDB::ExtendInfo; + using DBStatus = DistributedDB::DBStatus; + + virtual bool ParseHeadData( + const uint8_t *data, uint32_t totalLen, uint32_t &headSize, std::vector &users) = 0; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_EXTEND_HEAD_HANDLER_H diff --git a/services/distributeddataservice/adapter/include/dfx/visibility.h b/services/distributeddataservice/adapter/include/dfx/visibility.h index 10bc02f92..b58fa139a 100644 --- a/services/distributeddataservice/adapter/include/dfx/visibility.h +++ b/services/distributeddataservice/adapter/include/dfx/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#ifndef DISTRIBUTEDDATAMGR_DFX_VISIBILITY_H +#define DISTRIBUTEDDATAMGR_DFX_VISIBILITY_H +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif - +#endif // DISTRIBUTEDDATAMGR_DFX_VISIBILITY_H \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/log/visibility.h b/services/distributeddataservice/adapter/include/log/visibility.h index 10bc02f92..49ddb4b2b 100644 --- a/services/distributeddataservice/adapter/include/log/visibility.h +++ b/services/distributeddataservice/adapter/include/log/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#ifndef DISTRIBUTEDDATAMGR_LOG_VISIBILITY_H +#define DISTRIBUTEDDATAMGR_LOG_VISIBILITY_H +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif - +#endif // DISTRIBUTEDDATAMGR_LOG_VISIBILITY_H diff --git a/services/distributeddataservice/adapter/test/BUILD.gn b/services/distributeddataservice/adapter/test/BUILD.gn index 631b8bab2..b716360d7 100755 --- a/services/distributeddataservice/adapter/test/BUILD.gn +++ b/services/distributeddataservice/adapter/test/BUILD.gn @@ -21,7 +21,7 @@ group("unittest") { "../account/test:unittest", "../autils/test:unittest", "../communicator/test:unittest", - "../permission/test:unittest", "../dfx/test:unittest", + "../permission/test:unittest", ] } diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index b344d3f3d..03e1f656a 100755 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -42,10 +42,12 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/session_manager", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/src", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/rdb", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/kv", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", "//utils/system/safwk/native/include", @@ -78,6 +80,7 @@ ohos_shared_library("distributeddataservice") { "src/device_kvstore_impl.cpp", "src/device_kvstore_observer_impl.cpp", "src/device_kvstore_resultset_impl.cpp", + "src/executor_factory.cpp", "src/kvstore_account_observer.cpp", "src/kvstore_app_accessor.cpp", "src/kvstore_app_manager.cpp", @@ -92,6 +95,9 @@ ohos_shared_library("distributeddataservice") { "src/query_helper.cpp", "src/security/security.cpp", "src/security/sensitive.cpp", + "src/session_manager/route_head_handler_impl.cpp", + "src/session_manager/session_manager.cpp", + "src/session_manager/upgrade_manager.cpp", "src/single_kvstore_impl.cpp", ] @@ -102,6 +108,9 @@ ohos_shared_library("distributeddataservice") { "../service/rdb/rdb_syncer.cpp", ] + kv_sources = [ "../service/kv/user_delegate.cpp" ] + + sources += kv_sources sources += rdb_sources configs = [ ":module_private_config" ] @@ -110,6 +119,7 @@ ohos_shared_library("distributeddataservice") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -131,6 +141,7 @@ ohos_shared_library("distributeddataservice") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", diff --git a/services/distributeddataservice/app/src/executor_factory.cpp b/services/distributeddataservice/app/src/executor_factory.cpp new file mode 100644 index 000000000..b87fe785b --- /dev/null +++ b/services/distributeddataservice/app/src/executor_factory.cpp @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "executor_factory.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +ExecutorFactory &ExecutorFactory::GetInstance() +{ + static ExecutorFactory instance; + return instance; +} + +bool ExecutorFactory::Execute(KvStoreTask &&task) +{ + if (threadPool_ == nullptr) { + return false; + } + threadPool_->AddTask(std::move(task)); + return true; +} + +ExecutorFactory::ExecutorFactory() +{ + threadPool_ = KvStoreThreadPool::GetPool(POOL_SIZE, true); +} + +ExecutorFactory::~ExecutorFactory() +{ + if (threadPool_ != nullptr) { + threadPool_->Stop(); + threadPool_ = nullptr; + } +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/app/src/executor_factory.h b/services/distributeddataservice/app/src/executor_factory.h new file mode 100644 index 000000000..c91e2839a --- /dev/null +++ b/services/distributeddataservice/app/src/executor_factory.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H +#define DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H + +#include "kv_store_thread_pool.h" +namespace OHOS::DistributedData { +using OHOS::DistributedKv::KvStoreTask; +using OHOS::DistributedKv::KvStoreThreadPool; +class ExecutorFactory { +public: + static ExecutorFactory &GetInstance(); + bool Execute(KvStoreTask &&task); + +private: + ExecutorFactory(); + ~ExecutorFactory(); + + static constexpr int POOL_SIZE = 4; + + std::shared_ptr threadPool_; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H diff --git a/services/distributeddataservice/app/src/kvstore_account_observer.cpp b/services/distributeddataservice/app/src/kvstore_account_observer.cpp index 0e8991ad9..d2a1ac589 100755 --- a/services/distributeddataservice/app/src/kvstore_account_observer.cpp +++ b/services/distributeddataservice/app/src/kvstore_account_observer.cpp @@ -26,7 +26,10 @@ std::atomic g_kvStoreAccountEventStatus {0}; void KvStoreAccountObserver::OnAccountChanged(const AccountEventInfo &eventInfo) { ZLOGI("account event %d, begin.", eventInfo.status); - kvStoreDataService_.AccountEventChanged(eventInfo); + std::thread([this, eventInfo]() { + ZLOGI("account event processing in thread"); + kvStoreDataService_.AccountEventChanged(eventInfo); + }).detach(); ZLOGI("account event %d, end.", eventInfo.status); } } // namespace DistributedKv diff --git a/services/distributeddataservice/app/src/kvstore_app_manager.cpp b/services/distributeddataservice/app/src/kvstore_app_manager.cpp index 44f68e690..69c8cbbd3 100755 --- a/services/distributeddataservice/app/src/kvstore_app_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_app_manager.cpp @@ -16,17 +16,20 @@ #define LOG_TAG "KvStoreAppManager" #include "kvstore_app_manager.h" + #include #include #include #include + #include + #include "account_delegate.h" #include "broadcast_sender.h" #include "checker/checker_manager.h" #include "constant.h" -#include "directory_utils.h" #include "device_kvstore_impl.h" +#include "directory_utils.h" #include "ikvstore.h" #include "kv_store_delegate.h" #include "kvstore_app_accessor.h" @@ -34,6 +37,7 @@ #include "log_print.h" #include "permission_validator.h" #include "reporter.h" +#include "route_head_handler_impl.h" #include "types.h" namespace OHOS { @@ -228,6 +232,7 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & kvStore = nullptr; return Status::ERROR; } + kvStore->SetCompatibleIdentify(); auto result = singleStores_[type].emplace(storeId, kvStore); if (!result.second) { ZLOGE("emplace failed."); @@ -388,6 +393,7 @@ Status KvStoreAppManager::InitNbDbOption(const Options &options, const std::vect return Status::DB_ERROR; } + dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) dbOption.createIfNecessary = options.createIfMissing; dbOption.isEncryptedDb = options.encrypt; if (options.encrypt) { @@ -462,8 +468,8 @@ DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager(Pat } userId_ = AccountDelegate::GetInstance()->GetCurrentAccountId(bundleName_); - ZLOGD("accountId: %s bundleName: %s", KvStoreUtils::ToBeAnonymous(userId_).c_str(), bundleName_.c_str()); - delegateManagers_[type] = new (std::nothrow) DistributedDB::KvStoreDelegateManager(trueAppId_, userId_); + ZLOGD("accountId: %{public}s bundleName: %{public}s", deviceAccountId_.c_str(), bundleName_.c_str()); + delegateManagers_[type] = new (std::nothrow) DistributedDB::KvStoreDelegateManager(trueAppId_, deviceAccountId_); if (delegateManagers_[type] == nullptr) { ZLOGE("delegateManagers_[%d] is nullptr.", type); return nullptr; @@ -729,5 +735,23 @@ void KvStoreAppManager::Dump(int fd) const } } } + +bool KvStoreAppManager::IsStoreOpened(const std::string &storeId) const +{ + return (!singleStores_[PATH_DE].empty() && singleStores_->find(storeId) != singleStores_->end()) + || (!singleStores_[PATH_CE].empty() && singleStores_->find(storeId) != singleStores_->end()); +} + +void KvStoreAppManager::SetCompatibleIdentify(const std::string &deviceId) const +{ + for (const auto &storeType : singleStores_) { + for (const auto &item : storeType) { + if (item.second == nullptr) { + continue; + } + item.second->SetCompatibleIdentify(deviceId); + } + } +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_app_manager.h b/services/distributeddataservice/app/src/kvstore_app_manager.h index ca356d949..e1960c608 100755 --- a/services/distributeddataservice/app/src/kvstore_app_manager.h +++ b/services/distributeddataservice/app/src/kvstore_app_manager.h @@ -75,6 +75,9 @@ public: static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); size_t GetTotalKvStoreNum() const; + + bool IsStoreOpened(const std::string &storeId) const; + void SetCompatibleIdentify(const std::string &deviceId) const; private: DISALLOW_COPY_AND_MOVE(KvStoreAppManager); Status ConvertErrorStatus(DistributedDB::DBStatus dbStatus, bool createIfMissing); diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index 57ec67c97..f48511dc6 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -21,9 +21,11 @@ #include #include #include + #include #include +#include "auth/auth_delegate.h" #include "auto_launch_export.h" #include "bootstrap.h" #include "checker/checker_manager.h" @@ -32,6 +34,7 @@ #include "constant.h" #include "dds_trace.h" #include "device_kvstore_impl.h" +#include "executor_factory.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "kvstore_account_observer.h" @@ -45,8 +48,11 @@ #include "process_communicator_impl.h" #include "rdb_service_impl.h" #include "reporter.h" +#include "route_head_handler_impl.h" #include "system_ability_definition.h" #include "uninstaller/uninstaller.h" +#include "upgrade_manager.h" +#include "user_delegate.h" #include "utils/block_integer.h" #include "utils/crypto.h" @@ -93,9 +99,16 @@ void KvStoreDataService::Initialize() #ifndef UT_TEST KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default"); #endif - auto communicator = std::make_shared(); + auto communicator = std::make_shared(RouteHeadHandlerImpl::Create); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); - ZLOGI("set communicator ret:%d.", static_cast(ret)); + ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); + auto syncActivationCheck = [this](const std::string &userId, const std::string &appId, + const std::string &storeId) -> bool { + return CheckSyncActivation(userId, appId, storeId); + }; + ret = DistributedDB::KvStoreDelegateManager::SetSyncActivationCheckCallback(syncActivationCheck); + ZLOGI("set sync activation check callback ret:%{public}d.", static_cast(ret)); + InitSecurityAdapter(); KvStoreMetaManager::GetInstance().InitMetaParameter(); std::thread th = std::thread([]() { @@ -119,6 +132,7 @@ void KvStoreDataService::Initialize() accountEventObserver_ = std::make_shared(*this); AccountDelegate::GetInstance()->Subscribe(accountEventObserver_); + AppDistributedKv::CommunicationProvider::MakeCommunicationProvider()->StartWatchDeviceChange(this, {}); } Status KvStoreDataService::GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId, @@ -198,6 +212,7 @@ Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId param.storeId = storeId.storeId; const int32_t uid = IPCSkeleton::GetCallingUid(); param.trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + ZLOGI("%{public}s, %{public}s", param.trueAppId.c_str(), param.bundleName.c_str()); if (param.trueAppId.empty()) { ZLOGW("appId:%{public}s, uid:%{public}d, PERMISSION_DENIED", appId.appId.c_str(), uid); return Status::PERMISSION_DENIED; @@ -842,18 +857,12 @@ void KvStoreDataService::StartService() ZLOGE("backup create directory failed"); } // Initialize meta db delegate manager. - KvStoreMetaManager::GetInstance().InitMetaListener([this](const KvStoreMetaData &metaData) { - if (!metaData.isDirty) { - return; - } - - AppId appId; - appId.appId = metaData.bundleName; - StoreId storeId; - storeId.storeId = metaData.storeId; - CloseKvStore(appId, storeId); - DeleteKvStore(appId, storeId); - }); + KvStoreMetaManager::GetInstance().InitMetaListener(); + KvStoreMetaManager::GetInstance().SubscribeMeta( + KvStoreMetaRow::KEY_PREFIX, [this](const std::vector &key, const std::vector &value, + CHANGE_FLAG flag) { OnStoreMetaChanged(key, value, flag); }); + UpgradeManager::GetInstance().Init(); + UserDelegate::GetInstance().Init(); // subscribe account event listener to EventNotificationMgr AccountDelegate::GetInstance()->SubscribeAccountEvent(); @@ -883,48 +892,131 @@ void KvStoreDataService::StartService() KvStoreAppAccessor::GetInstance().EnableKvStoreAutoLaunch(); }); th.detach(); - ZLOGI("Publish ret: %d", static_cast(ret)); + ZLOGI("Publish ret: %{public}d", static_cast(ret)); +} + +void KvStoreDataService::OnStoreMetaChanged( + const std::vector &key, const std::vector &value, CHANGE_FLAG flag) +{ + if (flag != CHANGE_FLAG::UPDATE) { + return; + } + StoreMetaData metaData; + metaData.Unmarshall({ value.begin(), value.end() }); + ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(), + metaData.storeId.c_str(), metaData.isDirty); + if (metaData.deviceId != DeviceKvStoreImpl::GetLocalDeviceId() || metaData.deviceId.empty()) { + ZLOGD("ignore other device change or invalid meta device"); + return; + } + static constexpr const char *HARMONY_APP = "harmony"; + if (!metaData.isDirty || metaData.appType != HARMONY_APP) { + return; + } + ZLOGI("dirty kv store. storeId:%{public}s", metaData.storeId.c_str()); + CloseKvStore({ metaData.bundleName }, { metaData.storeId }); + DeleteKvStore({ metaData.bundleName }, { metaData.storeId }); } -bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &identifier, - DistributedDB::AutoLaunchParam ¶m) +bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( + const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { ZLOGI("start"); std::map entries; - if (KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) { - for (const auto &entry : entries) { - const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId( - entry.second.kvStoreMetaData.bundleName); - const std::string &curIdentifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, - entry.second.kvStoreMetaData.appId, entry.second.kvStoreMetaData.storeId); - if (identifier == curIdentifier) { - ZLOGI("identifier find"); - DistributedDB::AutoLaunchOption option; - option.createIfNecessary = false; - option.isEncryptedDb = entry.second.kvStoreMetaData.isEncrypt; - DistributedDB::CipherPassword password; - const std::vector &secretKey = entry.second.secretKeyMetaData.secretKey; - if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { - ZLOGE("Get secret key failed."); - } - option.passwd = password; - option.schema = entry.second.kvStoreMetaData.schema; - option.createDirByStoreIdOnly = true; - option.dataDir = entry.second.kvStoreMetaData.dataDir; - option.secOption = KvStoreAppManager::ConvertSecurity(entry.second.kvStoreMetaData.securityLevel); - option.isAutoSync = entry.second.kvStoreMetaData.isAutoSync; - param.userId = userId; - param.appId = entry.second.kvStoreMetaData.appId; - param.storeId = entry.second.kvStoreMetaData.storeId; - param.option = option; - return true; + if (!KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) { + ZLOGE("get full meta failed"); + return false; + } + std::string localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + for (const auto &entry : entries) { + auto &storeMeta = entry.second.kvStoreMetaData; + if ((!param.userId.empty() && (param.userId != storeMeta.deviceAccountId)) + || (localDeviceId != storeMeta.deviceId)) { + // judge local userid and local meta + continue; + } + const std::string &itemTripleIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier( + storeMeta.userId, storeMeta.appId, storeMeta.storeId, false); + const std::string &itemDualIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); + if (identifier == itemTripleIdentifier) { + // old triple tuple identifier, should SetEqualIdentifier + ResolveAutoLaunchCompatible(entry.second, identifier); + } + if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) { + ZLOGI("identifier find"); + DistributedDB::AutoLaunchOption option; + option.createIfNecessary = false; + option.isEncryptedDb = storeMeta.isEncrypt; + DistributedDB::CipherPassword password; + const std::vector &secretKey = entry.second.secretKeyMetaData.secretKey; + if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { + ZLOGE("Get secret key failed."); } + option.passwd = password; + option.schema = storeMeta.schema; + option.createDirByStoreIdOnly = true; + option.dataDir = storeMeta.dataDir; + option.secOption = KvStoreAppManager::ConvertSecurity(storeMeta.securityLevel); + option.isAutoSync = storeMeta.isAutoSync; + option.syncDualTupleMode = true; // dual tuple flag + param.appId = storeMeta.appId; + param.storeId = storeMeta.storeId; + param.option = option; + return true; } } ZLOGI("not find identifier"); return false; } +void KvStoreDataService::ResolveAutoLaunchCompatible(const MetaData &meta, const std::string &identifier) +{ + ZLOGI("AutoLaunch:peer device is old tuple, begin to open store"); + if (meta.kvStoreType >= KvStoreType::MULTI_VERSION) { + ZLOGW("no longer support multi or higher version store type"); + return; + } + + // open store and SetEqualIdentifier, then close store after 60s + auto &storeMeta = meta.kvStoreMetaData; + auto *delegateManager = new (std::nothrow) + DistributedDB::KvStoreDelegateManager(storeMeta.appId, storeMeta.deviceAccountId); + if (delegateManager == nullptr) { + ZLOGE("get store delegate manager failed"); + return; + } + delegateManager->SetKvStoreConfig({ storeMeta.dataDir }); + Options options = { + .encrypt = storeMeta.isEncrypt, + .autoSync = storeMeta.isAutoSync, + .securityLevel = storeMeta.securityLevel, + .kvStoreType = static_cast(storeMeta.kvStoreType), + .dataOwnership = true, + }; + DistributedDB::KvStoreNbDelegate::Option dbOptions; + KvStoreAppManager::InitNbDbOption(options, meta.secretKeyMetaData.secretKey, dbOptions); + DistributedDB::KvStoreNbDelegate *store = nullptr; + delegateManager->GetKvStore(storeMeta.storeId, dbOptions, + [&identifier, &store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate) { + ZLOGI("temporary open db for equal identifier, ret:%{public}d", status); + if (delegate != nullptr) { + KvStoreTuple tuple = { storeMeta.deviceAccountId, storeMeta.appId, storeMeta.storeId }; + UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP); + UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP); + store = delegate; + } + }); + KvStoreTask delayTask([delegateManager, store]() { + constexpr const int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds + std::this_thread::sleep_for(std::chrono::seconds(CLOSE_STORE_DELAY_TIME)); + ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied"); + delegateManager->CloseKvStore(store); + delete delegateManager; + }); + ExecutorFactory::GetInstance().Execute(std::move(delayTask)); +} + bool KvStoreDataService::CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const { @@ -960,7 +1052,7 @@ bool KvStoreDataService::CheckPermissions(const std::string &userId, const std:: return true; } bool ret = PermissionValidator::CheckSyncPermission(userId, appId, metaData.uid); - ZLOGD("checking sync permission ret:%d.", ret); + ZLOGD("checking sync permission ret:%{public}d.", ret); return ret; } @@ -1068,19 +1160,9 @@ Status KvStoreDataService::DeleteKvStoreOnly(const std::string &bundleName, pid_ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) { - ZLOGI("account event %d changed process, begin.", eventInfo.status); + ZLOGI("account event %{public}d changed process, begin.", eventInfo.status); std::lock_guard lg(accountMutex_); switch (eventInfo.status) { - case AccountStatus::HARMONY_ACCOUNT_LOGIN: - case AccountStatus::HARMONY_ACCOUNT_LOGOUT: { - g_kvStoreAccountEventStatus = 1; - // migrate all kvstore belong to this device account - for (auto &it : deviceAccountMap_) { - (it.second).MigrateAllKvStore(eventInfo.harmonyAccountId); - } - g_kvStoreAccountEventStatus = 0; - break; - } case AccountStatus::DEVICE_ACCOUNT_DELETE: { g_kvStoreAccountEventStatus = 1; // delete all kvstore belong to this device account @@ -1101,11 +1183,16 @@ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) g_kvStoreAccountEventStatus = 0; break; } + case AccountStatus::DEVICE_ACCOUNT_SWITCHED: { + auto ret = DistributedDB::KvStoreDelegateManager::NotifyUserChanged(); + ZLOGI("notify delegate manager result:%{public}d", ret); + break; + } default: { break; } } - ZLOGI("account event %d changed process, end.", eventInfo.status); + ZLOGI("account event %{public}d changed process, end.", eventInfo.status); } Status KvStoreDataService::GetLocalDevice(DeviceInfo &device) @@ -1122,7 +1209,7 @@ Status KvStoreDataService::GetDeviceList(std::vector &deviceInfoList DeviceInfo deviceInfo = {device.deviceId, device.deviceName, device.deviceType}; deviceInfoList.push_back(deviceInfo); } - ZLOGD("strategy is %d.", strategy); + ZLOGD("strategy is %{public}d.", strategy); return Status::SUCCESS; } @@ -1160,7 +1247,7 @@ Status KvStoreDataService::StartWatchDeviceChange(sptrAsObject().GetRefPtr(); auto listenerPair = std::make_pair(objectPtr, observer); deviceListeners_.insert(listenerPair); - ZLOGD("strategy is %d.", strategy); + ZLOGD("strategy is %{public}d.", strategy); return Status::SUCCESS; } @@ -1180,6 +1267,50 @@ Status KvStoreDataService::StopWatchDeviceChange(sptrsecond.IsStoreOpened(appId, storeId); +} + +void KvStoreDataService::OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const +{ + if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + ZLOGE("ignore device offline"); + return; + } + + for (const auto &item : deviceAccountMap_) { + item.second.SetCompatibleIdentify(info.deviceId); + } +} + +bool KvStoreDataService::CheckSyncActivation( + const std::string &userId, const std::string &appId, const std::string &storeId) +{ + ZLOGD("user:%{public}s, app:%{public}s, store:%{public}s", userId.c_str(), appId.c_str(), storeId.c_str()); + std::vector users = UserDelegate::GetInstance().GetLocalUserStatus(); + // active sync feature with single active user + for (const auto &user : users) { + if (userId == std::to_string(user.id)) { + return user.isActive; + if (!user.isActive) { + ZLOGD("the store is not in active user"); + return false; + } + // check store in other active user + continue; + } + if (IsStoreOpened(std::to_string(user.id), appId, storeId)) { + ZLOGD("the store already opened in user %{public}d", user.id); + return false; + } + } + ZLOGD("sync permitted"); + return true; +} + void KvStoreDataService::CreateRdbService() { rdbService_ = new(std::nothrow) DistributedRdb::RdbServiceImpl(); @@ -1239,4 +1370,4 @@ void DbMetaCallbackDelegateMgr::GetKvStoreKeys(std::vector &dbStats) } delegate_->CloseKvStore(kvStoreNbDelegatePtr); } -} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index f62715443..1b668168d 100755 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -39,7 +39,10 @@ class RdbServiceImpl; namespace OHOS::DistributedKv { class KvStoreAccountObserver; -class KvStoreDataService : public SystemAbility, public KvStoreDataServiceStub { +class KvStoreDataService + : public SystemAbility + , public KvStoreDataServiceStub + , public AppDistributedKv::AppDeviceStatusChangeListener { DECLARE_SYSTEM_ABILITY(KvStoreDataService); public: @@ -152,6 +155,8 @@ private: Status UpdateMetaData(const Options &options, const KvStoreParam &kvParas, const std::vector &metaKey, KvStoreUserManager &kvStoreUserManager); + void OnStoreMetaChanged(const std::vector &key, const std::vector &value, CHANGE_FLAG flag); + Status GetKvStoreFailDo(const Options &options, const KvStoreParam &kvParas, SecretKeyPara &secKeyParas, KvStoreUserManager &kvUserManager, sptr &kvStore); @@ -163,10 +168,14 @@ private: bool CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const; bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); + static void ResolveAutoLaunchCompatible(const MetaData &meta, const std::string &identifier); + bool CheckSyncActivation(const std::string &userId, const std::string &appId, const std::string &storeId); bool CheckOptions(const Options &options, const std::vector &metaKey) const; - + void OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; void CreateRdbService(); + bool IsStoreOpened(const std::string &userId, const std::string &appId, const std::string &storeId); static constexpr int TEN_SEC = 10; diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 5cba848d3..21143dc77 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -15,25 +15,33 @@ #define LOG_TAG "KvStoreMetaManager" #include "kvstore_meta_manager.h" -#include -#include + #include #include -#include #include -#include "hks_api.h" -#include "hks_param.h" + +#include +#include +#include + #include "account_delegate.h" #include "constant.h" -#include "kvstore_utils.h" #include "device_kvstore_impl.h" +#include "directory_utils.h" +#include "executor_factory.h" +#include "hks_api.h" +#include "hks_param.h" +#include "kvstore_app_manager.h" #include "kvstore_data_service.h" +#include "kvstore_utils.h" #include "log_print.h" +#include "metadata/capability_meta_data.h" +#include "metadata/user_meta_data.h" +#include "rdb_types.h" #include "reporter.h" -#include "directory_utils.h" -#include "kvstore_app_manager.h" +#include "serializable/serializable.h" +#include "user_delegate.h" #include "utils/crypto.h" -#include "rdb_types.h" namespace OHOS { namespace DistributedKv { @@ -76,17 +84,21 @@ KvStoreMetaManager &KvStoreMetaManager::GetInstance() return instance; } -void KvStoreMetaManager::InitMetaListener(std::function observer) +void KvStoreMetaManager::SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer) { - metaObserver_.notify_ = observer; + metaObserver_.handlerMap_[keyPrefix] = observer; +} +void KvStoreMetaManager::InitMetaListener() +{ InitMetaData(); - auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(&listener_, {"metaMgr"}); + auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(&listener_, { "metaMgr" }); if (status != AppDistributedKv::Status::SUCCESS) { ZLOGW("register failed."); + return; } ZLOGI("register meta device change success."); - GetInstance().SubscribeMetaKvStore(); + SubscribeMetaKvStore(); } void KvStoreMetaManager::InitMetaData() @@ -124,6 +136,7 @@ void KvStoreMetaManager::InitMetaData() if (CheckUpdateServiceMeta(metaKey, UPDATE, value) != Status::SUCCESS) { ZLOGW("CheckUpdateServiceMeta database failed."); } + ZLOGI("end."); } @@ -291,7 +304,7 @@ Status KvStoreMetaManager::CheckUpdateServiceMeta(const std::vector &me default: break; } - ZLOGI("Flag: %d status: %d", static_cast(flag), static_cast(dbStatus)); + ZLOGI("Flag: %{public}d status: %{public}d", static_cast(flag), static_cast(dbStatus)); SyncMeta(); return (dbStatus != DistributedDB::DBStatus::OK) ? Status::DB_ERROR : Status::SUCCESS; } @@ -833,10 +846,10 @@ void KvStoreMetaManager::SubscribeMetaKvStore() return; } - int mode = DistributedDB::OBSERVER_CHANGES_NATIVE; + int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN; auto dbStatus = metaDelegate->RegisterObserver(DistributedDB::Key(), mode, &metaObserver_); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGW("register meta observer failed :%d.", dbStatus); + ZLOGW("register meta observer failed :%{public}d.", dbStatus); } } @@ -959,27 +972,23 @@ KvStoreMetaManager::KvStoreMetaObserver::~KvStoreMetaObserver() void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data) { ZLOGD("on data change."); - if (notify_ != nullptr) { - auto &updated = data.GetEntriesUpdated(); - for (const auto &entry : updated) { - std::string key(entry.key.begin(), entry.key.end()); - if (key.find(KvStoreMetaRow::KEY_PREFIX) != 0) { - continue; - } + HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted()); + HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated()); + HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted()); + KvStoreMetaManager::GetInstance().SyncMeta(); +} - KvStoreMetaData metaData; - std::string json(entry.value.begin(), entry.value.end()); - metaData.Unmarshal(Serializable::ToJson(json)); - ZLOGD("meta data info appType:%s, storeId:%s isDirty:%d", - metaData.appType.c_str(), metaData.storeId.c_str(), metaData.isDirty); - if (!metaData.isDirty || metaData.appType != HARMONY_APP) { - continue; +void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges( + CHANGE_FLAG flag, const std::list &entries) +{ + for (const auto &entry : entries) { + std::string key(entry.key.begin(), entry.key.end()); + for (const auto &item : handlerMap_) { + if (key.find(item.first) == 0) { + item.second(entry.key, entry.value, flag); } - ZLOGI("dirty kv store. storeId:%s", metaData.storeId.c_str()); - notify_(metaData); } } - KvStoreMetaManager::GetInstance().SyncMeta(); } void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged( @@ -1046,7 +1055,7 @@ Status KvStoreMetaManager::GetKvStoreMeta(const std::vector &metaKey, K } DistributedDB::Value dbValue; DistributedDB::DBStatus dbStatus = metaDelegate->Get(metaKey, dbValue); - ZLOGI("status: %d", static_cast(dbStatus)); + ZLOGI("status: %{public}d", static_cast(dbStatus)); if (dbStatus == DistributedDB::DBStatus::NOT_FOUND) { ZLOGI("key not found."); return Status::KEY_NOT_FOUND; @@ -1250,5 +1259,5 @@ bool KvStoreMetaManager::GetKvStoreMetaDataByAppId(const std::string &appId, KvS { return GetKvStoreMetaByType(KvStoreMetaData::APP_ID, appId, metaData); } -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index c67d6b70c..20925958c 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -19,12 +19,13 @@ #include #include "app_device_status_change_listener.h" -#include "types.h" -#include "system_ability.h" #include "kv_store_delegate.h" #include "kv_store_delegate_manager.h" +#include "kv_store_task.h" #include "kvstore_impl.h" #include "single_kvstore_impl.h" +#include "system_ability.h" +#include "types.h" namespace OHOS { namespace DistributedKv { @@ -37,6 +38,12 @@ enum FLAG { CHECK_EXIST_LOCAL, }; +enum class CHANGE_FLAG { + INSERT, + UPDATE, + DELETE +}; + struct Serializable { using json = nlohmann::json; template @@ -146,12 +153,14 @@ private: class KvStoreMetaManager { public: static constexpr uint32_t META_STORE_VERSION = 0x03000001; + static const inline std::string META_DB_APP_ID = "distributeddata"; enum DatabaseType { KVDB, RDB, }; using NbDelegate = std::unique_ptr>; + using ChangeObserver = std::function &, const std::vector &, CHANGE_FLAG)>; class MetaDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceStatusChangeListener { void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, @@ -165,9 +174,8 @@ public: static KvStoreMetaManager &GetInstance(); void InitMetaParameter(); - - void InitMetaListener(std::function observer); - + void InitMetaListener(); + void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer); const NbDelegate &GetMetaKvStore(); Status CheckUpdateServiceMeta(const std::vector &metaKey, FLAG flag, const std::vector &val = {}); @@ -256,10 +264,11 @@ private: // Database change callback void OnChange(const DistributedDB::KvStoreChangedData &data) override; - std::function notify_ = nullptr; + std::map handlerMap_; + private: + void HandleChanges(CHANGE_FLAG flag, const std::list &list); }; - static const inline std::string META_DB_APP_ID = "distributeddata"; static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key"; static constexpr const char *STRATEGY_META_PREFIX = "StrategyMetaData"; static constexpr const char *CAPABILITY_ENABLED = "capabilityEnabled"; diff --git a/services/distributeddataservice/app/src/kvstore_user_manager.cpp b/services/distributeddataservice/app/src/kvstore_user_manager.cpp index 98ef5cad6..da27844f2 100755 --- a/services/distributeddataservice/app/src/kvstore_user_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_user_manager.cpp @@ -143,5 +143,19 @@ void KvStoreUserManager::Dump(int fd) const pair.second.Dump(fd); } } + +bool KvStoreUserManager::IsStoreOpened(const std::string &appId, const std::string &storeId) +{ +// std::lock_guard lg(appMutex_); + auto it = appMap_.find(appId); + return it != appMap_.end() && it->second.IsStoreOpened(storeId); +} + +void KvStoreUserManager::SetCompatibleIdentify(const std::string &deviceId) const +{ + for (const auto &item : appMap_) { + item.second.SetCompatibleIdentify(deviceId); + } +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_user_manager.h b/services/distributeddataservice/app/src/kvstore_user_manager.h index d445ae7e6..184c9b981 100755 --- a/services/distributeddataservice/app/src/kvstore_user_manager.h +++ b/services/distributeddataservice/app/src/kvstore_user_manager.h @@ -66,6 +66,9 @@ public: void Dump(int fd) const; + bool IsStoreOpened(const std::string &appId, const std::string &storeId); + void SetCompatibleIdentify(const std::string &deviceId) const; + private: std::mutex appMutex_; std::map appMap_; diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp new file mode 100644 index 000000000..b8053c590 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "route_head_handler_impl.h" + +#define LOG_TAG "RouteHeadHandler" + +#include "auth/auth_delegate.h" +#include "device_kvstore_impl.h" +#include "kvstore_meta_manager.h" +#include "log_print.h" +#include "securec.h" +#include "upgrade_manager.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) +{ + auto handler = std::make_shared(info); + if (handler == nullptr) { + ZLOGE("new instance failed"); + return nullptr; + } + handler->Init(); + return handler; +} + +RouteHeadHandlerImpl::RouteHeadHandlerImpl(const ExtendInfo &info) + : userId_(info.userId), appId_(info.appId), storeId_(info.storeId), deviceId_(info.dstTarget) +{ + ZLOGI("init route handler, app:%{public}s, user:%{public}s, peer:%{public}s", appId_.c_str(), userId_.c_str(), + deviceId_.c_str()); +} + +void RouteHeadHandlerImpl::Init() +{ + ZLOGD("begin"); + if (deviceId_.empty()) { + return; + } + SessionPoint localPoint { DeviceKvStoreImpl::GetLocalDeviceId(), std::stoi(userId_), appId_ }; + session_ = SessionManager::GetInstance().GetSession(localPoint, deviceId_); + ZLOGD("valid session:%{public}s", Serializable::Marshall(session_).c_str()); +} + +DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize) +{ + ZLOGD("begin"); + headSize = 0; + if (appId_ == DistributedKv::KvStoreMetaManager::META_DB_APP_ID) { + ZLOGI("meta data permitted"); + return DistributedDB::OK; + } + bool flag = false; + auto peerCap = UpgradeManager::GetInstance().GetCapability(session_.targetDeviceId, flag); + if (!flag) { + ZLOGI("get peer cap failed"); + return DistributedDB::DB_ERROR; + } + if (peerCap.version == CapMetaData::INVALID_VERSION) { + // older versions ignore pack extend head + ZLOGI("ignore older version device"); + return DistributedDB::OK; + } + if (!session_.IsValid()) { + ZLOGI("no valid session to peer device"); + return DistributedDB::DB_ERROR; + } + size_t expectSize = sizeof(RouteHead) + sizeof(SessionDevicePair) + sizeof(SessionUserPair) + + session_.targetUserIds.size() * sizeof(int) + sizeof(SessionAppId) + session_.appId.size(); + + // align message uint width + headSize = GET_ALIGNED_SIZE(expectSize, ALIGN_WIDTH); + ZLOGI("packed size:%{public}u", headSize); + headSize_ = headSize; + return DistributedDB::OK; +} + +DistributedDB::DBStatus RouteHeadHandlerImpl::FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) +{ + ZLOGD("begin"); + if (headSize != headSize_) { + ZLOGI("size not match"); + return DistributedDB::DB_ERROR; + } + if (headSize_ == 0) { + ZLOGI("ignore older version device"); + return DistributedDB::OK; + } + auto packRet = PackData(data, headSize); + ZLOGD("pack result:%{public}d", packRet); + return packRet ? DistributedDB::OK : DistributedDB::DB_ERROR; +} + +bool RouteHeadHandlerImpl::PackData(uint8_t *data, uint32_t totalLen) +{ + if (headSize_ > totalLen) { + ZLOGE("the buffer size is not enough"); + return false; + } + + auto isOk = PackDataHead(data, headSize_); + if (isOk) { + return PackDataBody(data + sizeof(RouteHead), headSize_ - sizeof(RouteHead)); + } + return false; +} + +bool RouteHeadHandlerImpl::PackDataHead(uint8_t *data, uint32_t totalLen) +{ + uint8_t *ptr = data; + if (headSize_ < sizeof(RouteHead)) { + return false; + } + RouteHead *head = reinterpret_cast(ptr); + head->magic = RouteHead::MAGIC_NUMBER; + head->version = RouteHead::VERSION; + head->checkSum = 0; + head->dataLen = static_cast(totalLen - sizeof(RouteHead)); + return true; +} + +bool RouteHeadHandlerImpl::PackDataBody(uint8_t *data, uint32_t totalLen) +{ + uint8_t *ptr = data; + SessionDevicePair *devicePair = reinterpret_cast(ptr); + auto ret = strcpy_s(devicePair->sourceDeviceId, DEVICE_ID_SIZE_MAX, session_.sourceDeviceId.c_str()); + if (ret != 0) { + ZLOGE("strcpy for source device id failed"); + return false; + } + ret = strcpy_s(devicePair->targetDeviceId, DEVICE_ID_SIZE_MAX, session_.targetDeviceId.c_str()); + if (ret != 0) { + ZLOGE("strcpy for target device id failed"); + return false; + } + ptr += sizeof(SessionDevicePair); + + SessionUserPair *userPair = reinterpret_cast(ptr); + userPair->sourceUserId = session_.sourceUserId; + userPair->targetUserCount = session_.targetUserIds.size(); + for (size_t i = 0; i < session_.targetUserIds.size(); ++i) { + *(userPair->targetUserIds + i) = session_.targetUserIds[i]; + } + ptr += (sizeof(SessionUserPair) + session_.targetUserIds.size() * sizeof(int)); + + SessionAppId *appPair = reinterpret_cast(ptr); + appPair->len = data + totalLen - ptr; // left size + ret = strcpy_s(appPair->appId, data + totalLen - ptr, session_.appId.c_str()); + if (ret != 0) { + ZLOGE("strcpy for app id failed"); + return false; + } + return true; +} + +bool RouteHeadHandlerImpl::ParseHeadData( + const uint8_t *data, uint32_t len, uint32_t &headSize, std::vector &users) +{ + auto ret = UnPackData(data, len, headSize); + if (!ret) { + headSize = 0; + ZLOGE("unpack data head failed"); + return false; + } + ZLOGI("unpacked size:%{public}u", headSize); + // flip the local and peer ends + SessionPoint local { .deviceId = session_.targetDeviceId, .appId = session_.appId }; + SessionPoint peer { .deviceId = session_.sourceDeviceId, .userId = session_.sourceUserId, .appId = session_.appId }; + ZLOGI("validSession:%{public}s", Serializable::Marshall(session_).c_str()); + for (const auto &item : session_.targetUserIds) { + local.userId = item; + if (SessionManager::GetInstance().CheckSession(local, peer)) { + users.emplace_back(std::to_string(item)); + } + } + return true; +} + +bool RouteHeadHandlerImpl::UnPackData(const uint8_t *data, uint32_t totalLen, uint32_t &unpackedSize) +{ + if (data == nullptr || totalLen < sizeof(RouteHead)) { + ZLOGE("invalid input data"); + return false; + } + unpackedSize = 0; + const RouteHead *head = UnPackHeadHead(data, totalLen); + if (head != nullptr && head->version == RouteHead::VERSION) { + auto isOk = UnPackHeadBody(data + sizeof(RouteHead), totalLen - sizeof(RouteHead)); + if (isOk) { + unpackedSize = sizeof(RouteHead) + head->dataLen; + } + return isOk; + } + return false; +} + +const RouteHead *RouteHeadHandlerImpl::UnPackHeadHead(const uint8_t *data, uint32_t totalLen) +{ + const uint8_t *ptr = data; + const RouteHead *head = reinterpret_cast(ptr); + if (head->magic != RouteHead::MAGIC_NUMBER) { + ZLOGW("not route head data"); + return nullptr; + } + if (head->dataLen + sizeof(RouteHead) > totalLen) { + ZLOGE("invalid route head len"); + return nullptr; + } + return head; +} + +bool RouteHeadHandlerImpl::UnPackHeadBody(const uint8_t *data, uint32_t totalLen) +{ + const uint8_t *ptr = data; + uint32_t leftSize = totalLen; + + if (leftSize < sizeof(SessionDevicePair)) { + ZLOGE("failed to parse device pair"); + return false; + } + const SessionDevicePair *devicePair = reinterpret_cast(ptr); + session_.sourceDeviceId.append(devicePair->sourceDeviceId, DEVICE_ID_SIZE_MAX); + session_.targetDeviceId.append(devicePair->targetDeviceId, DEVICE_ID_SIZE_MAX); + ptr += sizeof(SessionDevicePair); + leftSize -= sizeof(SessionDevicePair); + + if (leftSize < sizeof(SessionUserPair)) { + ZLOGE("failed to parse user pair"); + return false; + } + const SessionUserPair *userPair = reinterpret_cast(ptr); + session_.sourceUserId = userPair->sourceUserId; + + if (leftSize < sizeof(SessionUserPair) + userPair->targetUserCount * sizeof(int)) { + ZLOGE("failed to parse user pair, target user"); + return false; + } + for (int i = 0; i < userPair->targetUserCount; ++i) { + session_.targetUserIds.push_back(*(userPair->targetUserIds + i)); + } + ptr += sizeof(SessionUserPair) + userPair->targetUserCount * sizeof(int); + + if (leftSize < sizeof(SessionAppId)) { + ZLOGE("failed to parse app id len"); + return false; + } + const SessionAppId *appId = reinterpret_cast(ptr); + + if (leftSize < sizeof(SessionAppId) + appId->len) { + ZLOGE("failed to parse app id"); + return false; + } + session_.appId.append(appId->appId, appId->len); + return true; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h new file mode 100644 index 000000000..bfd39080e --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_ROUTE_HEAD_HANDLER_H +#define DISTRIBUTEDDATAMGR_ROUTE_HEAD_HANDLER_H +#include "process_communicator_impl.h" +#include "route_head_handler.h" +#include "serializable/serializable.h" +#include "session_manager.h" + +namespace OHOS::DistributedData { +constexpr int ALIGN_WIDTH = 8; +template constexpr T GET_ALIGNED_SIZE(T x, int alignWidth) +{ + return (x + (alignWidth - 1)) & ~(alignWidth - 1); +} + +#pragma pack(1) +// format: head + device pair + user pair + appid +struct RouteHead { + static constexpr uint16_t MAGIC_NUMBER = 0x8421; + static constexpr uint16_t VERSION = 0x1; + uint16_t magic = MAGIC_NUMBER; + uint16_t version = VERSION; + uint64_t checkSum; + uint32_t dataLen; +}; + +constexpr const int32_t DEVICE_ID_SIZE_MAX = 65; +struct SessionDevicePair { + char sourceDeviceId[DEVICE_ID_SIZE_MAX]; + char targetDeviceId[DEVICE_ID_SIZE_MAX]; +}; + +struct SessionUserPair { + int sourceUserId; + uint8_t targetUserCount; + int targetUserIds[0]; +}; + +struct SessionAppId { + uint32_t len; + char appId[0]; +}; +#pragma pack() + +class RouteHeadHandlerImpl : public DistributedData::RouteHeadHandler { +public: + static std::shared_ptr Create(const ExtendInfo &info); + explicit RouteHeadHandlerImpl(const ExtendInfo &info); + DBStatus GetHeadDataSize(uint32_t &headSize) override; + DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) override; + bool ParseHeadData(const uint8_t *data, uint32_t len, uint32_t &headSize, std::vector &users) override; + +private: + void Init(); + bool PackData(uint8_t *data, uint32_t totalLen); + bool PackDataHead(uint8_t *data, uint32_t totalLen); + bool PackDataBody(uint8_t *data, uint32_t totalLen); + bool UnPackData(const uint8_t *data, uint32_t totalLen, uint32_t &unpackedSize); + const RouteHead *UnPackHeadHead(const uint8_t *data, uint32_t totalLen); + bool UnPackHeadBody(const uint8_t *data, uint32_t totalLen); + + std::string userId_; + std::string appId_; + std::string storeId_; + std::string deviceId_; + Session session_; + uint32_t headSize_; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_ROUTE_HEAD_HANDLER_H diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/services/distributeddataservice/app/src/session_manager/session_manager.cpp new file mode 100644 index 000000000..dc1678211 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_manager.h" + +#define LOG_TAG "SessionManager" + +#include "auth/auth_delegate.h" +#include "checker/checker_manager.h" +#include "log/log_print.h" +#include "user_delegate.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +SessionManager &SessionManager::GetInstance() +{ + static SessionManager instance; + return instance; +} + +Session SessionManager::GetSession(const SessionPoint &from, const std::string &targetDeviceId) const +{ + ZLOGD("begin. peer device:%{public}.6s", targetDeviceId.c_str()); + auto users = UserDelegate::GetInstance().GetRemoteUserStatus(targetDeviceId); + Session session; + session.appId = from.appId; + session.sourceUserId = from.userId; + session.sourceDeviceId = from.deviceId; + session.targetDeviceId = targetDeviceId; + for (const auto &user : users) { + bool isPermitted = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, targetDeviceId, from.appId); + ZLOGD("access to peer user %{public}d is %{public}d", user.id, isPermitted); + if (isPermitted) { + session.targetUserIds.push_back(user.id); + } + } + ZLOGD("end"); + return session; +} +bool SessionManager::CheckSession(const SessionPoint &from, const SessionPoint &to) const +{ + return AuthDelegate::GetInstance()->CheckAccess(from.userId, to.userId, to.deviceId, from.appId); +} + +bool Session::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(sourceDeviceId)], sourceDeviceId) && ret; + ret = SetValue(node[GET_NAME(targetDeviceId)], targetDeviceId) && ret; + ret = SetValue(node[GET_NAME(sourceUserId)], sourceUserId) && ret; + ret = SetValue(node[GET_NAME(targetUserIds)], targetUserIds) && ret; + ret = SetValue(node[GET_NAME(appId)], appId) && ret; + return ret; +} + +bool Session::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(sourceDeviceId), sourceDeviceId) && ret; + ret = GetValue(node, GET_NAME(targetDeviceId), targetDeviceId) && ret; + ret = GetValue(node, GET_NAME(sourceUserId), sourceUserId) && ret; + ret = GetValue(node, GET_NAME(targetUserIds), targetUserIds) && ret; + ret = GetValue(node, GET_NAME(appId), appId) && ret; + return ret; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.h b/services/distributeddataservice/app/src/session_manager/session_manager.h new file mode 100644 index 000000000..355539738 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/session_manager.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_SESSIONMANAGER_H +#define DISTRIBUTEDDATAMGR_SESSIONMANAGER_H + +#include +#include + +#include "serializable/serializable.h" + +namespace OHOS::DistributedData { +struct SessionPoint { + std::string deviceId; + int userId; + std::string appId; +}; + +class Session : public Serializable { +public: + std::string sourceDeviceId; + std::string targetDeviceId; + int32_t sourceUserId; + std::vector targetUserIds; + std::string appId; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + inline bool IsValid() + { + return !targetUserIds.empty(); + } +}; + +class SessionManager { +public: + static SessionManager &GetInstance(); + Session GetSession(const SessionPoint &from, const std::string &targetDeviceId) const; + bool CheckSession(const SessionPoint &from, const SessionPoint &to) const; +}; +} // namespace OHOS::DistributedData + +#endif // DISTRIBUTEDDATAMGR_SESSIONMANAGER_H diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp new file mode 100644 index 000000000..ae9642d2c --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "UpgradeManager" + +#include "upgrade_manager.h" + +#include "account_delegate.h" +#include "device_kvstore_impl.h" +#include "executor_factory.h" +#include "log_print.h" +#include "utils/constant.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +UpgradeManager &UpgradeManager::GetInstance() +{ + static UpgradeManager instance; + return instance; +} + +void UpgradeManager::Init() +{ + OHOS::DistributedKv::KvStoreTask retryTask([this]() { + do { + if (InitLocalCapability()) { + break; + } + static constexpr int RETRY_INTERVAL = 500; // millisecond + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL)); + } while (true); + }); + ExecutorFactory::GetInstance().Execute(std::move(retryTask)); +} + +CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &status) +{ + status = true; + if (capabilityMap_.Contains(deviceId)) { + return capabilityMap_.Find(deviceId).second; + } + ZLOGI("load capability from meta"); + CapMetaData capMetaData; + auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + status = false; + return capMetaData; + } + auto dbKey = CapMetaRow::GetKeyFor(deviceId); + ZLOGD("cap key:%{public}s", std::string(dbKey.begin(), dbKey.end()).c_str()); + DistributedDB::Value dbValue; + auto ret = metaDelegate->Get(dbKey, dbValue); + if (ret != DistributedDB::DBStatus::OK) { + ZLOGE("get cap meta failed, ret:%{public}d", ret); + status = false; + return capMetaData; + } + capMetaData.Unmarshall({ dbValue.begin(), dbValue.end() }); + bool isOk = capabilityMap_.Insert(deviceId, capMetaData); + ZLOGI("device:%{public}s, version:%{public}d, insert:%{public}d", deviceId.c_str(), capMetaData.version, isOk); + return capMetaData; +} + +bool UpgradeManager::InitLocalCapability() +{ + auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + return false; + } + auto localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + CapMetaData capMetaData; + capMetaData.version = CapMetaData::CURRENT_VERSION; + auto dbKey = CapMetaRow::GetKeyFor(localDeviceId); + std::string jsonData = CapMetaData::Marshall(capMetaData); + DistributedDB::Value dbValue { jsonData.begin(), jsonData.end() }; + auto ret = metaDelegate->Put(dbKey, dbValue); + ZLOGI("put capability meta data ret %{public}d", ret); + bool isOk = capabilityMap_.Insert(localDeviceId, capMetaData); + return ret == DistributedDB::DBStatus::OK && isOk; +} + +void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate, + const KvStoreTuple &tuple, DistributedData::AUTH_GROUP_TYPE groupType) +{ + if (storeDelegate == nullptr) { + ZLOGE("null store delegate"); + return; + } + auto localDevice = DeviceKvStoreImpl::GetLocalDeviceId(); + auto devices = + AuthDelegate::GetInstance()->GetTrustedDevicesByType(groupType, std::stoi(tuple.userId), tuple.appId); + auto result = std::remove_if(devices.begin(), devices.end(), [&localDevice](const std::string &device) { + if (localDevice == device) { + return true; + } + bool flag = false; + auto capability = DistributedData::UpgradeManager::GetInstance().GetCapability(device, flag); + return !flag || capability.version >= DistributedData::CapMetaData::CURRENT_VERSION; + }); + devices.erase(result, devices.end()); + + bool isSuccess = false; + auto compatibleUser = UpgradeManager::GetIdentifierByType(groupType, isSuccess); + if (!isSuccess) { + ZLOGW("get identifier by type failed"); + return; + } + + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId); + ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}s", tuple.storeId.c_str(), + compatibleUser.c_str(), DistributedData::Serializable::Marshall(devices).c_str()); + storeDelegate->SetEqualIdentifier(syncIdentifier, devices); +} + +std::string UpgradeManager::GetIdentifierByType(int32_t groupType, bool &isSuccess) +{ + isSuccess = true; + if (groupType == PEER_TO_PEER_GROUP) { + return "default"; + } else if (groupType == IDENTICAL_ACCOUNT_GROUP) { + auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + if (accountId.empty()) { + ZLOGE("failed to get current account id"); + isSuccess = false; + return {}; + } + return accountId; + } else { + ZLOGW("not supported group type:%{public}d", groupType); + isSuccess = false; + return {}; + } +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.h b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h new file mode 100644 index 000000000..44c67c94a --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H +#define DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H +#include + +#include "concurrent_map.h" +#include "kvstore_meta_manager.h" +#include "metadata/capability_meta_data.h" +#include "types.h" +namespace OHOS::DistributedData { +using DistributedDB::KvStoreNbDelegate; +using OHOS::DistributedKv::KvStoreTuple; + +class UpgradeManager { +public: + static UpgradeManager &GetInstance(); + void Init(); + CapMetaData GetCapability(const std::string &deviceId, bool &status); + static void SetCompatibleIdentifyByType( + KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple, AUTH_GROUP_TYPE groupType); + static std::string GetIdentifierByType(int32_t groupType, bool &isSuccess); + +private: + bool InitLocalCapability(); + ConcurrentMap capabilityMap_ {}; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H diff --git a/services/distributeddataservice/app/src/single_kvstore_impl.cpp b/services/distributeddataservice/app/src/single_kvstore_impl.cpp index 984fe07bc..a81e90dec 100755 --- a/services/distributeddataservice/app/src/single_kvstore_impl.cpp +++ b/services/distributeddataservice/app/src/single_kvstore_impl.cpp @@ -23,6 +23,7 @@ #include "constant.h" #include "dds_trace.h" #include "device_kvstore_impl.h" +#include "auth/auth_delegate.h" #include "kvstore_data_service.h" #include "kvstore_utils.h" #include "ipc_skeleton.h" @@ -30,6 +31,7 @@ #include "permission_validator.h" #include "query_helper.h" #include "reporter.h" +#include "upgrade_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; @@ -1610,4 +1612,36 @@ std::string SingleKvStoreImpl::GetStoreId() { return storeId_; } + +void SingleKvStoreImpl::SetCompatibleIdentify(const std::string &changedDevice) +{ + bool flag = false; + auto capability = UpgradeManager::GetInstance().GetCapability(changedDevice, flag); + if (!flag || capability.version >= CapMetaData::CURRENT_VERSION) { + ZLOGE("get peer capability %{public}d, or not older version", flag); + return; + } + + auto peerUserId = 0; // peer user id reversed here + auto groupType = + AuthDelegate::GetInstance()->GetGroupType(std::stoi(deviceAccountId_), peerUserId, changedDevice, appId_); + flag = false; + std::string compatibleUserId = UpgradeManager::GetIdentifierByType(groupType, flag); + if (!flag) { + ZLOGE("failed to get identifier by group type %{public}d", groupType); + return; + } + // older version use bound account syncIdentifier instead of user syncIdentifier + ZLOGI("compatible user:%{public}s", compatibleUserId.c_str()); + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUserId, appId_, storeId_); + kvStoreNbDelegate_->SetEqualIdentifier(syncIdentifier, { changedDevice }); +} + +void SingleKvStoreImpl::SetCompatibleIdentify() +{ + KvStoreTuple tuple = { deviceAccountId_, appId_, storeId_ }; + UpgradeManager::SetCompatibleIdentifyByType(kvStoreNbDelegate_, tuple, IDENTICAL_ACCOUNT_GROUP); + UpgradeManager::SetCompatibleIdentifyByType(kvStoreNbDelegate_, tuple, PEER_TO_PEER_GROUP); +} } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/app/src/single_kvstore_impl.h b/services/distributeddataservice/app/src/single_kvstore_impl.h index e1c2d5179..767872248 100755 --- a/services/distributeddataservice/app/src/single_kvstore_impl.h +++ b/services/distributeddataservice/app/src/single_kvstore_impl.h @@ -20,6 +20,8 @@ #include #include #include + +#include "auth/auth_delegate.h" #include "flowctrl_manager/kvstore_flowctrl_manager.h" #include "ikvstore_observer.h" #include "ikvstore_single.h" @@ -77,6 +79,8 @@ public: Status GetSecurityLevel(SecurityLevel &securityLevel) override; bool Import(const std::string &bundleName) const; void OnDump(int fd) const; + void SetCompatibleIdentify(const std::string &changedDevice); + void SetCompatibleIdentify(); protected: virtual KvStoreObserverImpl *CreateObserver(const SubscribeType subscribeType, sptr observer); diff --git a/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/services/distributeddataservice/app/src/uninstaller/BUILD.gn index 86458e388..c053864f9 100755 --- a/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -25,6 +25,7 @@ ohos_static_library("distributeddata_uninstaller_static") { "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//third_party/json/single_include", "//utils/native/base/include", "//base/security/huks/interfaces/innerkits/huks_standard/main/include", @@ -34,6 +35,7 @@ ohos_static_library("distributeddata_uninstaller_static") { deps = [ "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/libs/distributeddb:distributeddb", "//utils/native/base:utils", ] diff --git a/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp b/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp new file mode 100644 index 000000000..17c39f31a --- /dev/null +++ b/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "gmock/gmock.h" +#include "route_head_handler_impl.h" +#include "upgrade_manager.h" +#include "user_delegate.h" + +namespace OHOS::DistributedData { +using namespace testing::ext; +class SessionManagerTest : public testing::Test { +public: + static void SetUpTestCase() + { + // init peer device + UserMetaData userMetaData; + userMetaData.deviceId = "PEER_DEVICE_ID"; + + UserStatus status; + status.isActive = true; + constexpr const int MOCK_PEER_USER = 101; + status.id = MOCK_PEER_USER; + userMetaData.users = { status }; + + CapMetaData capMetaData; + capMetaData.version = CapMetaData::CURRENT_VERSION; + UpgradeManager::GetInstance().Init(); + } + static void TearDownTestCase() + { + } + void SetUp() + { + } + void TearDown() + { + } +}; + +/** +* @tc.name: PackAndUnPack01 +* @tc.desc: test get db dir +* @tc.type: FUNC +* @tc.require: +* @tc.author: illybyy +*/ +HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level0) +{ + const DistributedDB::ExtendInfo info = { + .userId = "100", .appId = "com.sample.helloworld", .storeId = "test_store", .deviceId = "PEER_DEVICE_ID" + }; + auto sendHandler = RouteHeadHandlerImpl::Create(info); + ASSERT_NE(sendHandler, nullptr); + auto size = sendHandler->GetHeadDataSize(); + ASSERT_GT(size, 0); + std::unique_ptr data = std::make_unique(size); + sendHandler->FillHeadData(data.get(), size, size); + + std::vector users; + auto recvHandler = RouteHeadHandlerImpl::Create({}); + recvHandler->ParseHeadData(data.get(), size, size, users); + EXPECT_EQ(users.size(), 1); + EXPECT_EQ(users[0], "101"); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/BUILD.gn b/services/distributeddataservice/framework/BUILD.gn index 2c2032bdf..094f15438 100644 --- a/services/distributeddataservice/framework/BUILD.gn +++ b/services/distributeddataservice/framework/BUILD.gn @@ -23,6 +23,7 @@ config("module_public_config") { "//third_party/json/single_include", "//third_party/openssl/include/", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/common", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include", ] } @@ -34,9 +35,12 @@ ohos_shared_library("distributeddatasvcfwk") { "checker/default/system_checker.cpp", "eventcenter/event.cpp", "eventcenter/event_center.cpp", + "metadata/capability_meta_data.cpp", "metadata/meta_data.cpp", "metadata/secret_key_meta_data.cpp", "metadata/store_meta_data.cpp", + "metadata/strategy_meta_data.cpp", + "metadata/user_meta_data.cpp", "serializable/serializable.cpp", "utils/anonymous.cpp", "utils/block_integer.cpp", diff --git a/services/distributeddataservice/framework/include/metadata/capability_meta_data.h b/services/distributeddataservice/framework/include/metadata/capability_meta_data.h new file mode 100644 index 000000000..f2dadaf3c --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/capability_meta_data.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_CAPABILITY_META_DATA_H +#define DISTRIBUTEDDATAMGR_CAPABILITY_META_DATA_H +#include "serializable/serializable.h" + +namespace OHOS::DistributedData { +class API_EXPORT CapMetaData final : public Serializable { +public: + const static int32_t CURRENT_VERSION = 1; + const static int32_t INVALID_VERSION = -1; + int32_t version = INVALID_VERSION; + + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; + +class CapMetaRow { +public: + static const std::string KEY_PREFIX; + API_EXPORT static std::vector GetKeyFor(const std::string &key); +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_CAPABILITY_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h b/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h index 2b93aa5fa..768c2ce6a 100644 --- a/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h @@ -22,9 +22,10 @@ struct SecretKeyMetaData final : public Serializable { std::vector time {}; std::vector sKey {}; int32_t kvStoreType = 0; - ~SecretKeyMetaData(); - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; + API_EXPORT SecretKeyMetaData(); + API_EXPORT ~SecretKeyMetaData(); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; }; } } diff --git a/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/services/distributeddataservice/framework/include/metadata/store_meta_data.h index 2000d6c93..4717867d4 100644 --- a/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -14,10 +14,16 @@ */ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H + +#include + #include "serializable/serializable.h" -namespace OHOS { -namespace DistributedData { + +namespace OHOS::DistributedData { struct StoreMetaData final : public Serializable { + // record kvstore meta version for compatible, should update when modify kvstore meta structure. + static constexpr uint32_t META_VERSION_SUPPORT_MULTIUSER = 0x03000002; + static constexpr uint32_t META_VERSION_SUPPORT_MULTIUSER_HOS = 0x03000001; bool isAutoSync = false; bool isBackup = false; bool isDirty = false; @@ -34,11 +40,26 @@ struct StoreMetaData final : public Serializable { std::string schema = ""; std::string storeId = ""; std::string userId = ""; - uint32_t version = 0; + uint32_t version = META_VERSION_SUPPORT_MULTIUSER; + + API_EXPORT ~StoreMetaData(); + API_EXPORT StoreMetaData(); + API_EXPORT StoreMetaData(const std::string &appId, const std::string &storeId, const std::string &userId); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; +class KvStoreMetaRow { +public: + KVSTORE_API static const std::string KEY_PREFIX; + + KVSTORE_API static std::vector GetKeyFor(const std::string &key); +}; + +class SecretMetaRow { +public: + KVSTORE_API static const std::string KEY_PREFIX; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; + KVSTORE_API static std::vector GetKeyFor(const std::string &key); }; -} -} +} // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h b/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h new file mode 100644 index 000000000..437c7ef2c --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_STRATEGY_META_DATA_H +#define DISTRIBUTEDDATAMGR_STRATEGY_META_DATA_H +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +struct StrategyMeta final : public Serializable { + std::string devId; + std::string devAccId; + std::string grpId; + std::string bundleName; + std::string storeId; + + API_EXPORT StrategyMeta(const std::string &devId, const std::string &devAccId, const std::string &grpId, + const std::string &bundleName, const std::string &storeId); + API_EXPORT ~StrategyMeta() {}; + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_STRATEGY_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/user_meta_data.h b/services/distributeddataservice/framework/include/metadata/user_meta_data.h new file mode 100644 index 000000000..7ed2b61a2 --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/user_meta_data.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_USER_META_DATA_H +#define DISTRIBUTEDDATAMGR_USER_META_DATA_H +#include +#include + +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +class API_EXPORT UserStatus final : public Serializable { +public: + int id; + bool isActive; + API_EXPORT UserStatus() = default; + API_EXPORT ~UserStatus() = default; + API_EXPORT UserStatus(int id, bool isActive); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; + +class API_EXPORT UserMetaData final : public Serializable { +public: + std::string deviceId; + std::vector users; + + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; + +class UserMetaRow { +public: + API_EXPORT static const std::string KEY_PREFIX; + API_EXPORT static std::vector GetKeyFor(const std::string &key); +}; +} // namespace OHOS::DistributedData + +#endif // DISTRIBUTEDDATAMGR_USER_META_DATA_H diff --git a/services/distributeddataservice/framework/include/serializable/serializable.h b/services/distributeddataservice/framework/include/serializable/serializable.h index 1bd6790fc..1ac14e112 100644 --- a/services/distributeddataservice/framework/include/serializable/serializable.h +++ b/services/distributeddataservice/framework/include/serializable/serializable.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_SERIALIZABLE_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_SERIALIZABLE_H #include +#include #include "visibility.h" #ifndef JSON_NOEXCEPTION #define JSON_NOEXCEPTION @@ -30,8 +31,22 @@ struct Serializable { public: using json = nlohmann::json; using size_type= nlohmann::json::size_type; + using error_handler_t = nlohmann::detail::error_handler_t; API_EXPORT json Marshall() const; + template + static std::string Marshall(T &values) + { + json root; + SetValue(root, values); + return root.dump(-1, ' ', false, error_handler_t::replace); + } + API_EXPORT bool Unmarshall(const std::string &jsonStr); + template + static bool Unmarshall(const std::string &body, T &values) + { + return GetValue(ToJson(body), "", values); + } API_EXPORT static json ToJson(const std::string &jsonStr); virtual bool Marshal(json &node) const = 0; virtual bool Unmarshal(const json &node) = 0; diff --git a/services/distributeddataservice/framework/metadata/capability_meta_data.cpp b/services/distributeddataservice/framework/metadata/capability_meta_data.cpp new file mode 100644 index 000000000..624c0b7a9 --- /dev/null +++ b/services/distributeddataservice/framework/metadata/capability_meta_data.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "metadata/capability_meta_data.h" + +#include "utils/constant.h" +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; + +bool CapMetaData::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(version)], version) && ret; + return ret; +} + +bool CapMetaData::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(version), version) && ret; + return ret; +} + +const std::string CapMetaRow::KEY_PREFIX = "CapabilityMeta"; +std::vector CapMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp b/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp index b844394a2..9ea3a7e32 100644 --- a/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp @@ -15,6 +15,9 @@ #include "metadata/secret_key_meta_data.h" namespace OHOS { namespace DistributedData { +SecretKeyMetaData::SecretKeyMetaData() +{ +} SecretKeyMetaData::~SecretKeyMetaData() { sKey.assign(sKey.size(), 0); diff --git a/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/services/distributeddataservice/framework/metadata/store_meta_data.cpp index a730149dd..3069a3a91 100644 --- a/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -14,15 +14,18 @@ */ #include "metadata/store_meta_data.h" + +#include "utils/constant.h" namespace OHOS { namespace DistributedData { -bool StoreMetaData::Marshal(Serializable::json &node) const +using namespace OHOS::DistributedKv; +bool StoreMetaData::Marshal(json &node) const { SetValue(node[GET_NAME(appId)], appId); SetValue(node[GET_NAME(appType)], appType); SetValue(node[GET_NAME(bundleName)], bundleName); SetValue(node[GET_NAME(dataDir)], dataDir); - SetValue(node[GET_NAME(deviceAccountId)], deviceAccountId); + SetValue(node[GET_NAME(deviceAccountID)], deviceAccountId); SetValue(node[GET_NAME(deviceId)], deviceId); SetValue(node[GET_NAME(isAutoSync)], isAutoSync); SetValue(node[GET_NAME(isBackup)], isBackup); @@ -30,19 +33,20 @@ bool StoreMetaData::Marshal(Serializable::json &node) const SetValue(node[GET_NAME(kvStoreType)], kvStoreType); SetValue(node[GET_NAME(schema)], schema); SetValue(node[GET_NAME(storeId)], storeId); - SetValue(node[GET_NAME(uid)], uid); + SetValue(node[GET_NAME(UID)], uid); + SetValue(node[GET_NAME(userId)], userId); SetValue(node[GET_NAME(version)], version); SetValue(node[GET_NAME(securityLevel)], securityLevel); SetValue(node[GET_NAME(isDirty)], isDirty); return true; } -bool StoreMetaData::Unmarshal(const Serializable::json &node) +bool StoreMetaData::Unmarshal(const json &node) { GetValue(node, GET_NAME(appId), appId); GetValue(node, GET_NAME(appType), appType); GetValue(node, GET_NAME(bundleName), bundleName); GetValue(node, GET_NAME(dataDir), dataDir); - GetValue(node, GET_NAME(deviceAccountId), deviceAccountId); + GetValue(node, GET_NAME(deviceAccountID), deviceAccountId); GetValue(node, GET_NAME(deviceId), deviceId); GetValue(node, GET_NAME(isAutoSync), isAutoSync); GetValue(node, GET_NAME(isBackup), isBackup); @@ -50,11 +54,37 @@ bool StoreMetaData::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(kvStoreType), kvStoreType); GetValue(node, GET_NAME(schema), schema); GetValue(node, GET_NAME(storeId), storeId); - GetValue(node, GET_NAME(uid), uid); + GetValue(node, GET_NAME(UID), uid); + GetValue(node, GET_NAME(userId), userId); GetValue(node, GET_NAME(version), version); GetValue(node, GET_NAME(securityLevel), securityLevel); GetValue(node, GET_NAME(isDirty), isDirty); return true; } +StoreMetaData::StoreMetaData() +{ +} +StoreMetaData::~StoreMetaData() +{ +} +StoreMetaData::StoreMetaData(const std::string &appId, const std::string &storeId, const std::string &userId) + : appId(appId), storeId(storeId), userId(userId) +{ +} + +// the Key Prefix for Meta data of KvStore. +const std::string KvStoreMetaRow::KEY_PREFIX = "KvStoreMetaData"; +std::vector KvStoreMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KvStoreMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} + +const std::string SecretMetaRow::KEY_PREFIX = "SecretKey"; +std::vector SecretMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ SecretMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; } -} \ No newline at end of file +} // namespace DistributedData +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp b/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp new file mode 100644 index 000000000..2cb49d40e --- /dev/null +++ b/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "metadata/strategy_meta_data.h" +namespace OHOS::DistributedData { +bool StrategyMeta::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(devId)], devId) && ret; + ret = SetValue(node[GET_NAME(devAccId)], devAccId) && ret; + ret = SetValue(node[GET_NAME(grpId)], grpId) && ret; + ret = SetValue(node[GET_NAME(bundleName)], bundleName) && ret; + ret = SetValue(node[GET_NAME(storeId)], storeId) && ret; + return ret; +} + +bool StrategyMeta::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(devId), devId) && ret; + ret = GetValue(node, GET_NAME(devAccId), devAccId) && ret; + ret = GetValue(node, GET_NAME(grpId), grpId) && ret; + ret = GetValue(node, GET_NAME(bundleName), bundleName) && ret; + ret = GetValue(node, GET_NAME(storeId), storeId) && ret; + return ret; +} +StrategyMeta::StrategyMeta(const std::string &devId, const std::string &devAccId, const std::string &grpId, + const std::string &bundleName, const std::string &storeId) + : devId(devId), devAccId(devAccId), grpId(grpId), bundleName(bundleName), storeId(storeId) +{ +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/user_meta_data.cpp b/services/distributeddataservice/framework/metadata/user_meta_data.cpp new file mode 100644 index 000000000..c556e99dc --- /dev/null +++ b/services/distributeddataservice/framework/metadata/user_meta_data.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "metadata/user_meta_data.h" + +#include "utils/constant.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +bool UserMetaData::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(deviceId)], deviceId) && ret; + ret = SetValue(node[GET_NAME(users)], users) && ret; + + return ret; +} + +bool UserMetaData::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(deviceId), deviceId) && ret; + ret = GetValue(node, GET_NAME(users), users) && ret; + + return ret; +} + +bool UserStatus::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(id)], id) && ret; + ret = SetValue(node[GET_NAME(isActive)], isActive) && ret; + return ret; +} + +bool UserStatus::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(id), id) && ret; + ret = GetValue(node, GET_NAME(isActive), isActive) && ret; + return ret; +} +UserStatus::UserStatus(int id, bool isActive) : id(id), isActive(isActive) +{ +} + +const std::string UserMetaRow::KEY_PREFIX = "UserMeta"; +std::vector UserMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/service/config/src/model/directory_config.cpp b/services/distributeddataservice/service/config/src/model/directory_config.cpp index 5cde0ec35..97152be9a 100644 --- a/services/distributeddataservice/service/config/src/model/directory_config.cpp +++ b/services/distributeddataservice/service/config/src/model/directory_config.cpp @@ -44,8 +44,8 @@ bool DirectoryConfig::Marshal(json &node) const bool DirectoryConfig::Unmarshal(const json &node) { bool ret = true; - ret &= GetValue(node, GET_NAME(currentStrategyVersion), currentStrategyVersion); - ret &= GetValue(node, GET_NAME(strategy), strategy); + ret = GetValue(node, GET_NAME(currentStrategyVersion), currentStrategyVersion) && ret; + ret = GetValue(node, GET_NAME(strategy), strategy) && ret; return ret; } } diff --git a/services/distributeddataservice/service/directory/include/directory_manager.h b/services/distributeddataservice/service/directory/include/directory_manager.h index 433089578..3227244e8 100644 --- a/services/distributeddataservice/service/directory/include/directory_manager.h +++ b/services/distributeddataservice/service/directory/include/directory_manager.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SDB_DIRECTORY_MANAGER_H -#define SDB_DIRECTORY_MANAGER_H +#ifndef DISTRIBUTEDDATAMGR_DIRECTORY_MANAGER_H +#define DISTRIBUTEDDATAMGR_DIRECTORY_MANAGER_H #include #include @@ -91,4 +91,4 @@ private: std::string version_; }; } // namespace OHOS::DistributedKv -#endif // SDB_DIRECTORY_MANAGER_H +#endif // DISTRIBUTEDDATAMGR_DIRECTORY_MANAGER_H diff --git a/services/distributeddataservice/service/directory/include/kvstore_context.h b/services/distributeddataservice/service/directory/include/kvstore_context.h index 27135bd3b..c42bb7f21 100644 --- a/services/distributeddataservice/service/directory/include/kvstore_context.h +++ b/services/distributeddataservice/service/directory/include/kvstore_context.h @@ -13,15 +13,16 @@ * limitations under the License. */ +#ifndef DISTRIBUTEDDATAMGR_KVSTORE_CONTEXT_H +#define DISTRIBUTEDDATAMGR_KVSTORE_CONTEXT_H #include -#ifndef SDB_KVSTORE_CONTEXT_H -#define SDB_KVSTORE_CONTEXT_H +#include "types.h" namespace OHOS::DistributedData { struct ClientContext { std::string userId {}; std::string bundleName {}; std::string dataDir {}; }; -} -#endif // SDB_KVSTORE_CONTEXT_H \ No newline at end of file +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_KVSTORE_CONTEXT_H \ No newline at end of file diff --git a/services/distributeddataservice/service/kv/user_delegate.cpp b/services/distributeddataservice/service/kv/user_delegate.cpp new file mode 100644 index 000000000..96c55badc --- /dev/null +++ b/services/distributeddataservice/service/kv/user_delegate.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "user_delegate.h" + +#define LOG_TAG "UserDelegate" + +#include "account_delegate.h" +#include "communication_provider.h" +#include "device_kvstore_impl.h" +#include "executor_factory.h" +#include "kvstore_meta_manager.h" +#include "log_print.h" +#include "os_account_manager.h" + +namespace OHOS::DistributedData { +using OHOS::AppDistributedKv::CommunicationProvider; +using namespace OHOS::DistributedKv; +using namespace OHOS::AccountSA; +std::vector UserDelegate::GetLocalUserStatus() +{ + ZLOGI("begin"); + auto deviceInfo = CommunicationProvider::GetInstance().GetLocalDevice(); + if (deviceInfo.deviceId.empty()) { + ZLOGE("failed to get local device id"); + return {}; + } + return GetUsers(deviceInfo.deviceId); +} + +std::vector UserDelegate::GetRemoteUserStatus(const std::string &deviceId) +{ + if (deviceId.empty()) { + ZLOGE("error input device id"); + return {}; + } + return GetUsers(deviceId); +} + +std::vector UserDelegate::GetUsers(const std::string &deviceId) +{ + std::vector userStatus; + for (const auto &entry : deviceUserMap_[deviceId]) { + userStatus.emplace_back(entry.first, entry.second); + } + ZLOGI("device:%{public}s, users:%{public}s", deviceId.c_str(), Serializable::Marshall(userStatus).c_str()); + return userStatus; +} + +void UserDelegate::DeleteUsers(const std::string &deviceId) +{ + deviceUserMap_.Erase(deviceId); +} + +void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector &userStatus) +{ + ZLOGI("begin, device:%{public}s, users:%{public}u", deviceId.c_str(), userStatus.size()); + deviceUserMap_.ComputeIfPresent(deviceId, [](const auto &key, std::map &userMap) { + for (auto &user : userMap) { + user.second = false; + } + }); + for (auto &user : userStatus) { + deviceUserMap_[deviceId][user.id] = user.isActive; + } + ZLOGI("end, device:%{public}s, users:%{public}u", deviceId.c_str(), deviceUserMap_[deviceId].size()); +} + +bool UserDelegate::InitLocalUserMeta() +{ + std::vector osAccountIds = { { 0, true } }; // system user default + auto ret = OsAccountManager::QueryActiveOsAccountIds(osAccountIds); + if (ret != 0 || osAccountIds.empty()) { + ZLOGE("failed to query os accounts, ret:%{public}d", ret); + return false; + } + std::vector userStatus = { { 0, true } }; + for (const auto &user : osAccountIds) { + userStatus.emplace_back(user, true); + } + UserMetaData userMetaData; + userMetaData.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + UpdateUsers(userMetaData.deviceId, userStatus); + for (auto &pair : deviceUserMap_[userMetaData.deviceId]) { + userMetaData.users.emplace_back(pair.first, pair.second); + } + + auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + return false; + } + auto dbKey = UserMetaRow::GetKeyFor(userMetaData.deviceId); + std::string jsonData = UserMetaData::Marshall(userMetaData); + DistributedDB::Value dbValue{ jsonData.begin(), jsonData.end() }; + ret = metaDelegate->Put(dbKey, dbValue); + ZLOGI("put user meta data ret %{public}d", ret); + return ret == DistributedDB::DBStatus::OK; +} + +UserDelegate &UserDelegate::GetInstance() +{ + static UserDelegate instance; + return instance; +} + +void UserDelegate::Init() +{ + KvStoreTask retryTask([&]() { + do { + static constexpr int RETRY_INTERVAL = 500; // millisecond + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL)); + if (!InitLocalUserMeta()) { + continue; + } + break; + } while (true); + ZLOGI("update user meta ok"); + }); + ExecutorFactory::GetInstance().Execute(std::move(retryTask)); + auto ret = AccountDelegate::GetInstance()->Subscribe( + std::make_shared(std::shared_ptr(this))); + // subscribe user meta in other devices + KvStoreMetaManager::GetInstance().SubscribeMeta(UserMetaRow::KEY_PREFIX, + [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { + UserMetaData metaData; + metaData.Unmarshall({ value.begin(), value.end() }); + if (metaData.deviceId == DeviceKvStoreImpl::GetLocalDeviceId()) { + ZLOGD("ignore local device user meta change"); + return; + } + if (flag == CHANGE_FLAG::INSERT || flag == CHANGE_FLAG::UPDATE) { + UpdateUsers(metaData.deviceId, metaData.users); + } else if (flag == CHANGE_FLAG::DELETE) { + DeleteUsers(metaData.deviceId); + } else { + ZLOGD("ignored operation"); + } + }); + ZLOGD("subscribe os account ret:%{public}d", ret); +} + +bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) +{ + // update all local user status + return InitLocalUserMeta(); +} + +UserDelegate::LocalUserObserver::LocalUserObserver(const std::shared_ptr &userDelegate) + : userDelegate_(std::move(userDelegate)) +{ +} + +void UserDelegate::LocalUserObserver::OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) +{ + ZLOGI("event info:%{public}s, %{public}d", eventInfo.deviceAccountId.c_str(), eventInfo.status); + userDelegate_->NotifyUserEvent({}); // just notify +} + +std::string UserDelegate::LocalUserObserver::Name() +{ + return "user_delegate"; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/service/kv/user_delegate.h b/services/distributeddataservice/service/kv/user_delegate.h new file mode 100644 index 000000000..9239d174e --- /dev/null +++ b/services/distributeddataservice/service/kv/user_delegate.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_USER_DELEGATE_H +#define DISTRIBUTEDDATAMGR_USER_DELEGATE_H + +#include + +#include "account_delegate.h" +#include "concurrent_map.h" +#include "metadata/user_meta_data.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +using AccountDelegate = DistributedKv::AccountDelegate; +using DistributedData::UserStatus; +class UserDelegate { +public: + struct UserEvent { + int id; + bool isActive; + }; + static UserDelegate &GetInstance(); + + void Init(); + std::vector GetLocalUserStatus(); + std::vector GetRemoteUserStatus(const std::string &deviceId); + bool InitLocalUserMeta(); + +private: + class LocalUserObserver : public AccountDelegate::Observer { + public: + explicit LocalUserObserver(const std::shared_ptr &userDelegate); + void OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) override; + std::string Name() override; + + private: + std::shared_ptr userDelegate_; + }; + std::vector GetUsers(const std::string &deviceId); + void UpdateUsers(const std::string &deviceId, const std::vector &userStatus); + void DeleteUsers(const std::string &deviceId); + bool NotifyUserEvent(const UserEvent &userEvent); + + // device : { user : isActive } + ConcurrentMap> deviceUserMap_; +}; +} // namespace OHOS::DistributedData + +#endif // DISTRIBUTEDDATAMGR_USER_DELEGATE_H -- Gitee From 9fb2d457992262c71d314835eb8c3c5e78161a0c Mon Sep 17 00:00:00 2001 From: illybyy Date: Mon, 28 Feb 2022 22:07:27 +0800 Subject: [PATCH 02/10] fix test compile Signed-off-by: illybyy --- .../route_head_handler_impl.cpp | 3 +- .../session_manager/route_head_handler_impl.h | 1 - .../distributeddataservice/app/test/BUILD.gn | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp index b8053c590..f763d20d3 100644 --- a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -25,6 +25,7 @@ namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; +constexpr const int ALIGN_WIDTH = 8; std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) { auto handler = std::make_shared(info); @@ -37,7 +38,7 @@ std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo } RouteHeadHandlerImpl::RouteHeadHandlerImpl(const ExtendInfo &info) - : userId_(info.userId), appId_(info.appId), storeId_(info.storeId), deviceId_(info.dstTarget) + : userId_(info.userId), appId_(info.appId), storeId_(info.storeId), deviceId_(info.dstTarget), headSize_(0) { ZLOGI("init route handler, app:%{public}s, user:%{public}s, peer:%{public}s", appId_.c_str(), userId_.c_str(), deviceId_.c_str()); diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h index bfd39080e..395e4d336 100644 --- a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h @@ -21,7 +21,6 @@ #include "session_manager.h" namespace OHOS::DistributedData { -constexpr int ALIGN_WIDTH = 8; template constexpr T GET_ALIGNED_SIZE(T x, int alignWidth) { return (x + (alignWidth - 1)) & ~(alignWidth - 1); diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index c9dfe3160..a14a77e0b 100755 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -31,6 +31,8 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/session_manager", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/kv", "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", "//utils/native/base/include", "//utils/system/safwk/native/include", @@ -54,6 +56,7 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -68,6 +71,9 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_impl_logical_isolation_test.cpp", ] @@ -80,16 +86,21 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + + sources += kv_sources deps = [ "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -112,6 +123,7 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -126,9 +138,15 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_impl_physical_isolation_test.cpp", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + + sources += kv_sources configs = [ ":module_private_config" ] @@ -138,6 +156,7 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", @@ -148,6 +167,7 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -170,6 +190,7 @@ ohos_unittest("KvStoreDataServiceTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -184,10 +205,15 @@ ohos_unittest("KvStoreDataServiceTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_data_service_test.cpp", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + sources += kv_sources configs = [ ":module_private_config" ] external_deps = [ @@ -196,6 +222,7 @@ ohos_unittest("KvStoreDataServiceTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", @@ -206,6 +233,7 @@ ohos_unittest("KvStoreDataServiceTest") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -228,6 +256,7 @@ ohos_unittest("KvStoreBackupTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -242,10 +271,15 @@ ohos_unittest("KvStoreBackupTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_backup_test.cpp", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + sources += kv_sources cflags_cc = [ "-DUT_TEST" ] configs = [ ":module_private_config" ] @@ -255,6 +289,7 @@ ohos_unittest("KvStoreBackupTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", @@ -265,6 +300,7 @@ ohos_unittest("KvStoreBackupTest") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -293,6 +329,7 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", @@ -319,6 +356,7 @@ ohos_unittest("KvStoreSyncManagerTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -333,9 +371,14 @@ ohos_unittest("KvStoreSyncManagerTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + sources += kv_sources configs = [ ":module_private_config" ] external_deps = [ @@ -344,6 +387,7 @@ ohos_unittest("KvStoreSyncManagerTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", @@ -354,6 +398,7 @@ ohos_unittest("KvStoreSyncManagerTest") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -376,6 +421,7 @@ ohos_unittest("KvStoreUninstallerTest") { "../src/device_kvstore_impl.cpp", "../src/device_kvstore_observer_impl.cpp", "../src/device_kvstore_resultset_impl.cpp", + "../src/executor_factory.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", @@ -390,16 +436,22 @@ ohos_unittest("KvStoreUninstallerTest") { "../src/query_helper.cpp", "../src/security/security.cpp", "../src/security/sensitive.cpp", + "../src/session_manager/route_head_handler_impl.cpp", + "../src/session_manager/session_manager.cpp", + "../src/session_manager/upgrade_manager.cpp", "../src/single_kvstore_impl.cpp", "unittest/uninstaller_test.cpp", ] + kv_sources = [ "../../service/kv/user_delegate.cpp" ] + sources += kv_sources configs = [ ":module_private_config" ] deps = [ "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/account:distributeddata_account_static", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/auth:distributeddata_auth_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/permission:distributeddata_permission_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -420,6 +472,7 @@ ohos_unittest("KvStoreUninstallerTest") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", -- Gitee From d0d0656d92cc63c718ccb3b9c281e03ef8974e2a Mon Sep 17 00:00:00 2001 From: illybyy Date: Tue, 1 Mar 2022 10:31:30 +0800 Subject: [PATCH 03/10] fix auth free memory Signed-off-by: illybyy --- .../adapter/auth/src/auth_delegate.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp index 28fc05d92..9c8a2d8c8 100644 --- a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp +++ b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp @@ -55,7 +55,7 @@ AuthHandler::RelatedGroup AuthHandler::GetGroupInfo( int32_t localUserId, const std::string &appId, const std::string &peerDeviceId) { auto groupManager = GetGmInstance(); - if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr) { + if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr || groupManager->destroyInfo == nullptr) { ZLOGE("failed to get group manager"); return {}; } @@ -70,7 +70,7 @@ AuthHandler::RelatedGroup AuthHandler::GetGroupInfo( ZLOGI("get related group json :%{public}s", groupInfo); std::vector groups; RelatedGroup::Unmarshall(groupInfo, groups); - free(groupInfo); + groupManager->destroyInfo(&groupInfo); // same account has priority std::sort(groups.begin(), groups.end(), @@ -88,7 +88,7 @@ std::vector AuthHandler::GetTrustedDevicesByType( { auto groupManager = GetGmInstance(); if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr - || groupManager->getTrustedDevices == nullptr) { + || groupManager->getTrustedDevices == nullptr || groupManager->destroyInfo == nullptr) { ZLOGE("failed to get group manager"); return {}; } @@ -104,7 +104,7 @@ std::vector AuthHandler::GetTrustedDevicesByType( ZLOGI("get joined group json :%{public}s", groupsJson); std::vector groups; RelatedGroup::Unmarshall(groupsJson, groups); - free(groupsJson); + groupManager->destroyInfo(&groupsJson); std::vector trustedDevices; for (const auto &group : groups) { @@ -121,7 +121,7 @@ std::vector AuthHandler::GetTrustedDevicesByType( ZLOGI("get trusted device json:%{public}s", devicesJson); std::vector devices; TrustDevice::Unmarshall(devicesJson, devices); - free(devicesJson); + groupManager->destroyInfo(&devicesJson); for (const auto &item : devices) { auto &provider = AppDistributedKv::CommunicationProvider::GetInstance(); auto networkId = provider.ToNodeId(item.authId); -- Gitee From a904523ea35eceebd3475c642cc3cb96318d362b Mon Sep 17 00:00:00 2001 From: illybyy Date: Tue, 1 Mar 2022 14:59:31 +0800 Subject: [PATCH 04/10] fix review ideas Signed-off-by: illybyy --- .../innerkits/distributeddata/include/types.h | 13 ------------- .../distributeddataservice/adapter/auth/BUILD.gn | 1 + .../adapter/auth/src/auth_delegate.cpp | 2 +- .../app/src/kvstore_user_manager.cpp | 1 - .../app/src/session_manager/session_manager.cpp | 2 +- .../app/src/session_manager/upgrade_manager.cpp | 4 ++-- 6 files changed, 5 insertions(+), 18 deletions(-) diff --git a/interfaces/innerkits/distributeddata/include/types.h b/interfaces/innerkits/distributeddata/include/types.h index 5903077d5..4e2b0fe1f 100755 --- a/interfaces/innerkits/distributeddata/include/types.h +++ b/interfaces/innerkits/distributeddata/include/types.h @@ -82,19 +82,6 @@ struct KvStoreTuple { std::string userId; std::string appId; std::string storeId; - - KvStoreTuple() = default; - KvStoreTuple(std::string userId, std::string appId) : userId(std::move(userId)), appId(std::move(appId)) - { - } - KvStoreTuple(std::string userId, std::string appId, std::string storeId) - : userId(std::move(userId)), appId(std::move(appId)), storeId(std::move(storeId)) - { - } - bool operator<(const KvStoreTuple &that) const - { - return this->userId < that.userId || this->appId < that.appId || this->storeId < that.storeId; - } }; struct AppThreadInfo { diff --git a/services/distributeddataservice/adapter/auth/BUILD.gn b/services/distributeddataservice/adapter/auth/BUILD.gn index 155c3a2d1..ae239e3ec 100644 --- a/services/distributeddataservice/adapter/auth/BUILD.gn +++ b/services/distributeddataservice/adapter/auth/BUILD.gn @@ -10,6 +10,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + import("//build/ohos.gni") ohos_static_library("distributeddata_auth_static") { diff --git a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp index 9c8a2d8c8..062c5b4c4 100644 --- a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp +++ b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp @@ -79,7 +79,7 @@ AuthHandler::RelatedGroup AuthHandler::GetGroupInfo( ZLOGI("get group type:%{public}d", groups.front().groupType); return groups.front(); } - ZLOGD("there is no group to access to peer device:%{public}s", peerDeviceId.c_str()); + ZLOGD("there is no group to access to peer device:%{public}.10s", peerDeviceId.c_str()); return {}; } diff --git a/services/distributeddataservice/app/src/kvstore_user_manager.cpp b/services/distributeddataservice/app/src/kvstore_user_manager.cpp index da27844f2..0e472bc0c 100755 --- a/services/distributeddataservice/app/src/kvstore_user_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_user_manager.cpp @@ -146,7 +146,6 @@ void KvStoreUserManager::Dump(int fd) const bool KvStoreUserManager::IsStoreOpened(const std::string &appId, const std::string &storeId) { -// std::lock_guard lg(appMutex_); auto it = appMap_.find(appId); return it != appMap_.end() && it->second.IsStoreOpened(storeId); } diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/services/distributeddataservice/app/src/session_manager/session_manager.cpp index dc1678211..1f54406b0 100644 --- a/services/distributeddataservice/app/src/session_manager/session_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -32,7 +32,7 @@ SessionManager &SessionManager::GetInstance() Session SessionManager::GetSession(const SessionPoint &from, const std::string &targetDeviceId) const { - ZLOGD("begin. peer device:%{public}.6s", targetDeviceId.c_str()); + ZLOGD("begin. peer device:%{public}.10s", targetDeviceId.c_str()); auto users = UserDelegate::GetInstance().GetRemoteUserStatus(targetDeviceId); Session session; session.appId = from.appId; diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index ae9642d2c..e96a6a4aa 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -69,7 +69,7 @@ CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &sta } capMetaData.Unmarshall({ dbValue.begin(), dbValue.end() }); bool isOk = capabilityMap_.Insert(deviceId, capMetaData); - ZLOGI("device:%{public}s, version:%{public}d, insert:%{public}d", deviceId.c_str(), capMetaData.version, isOk); + ZLOGI("device:%{public}.10s, version:%{public}d, insert:%{public}d", deviceId.c_str(), capMetaData.version, isOk); return capMetaData; } @@ -121,7 +121,7 @@ void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegat auto syncIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId); - ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}s", tuple.storeId.c_str(), + ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s", tuple.storeId.c_str(), compatibleUser.c_str(), DistributedData::Serializable::Marshall(devices).c_str()); storeDelegate->SetEqualIdentifier(syncIdentifier, devices); } -- Gitee From 6e8fd94ca741e73ca3875935efb72e1b3f938260 Mon Sep 17 00:00:00 2001 From: illybyy Date: Tue, 1 Mar 2022 15:58:00 +0800 Subject: [PATCH 05/10] fix thread capture Signed-off-by: illybyy --- services/distributeddataservice/service/kv/user_delegate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/distributeddataservice/service/kv/user_delegate.cpp b/services/distributeddataservice/service/kv/user_delegate.cpp index 96c55badc..808be1d92 100644 --- a/services/distributeddataservice/service/kv/user_delegate.cpp +++ b/services/distributeddataservice/service/kv/user_delegate.cpp @@ -118,7 +118,7 @@ UserDelegate &UserDelegate::GetInstance() void UserDelegate::Init() { - KvStoreTask retryTask([&]() { + KvStoreTask retryTask([this]() { do { static constexpr int RETRY_INTERVAL = 500; // millisecond std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL)); -- Gitee From cbcd752e411623db7919c61b56afa1c0395f139d Mon Sep 17 00:00:00 2001 From: illybyy Date: Tue, 1 Mar 2022 16:53:59 +0800 Subject: [PATCH 06/10] fix pointer issue Signed-off-by: illybyy --- .../service/kv/user_delegate.cpp | 15 +++++++-------- .../service/kv/user_delegate.h | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/services/distributeddataservice/service/kv/user_delegate.cpp b/services/distributeddataservice/service/kv/user_delegate.cpp index 808be1d92..8e070a894 100644 --- a/services/distributeddataservice/service/kv/user_delegate.cpp +++ b/services/distributeddataservice/service/kv/user_delegate.cpp @@ -55,7 +55,7 @@ std::vector UserDelegate::GetUsers(const std::string &deviceId) for (const auto &entry : deviceUserMap_[deviceId]) { userStatus.emplace_back(entry.first, entry.second); } - ZLOGI("device:%{public}s, users:%{public}s", deviceId.c_str(), Serializable::Marshall(userStatus).c_str()); + ZLOGI("device:%{public}.10s, users:%{public}s", deviceId.c_str(), Serializable::Marshall(userStatus).c_str()); return userStatus; } @@ -66,7 +66,7 @@ void UserDelegate::DeleteUsers(const std::string &deviceId) void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector &userStatus) { - ZLOGI("begin, device:%{public}s, users:%{public}u", deviceId.c_str(), userStatus.size()); + ZLOGI("begin, device:%{public}.10s, users:%{public}u", deviceId.c_str(), userStatus.size()); deviceUserMap_.ComputeIfPresent(deviceId, [](const auto &key, std::map &userMap) { for (auto &user : userMap) { user.second = false; @@ -75,7 +75,7 @@ void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vectorSubscribe( - std::make_shared(std::shared_ptr(this))); + auto ret = AccountDelegate::GetInstance()->Subscribe(std::make_shared(*this)); // subscribe user meta in other devices KvStoreMetaManager::GetInstance().SubscribeMeta(UserMetaRow::KEY_PREFIX, [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { @@ -158,15 +157,15 @@ bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) return InitLocalUserMeta(); } -UserDelegate::LocalUserObserver::LocalUserObserver(const std::shared_ptr &userDelegate) - : userDelegate_(std::move(userDelegate)) +UserDelegate::LocalUserObserver::LocalUserObserver(UserDelegate &userDelegate) + : userDelegate_(userDelegate) { } void UserDelegate::LocalUserObserver::OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) { ZLOGI("event info:%{public}s, %{public}d", eventInfo.deviceAccountId.c_str(), eventInfo.status); - userDelegate_->NotifyUserEvent({}); // just notify + userDelegate_.NotifyUserEvent({}); // just notify } std::string UserDelegate::LocalUserObserver::Name() diff --git a/services/distributeddataservice/service/kv/user_delegate.h b/services/distributeddataservice/service/kv/user_delegate.h index 9239d174e..261430c41 100644 --- a/services/distributeddataservice/service/kv/user_delegate.h +++ b/services/distributeddataservice/service/kv/user_delegate.h @@ -42,12 +42,12 @@ public: private: class LocalUserObserver : public AccountDelegate::Observer { public: - explicit LocalUserObserver(const std::shared_ptr &userDelegate); + explicit LocalUserObserver(UserDelegate &userDelegate); void OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) override; std::string Name() override; private: - std::shared_ptr userDelegate_; + UserDelegate &userDelegate_; }; std::vector GetUsers(const std::string &deviceId); void UpdateUsers(const std::string &deviceId, const std::vector &userStatus); -- Gitee From 59be0b72a051520277308be4d522710c42144468 Mon Sep 17 00:00:00 2001 From: illybyy Date: Tue, 1 Mar 2022 20:40:36 +0800 Subject: [PATCH 07/10] fix switch user issue Signed-off-by: illybyy --- .../app/src/kvstore_meta_manager.cpp | 1 + .../service/kv/user_delegate.cpp | 31 +++++++++++++++++-- .../service/kv/user_delegate.h | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 21143dc77..92113fceb 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -984,6 +984,7 @@ void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges( for (const auto &entry : entries) { std::string key(entry.key.begin(), entry.key.end()); for (const auto &item : handlerMap_) { + ZLOGI("flag:%{public}d, key:%{public}s", flag, key.c_str()); if (key.find(item.first) == 0) { item.second(entry.key, entry.value, flag); } diff --git a/services/distributeddataservice/service/kv/user_delegate.cpp b/services/distributeddataservice/service/kv/user_delegate.cpp index 8e070a894..3f35b4ed8 100644 --- a/services/distributeddataservice/service/kv/user_delegate.cpp +++ b/services/distributeddataservice/service/kv/user_delegate.cpp @@ -52,6 +52,9 @@ std::vector UserDelegate::GetRemoteUserStatus(const std::vector UserDelegate::GetUsers(const std::string &deviceId) { std::vector userStatus; + if (!deviceUserMap_.Contains(deviceId)) { + LoadFromMeta(deviceId); + } for (const auto &entry : deviceUserMap_[deviceId]) { userStatus.emplace_back(entry.first, entry.second); } @@ -110,6 +113,30 @@ bool UserDelegate::InitLocalUserMeta() return ret == DistributedDB::DBStatus::OK; } +void UserDelegate::LoadFromMeta(const std::string &deviceId) +{ + auto &metaDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + return; + } + + auto dbKey = UserMetaRow::GetKeyFor(deviceId); + DistributedDB::Value dbValue; + auto ret = metaDelegate->Get(dbKey, dbValue); + UserMetaData userMetaData; + ZLOGI("get user meta data ret %{public}d", ret); + if (ret != DistributedDB::DBStatus::OK) { + return; + } + userMetaData.Unmarshall({ dbValue.begin(), dbValue.end() }); + std::map userMap; + for (const auto &user : userMetaData.users) { + userMap[user.id] = user.isActive; + } + deviceUserMap_[deviceId] = userMap; +} + UserDelegate &UserDelegate::GetInstance() { static UserDelegate instance; @@ -136,6 +163,7 @@ void UserDelegate::Init() [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { UserMetaData metaData; metaData.Unmarshall({ value.begin(), value.end() }); + ZLOGD("flag:%{public}d, value:%{public}.10s", flag, metaData.deviceId.c_str()); if (metaData.deviceId == DeviceKvStoreImpl::GetLocalDeviceId()) { ZLOGD("ignore local device user meta change"); return; @@ -157,8 +185,7 @@ bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) return InitLocalUserMeta(); } -UserDelegate::LocalUserObserver::LocalUserObserver(UserDelegate &userDelegate) - : userDelegate_(userDelegate) +UserDelegate::LocalUserObserver::LocalUserObserver(UserDelegate &userDelegate) : userDelegate_(userDelegate) { } diff --git a/services/distributeddataservice/service/kv/user_delegate.h b/services/distributeddataservice/service/kv/user_delegate.h index 261430c41..75d90a54d 100644 --- a/services/distributeddataservice/service/kv/user_delegate.h +++ b/services/distributeddataservice/service/kv/user_delegate.h @@ -50,6 +50,7 @@ private: UserDelegate &userDelegate_; }; std::vector GetUsers(const std::string &deviceId); + void LoadFromMeta(const std::string &deviceId); void UpdateUsers(const std::string &deviceId, const std::vector &userStatus); void DeleteUsers(const std::string &deviceId); bool NotifyUserEvent(const UserEvent &userEvent); -- Gitee From 34ce6f6a1e638b0779da4b5bb003d5407e369716 Mon Sep 17 00:00:00 2001 From: illybyy Date: Wed, 2 Mar 2022 10:23:24 +0800 Subject: [PATCH 08/10] bugfix Signed-off-by: illybyy --- .../adapter/auth/BUILD.gn | 2 - services/distributeddataservice/app/BUILD.gn | 1 + .../app/src/kvstore_account_observer.cpp | 6 ++- .../app/src/kvstore_data_service.cpp | 13 ++----- .../app/src/kvstore_data_service.h | 24 ++++++------ .../app/src/kvstore_device_listener.cpp | 37 +++++++++++++++++++ .../app/src/kvstore_device_listener.h | 33 +++++++++++++++++ 7 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 services/distributeddataservice/app/src/kvstore_device_listener.cpp create mode 100644 services/distributeddataservice/app/src/kvstore_device_listener.h diff --git a/services/distributeddataservice/adapter/auth/BUILD.gn b/services/distributeddataservice/adapter/auth/BUILD.gn index ae239e3ec..df2d81bec 100644 --- a/services/distributeddataservice/adapter/auth/BUILD.gn +++ b/services/distributeddataservice/adapter/auth/BUILD.gn @@ -30,8 +30,6 @@ ohos_static_library("distributeddata_auth_static") { cflags_cc = [ "-fvisibility=hidden" ] - configs = [ "//build/config/compiler:exceptions" ] - deps = [ "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", "//utils/native/base:utils", diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index 03e1f656a..ca6ca772a 100755 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -85,6 +85,7 @@ ohos_shared_library("distributeddataservice") { "src/kvstore_app_accessor.cpp", "src/kvstore_app_manager.cpp", "src/kvstore_data_service.cpp", + "src/kvstore_device_listener.cpp", "src/kvstore_impl.cpp", "src/kvstore_meta_manager.cpp", "src/kvstore_observer_impl.cpp", diff --git a/services/distributeddataservice/app/src/kvstore_account_observer.cpp b/services/distributeddataservice/app/src/kvstore_account_observer.cpp index d2a1ac589..ae25f382f 100755 --- a/services/distributeddataservice/app/src/kvstore_account_observer.cpp +++ b/services/distributeddataservice/app/src/kvstore_account_observer.cpp @@ -17,6 +17,7 @@ #include "kvstore_account_observer.h" #include +#include "executor_factory.h" #include "kvstore_data_service.h" #include "log_print.h" @@ -26,10 +27,11 @@ std::atomic g_kvStoreAccountEventStatus {0}; void KvStoreAccountObserver::OnAccountChanged(const AccountEventInfo &eventInfo) { ZLOGI("account event %d, begin.", eventInfo.status); - std::thread([this, eventInfo]() { + KvStoreTask task([this, eventInfo]() { ZLOGI("account event processing in thread"); kvStoreDataService_.AccountEventChanged(eventInfo); - }).detach(); + }); + DistributedData::ExecutorFactory::GetInstance().Execute(std::move(task)); ZLOGI("account event %d, end.", eventInfo.status); } } // namespace DistributedKv diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index f48511dc6..f2616e143 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -39,6 +39,7 @@ #include "iservice_registry.h" #include "kvstore_account_observer.h" #include "kvstore_app_accessor.h" +#include "kvstore_device_listener.h" #include "kvstore_meta_manager.h" #include "kvstore_utils.h" #include "log_print.h" @@ -132,7 +133,8 @@ void KvStoreDataService::Initialize() accountEventObserver_ = std::make_shared(*this); AccountDelegate::GetInstance()->Subscribe(accountEventObserver_); - AppDistributedKv::CommunicationProvider::MakeCommunicationProvider()->StartWatchDeviceChange(this, {}); + deviceInnerListener_ = std::make_unique(*this); + KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(deviceInnerListener_.get(), { "innerListener" }); } Status KvStoreDataService::GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId, @@ -1273,14 +1275,8 @@ bool KvStoreDataService::IsStoreOpened(const std::string &userId, const std::str return it != deviceAccountMap_.end() && it->second.IsStoreOpened(appId, storeId); } -void KvStoreDataService::OnDeviceChanged( - const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const +void KvStoreDataService::SetCompatibleIdentify(const AppDistributedKv::DeviceInfo &info) const { - if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { - ZLOGE("ignore device offline"); - return; - } - for (const auto &item : deviceAccountMap_) { item.second.SetCompatibleIdentify(info.deviceId); } @@ -1294,7 +1290,6 @@ bool KvStoreDataService::CheckSyncActivation( // active sync feature with single active user for (const auto &user : users) { if (userId == std::to_string(user.id)) { - return user.isActive; if (!user.isActive) { ZLOGD("the store is not in active user"); return false; diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index 1b668168d..f83c57944 100755 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -17,20 +17,22 @@ #define KVSTORE_DATASERVICE_H #include -#include #include +#include + +#include "account_delegate.h" +#include "backup_handler.h" #include "constant.h" +#include "device_change_listener_impl.h" #include "ikvstore_data_service.h" +#include "kvstore_device_listener.h" #include "kvstore_impl.h" #include "kvstore_user_manager.h" +#include "reporter.h" +#include "security/security.h" #include "single_kvstore_impl.h" #include "system_ability.h" -#include "reporter.h" #include "types.h" -#include "account_delegate.h" -#include "backup_handler.h" -#include "device_change_listener_impl.h" -#include "security/security.h" namespace OHOS::DistributedRdb { class IRdbService; @@ -41,8 +43,7 @@ namespace OHOS::DistributedKv { class KvStoreAccountObserver; class KvStoreDataService : public SystemAbility - , public KvStoreDataServiceStub - , public AppDistributedKv::AppDeviceStatusChangeListener { + , public KvStoreDataServiceStub { DECLARE_SYSTEM_ABILITY(KvStoreDataService); public: @@ -89,6 +90,8 @@ public: void AccountEventChanged(const AccountEventInfo &eventInfo); + void SetCompatibleIdentify(const AppDistributedKv::DeviceInfo &info) const; + bool CheckBackupFileExist(const std::string &userId, const std::string &bundleName, const std::string &storeId, int pathType); @@ -108,6 +111,7 @@ public: Status alreadyCreated = Status::SUCCESS; bool outdated = false; }; + private: class KvStoreClientDeathObserverImpl { public: @@ -172,11 +176,8 @@ private: bool CheckSyncActivation(const std::string &userId, const std::string &appId, const std::string &storeId); bool CheckOptions(const Options &options, const std::vector &metaKey) const; - void OnDeviceChanged( - const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; void CreateRdbService(); bool IsStoreOpened(const std::string &userId, const std::string &appId, const std::string &storeId); - static constexpr int TEN_SEC = 10; std::mutex accountMutex_; @@ -191,6 +192,7 @@ private: std::shared_ptr security_; sptr rdbService_; + std::shared_ptr deviceInnerListener_; }; class DbMetaCallbackDelegateMgr : public DbMetaCallbackDelegate { diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.cpp b/services/distributeddataservice/app/src/kvstore_device_listener.cpp new file mode 100644 index 000000000..2462c7da6 --- /dev/null +++ b/services/distributeddataservice/app/src/kvstore_device_listener.cpp @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define LOG_TAG "KvStoreDeviceListener" +#include "kvstore_device_listener.h" + +#include "kvstore_data_service.h" +#include "log_print.h" + +namespace OHOS::DistributedKv { +void KvStoreDeviceListener::OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const +{ + if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + ZLOGE("ignore device offline"); + return; + } + kvStoreDataService_.SetCompatibleIdentify(info); +} + +KvStoreDeviceListener::KvStoreDeviceListener(KvStoreDataService &kvStoreDataService) + : kvStoreDataService_(kvStoreDataService) +{ +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.h b/services/distributeddataservice/app/src/kvstore_device_listener.h new file mode 100644 index 000000000..09cb733a0 --- /dev/null +++ b/services/distributeddataservice/app/src/kvstore_device_listener.h @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DISTRIBUTEDDATAMGR_KVSTORE_DEVICE_LISTENER_H +#define DISTRIBUTEDDATAMGR_KVSTORE_DEVICE_LISTENER_H +#include "app_device_status_change_listener.h" + +namespace OHOS::DistributedKv { +using AppDeviceStatusChangeListener = AppDistributedKv::AppDeviceStatusChangeListener; +class KvStoreDataService; +class KvStoreDeviceListener : public AppDeviceStatusChangeListener { +public: + explicit KvStoreDeviceListener(KvStoreDataService &kvStoreDataService); + void OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; + +private: + KvStoreDataService &kvStoreDataService_; +}; +} // namespace OHOS::DistributedKv +#endif //DISTRIBUTEDDATAMGR_KVSTORE_DEVICE_LISTENER_H -- Gitee From 8f6bd0821cfc0e370aecc2423773695627bfa9e2 Mon Sep 17 00:00:00 2001 From: illybyy Date: Wed, 2 Mar 2022 11:07:43 +0800 Subject: [PATCH 09/10] test compile Signed-off-by: illybyy --- .../app/src/kvstore_device_listener.h | 2 +- services/distributeddataservice/app/test/BUILD.gn | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.h b/services/distributeddataservice/app/src/kvstore_device_listener.h index 09cb733a0..2c1eee2b3 100644 --- a/services/distributeddataservice/app/src/kvstore_device_listener.h +++ b/services/distributeddataservice/app/src/kvstore_device_listener.h @@ -30,4 +30,4 @@ private: KvStoreDataService &kvStoreDataService_; }; } // namespace OHOS::DistributedKv -#endif //DISTRIBUTEDDATAMGR_KVSTORE_DEVICE_LISTENER_H +#endif // DISTRIBUTEDDATAMGR_KVSTORE_DEVICE_LISTENER_H diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index a14a77e0b..8da274a17 100755 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -61,6 +61,7 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", @@ -128,6 +129,7 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", @@ -195,6 +197,7 @@ ohos_unittest("KvStoreDataServiceTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", @@ -261,6 +264,7 @@ ohos_unittest("KvStoreBackupTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", @@ -361,6 +365,7 @@ ohos_unittest("KvStoreSyncManagerTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", @@ -426,6 +431,7 @@ ohos_unittest("KvStoreUninstallerTest") { "../src/kvstore_app_accessor.cpp", "../src/kvstore_app_manager.cpp", "../src/kvstore_data_service.cpp", + "../src/kvstore_device_listener.cpp", "../src/kvstore_impl.cpp", "../src/kvstore_meta_manager.cpp", "../src/kvstore_observer_impl.cpp", -- Gitee From a84711e9aea54277e25391e7c6b0ce5f7854b5a7 Mon Sep 17 00:00:00 2001 From: illybyy Date: Mon, 7 Mar 2022 11:57:48 +0800 Subject: [PATCH 10/10] bugfix for empty device id procedure Signed-off-by: illybyy --- .../app/src/kvstore_data_service.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index f2616e143..732ca52b1 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -246,8 +246,14 @@ Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId KvStoreAppManager::ConvertPathType(param.uid, param.bundleName, options.securityLevel), store); } if (param.status == Status::SUCCESS) { + status = UpdateMetaData(options, param, keyPara.metaKey, it->second); + if (status != Status::SUCCESS) { + ZLOGE("failed to write meta"); + callback(nullptr); + return status; + } callback(std::move(store)); - return UpdateMetaData(options, param, keyPara.metaKey, it->second); + return status; } param.status = GetSingleKvStoreFailDo(options, param, keyPara, it->second, store); @@ -340,12 +346,17 @@ Status KvStoreDataService::RecoverSecretKey(const Status &alreadyCreated, bool & Status KvStoreDataService::UpdateMetaData(const Options &options, const KvStoreParam &kvParas, const std::vector &metaKey, KvStoreUserManager &kvStoreUserManager) { + auto localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + if (localDeviceId.empty()) { + ZLOGE("failed to get local device id"); + return Status::ERROR; + } KvStoreMetaData metaData; metaData.appId = kvParas.trueAppId; metaData.appType = "harmony"; metaData.bundleName = kvParas.bundleName; metaData.deviceAccountId = kvParas.userId; - metaData.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + metaData.deviceId = localDeviceId; metaData.isAutoSync = options.autoSync; metaData.isBackup = options.backup; metaData.isEncrypt = options.encrypt; @@ -833,7 +844,7 @@ void KvStoreDataService::OnStart() void KvStoreDataService::StartService() { static constexpr int32_t RETRY_TIMES = 10; - static constexpr int32_t RETRY_INTERVAL = 500; // unit is ms + static constexpr int32_t RETRY_INTERVAL = 500 * 1000; // unit is ms for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIMES; ++retry) { if (!DeviceKvStoreImpl::GetLocalDeviceId().empty()) { break; -- Gitee