diff --git a/bundle.json b/bundle.json index c4a0ef434248559bdeba768ca403ef9ca822d0d1..a8a25194b4bf801e80934defffb5103da86d0c76 100644 --- a/bundle.json +++ b/bundle.json @@ -70,7 +70,6 @@ "hitrace", "huks", "kv_store", - "image_framework", "ipc", "memmgr", "napi", @@ -80,12 +79,15 @@ "resource_management", "safwk", "samgr", + "screenlock_mgr", "time_service", "udmf", "app_file_service", "file_api", "openssl", - "json" + "json", + "dmsfwk", + "window_manager" ], "third_party": [ "libuv", @@ -107,6 +109,7 @@ "name": "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", "header": { "header_files": [ + "account/account_delegate.h", "backuprule/backup_rule_manager.h", "checker/checker_manager.h", "cloud/asset_loader.h", @@ -114,6 +117,7 @@ "cloud/cloud_db.h", "cloud/cloud_event.h", "cloud/cloud_info.h", + "cloud/cloud_report.h", "cloud/cloud_server.h", "cloud/schema_meta.h", "cloud/subscription.h", @@ -135,6 +139,7 @@ "metadata/store_meta_data_local.h", "metadata/strategy_meta_data.h", "metadata/user_meta_data.h", + "screen/screen_manager.h", "serializable/serializable.h", "snapshot/bind_event.h", "snapshot/machine_status.h", diff --git a/services/distributeddataservice/adapter/BUILD.gn b/services/distributeddataservice/adapter/BUILD.gn index ae76a3ce05c556d556e10e88c28317866cacb3cd..80c6b4594486d7131bee6316607960501cf5da8e 100644 --- a/services/distributeddataservice/adapter/BUILD.gn +++ b/services/distributeddataservice/adapter/BUILD.gn @@ -51,16 +51,21 @@ ohos_shared_library("distributeddata_adapter") { ubsan = true } sources = [] - + cflags = [ "-D_LIBCPP_HAS_COND_CLOCKWAIT" ] configs = [ ":distributeddata_adapter_private_config" ] deps = [ + "${data_service_path}/adapter/account:distributeddata_account_static", + "${data_service_path}/adapter/communicator:distributeddata_communicator_static", + "${data_service_path}/adapter/dfx:distributeddata_dfx_static", + "${data_service_path}/adapter/permission:distributeddata_permission_static", "${data_service_path}/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/account:distributeddata_account_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/dfx:distributeddata_dfx_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/permission:distributeddata_permission_static", ] + if (defined(global_parts_info) && + defined(global_parts_info.theme_screenlock_mgr)) { + deps += [ "${data_service_path}/adapter/screenlock:distributeddata_screenlock_static" ] + } + external_deps = [ "c_utils:utils", "hilog:libhilog", diff --git a/services/distributeddataservice/adapter/account/BUILD.gn b/services/distributeddataservice/adapter/account/BUILD.gn index 95465797ce4eb1ea4b0382aa0f86e502a09a748b..2bc40d6e4c1560edd1bd02d6e24868b246ae9bdb 100755 --- a/services/distributeddataservice/adapter/account/BUILD.gn +++ b/services/distributeddataservice/adapter/account/BUILD.gn @@ -22,13 +22,10 @@ ohos_static_library("distributeddata_account_static") { boundary_sanitize = true ubsan = true } - sources = [ - "src/account_delegate.cpp", - "src/account_delegate_impl.cpp", - ] + sources = [ "src/account_delegate_impl.cpp" ] include_dirs = [ - "../include/account", + "../../framework/include/account", "../include/autils", "../include/log", "../include/permission", diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp index 7cf335879f4fa11584617f47560f1a91f8f3c6f3..444d7b29986cdc7e7d99098cdd69d7464038aa6b 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp @@ -22,13 +22,7 @@ namespace DistributedKv { namespace { constexpr const char *DEFAULT_OHOS_ACCOUNT_UID = ""; // default UID } - -AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateDefaultImpl::GetBaseInstance; -AccountDelegate *AccountDelegateDefaultImpl::GetBaseInstance() -{ - static AccountDelegateDefaultImpl accountDelegate; - return &accountDelegate; -} +__attribute__((used)) static bool g_isInit = AccountDelegateDefaultImpl::Init(); std::string AccountDelegateDefaultImpl::GetCurrentAccountId() const { @@ -87,5 +81,13 @@ void AccountDelegateDefaultImpl::BindExecutor(std::shared_ptr exec { ZLOGD("no account part"); } -} // namespace DistributedKv + +bool AccountDelegateDefaultImpl::Init() +{ + static AccountDelegateDefaultImpl defaultAccountDelegate; + static std::once_flag onceFlag; + std::call_once(onceFlag, [&]() { AccountDelegate::RegisterAccountInstance(&defaultAccountDelegate); }); + return true; +} +} // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h index 74298cb527cf025187096a84e660cde313f13f3a..04ebda1d6e45fd6e1de5073019b2fad5c0bde08b 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h +++ b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h @@ -21,7 +21,6 @@ namespace OHOS { namespace DistributedKv { class AccountDelegateDefaultImpl final : public AccountDelegateImpl { public: - static AccountDelegate *GetBaseInstance(); std::string GetCurrentAccountId() const override; int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; @@ -31,6 +30,7 @@ public: void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; void BindExecutor(std::shared_ptr executors) override; + static bool Init(); private: ~AccountDelegateDefaultImpl(); diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp index 790d6d548a294644551221491b6e28ada932b961..c99e49d91bd71f407d16e500d2351914ffe4f7bb 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp @@ -32,12 +32,7 @@ using namespace OHOS::EventFwk; using namespace OHOS::AAFwk; using namespace OHOS::DistributedData; using namespace Security::AccessToken; -AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateNormalImpl::GetBaseInstance; -AccountDelegate *AccountDelegateNormalImpl::GetBaseInstance() -{ - static AccountDelegateNormalImpl accountDelegate; - return &accountDelegate; -} +__attribute__((used)) static bool g_isInit = AccountDelegateNormalImpl::Init(); std::string AccountDelegateNormalImpl::GetCurrentAccountId() const { @@ -223,5 +218,13 @@ bool AccountDelegateNormalImpl::QueryForegroundUserId(int &foregroundUserId) } return true; } -} // namespace DistributedKv + +bool AccountDelegateNormalImpl::Init() +{ + static AccountDelegateNormalImpl normalAccountDelegate; + static std::once_flag onceFlag; + std::call_once(onceFlag, [&]() { AccountDelegate::RegisterAccountInstance(&normalAccountDelegate); }); + return true; +} +} // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h index 758e25d4178d5e0a71c7c4434e5507438611c0b8..63c86d66243187fbc4e176f30baf4204194033e7 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h +++ b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h @@ -26,7 +26,6 @@ namespace OHOS { namespace DistributedKv { class AccountDelegateNormalImpl final : public AccountDelegateImpl { public: - static AccountDelegate *GetBaseInstance(); std::string GetCurrentAccountId() const override; int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; @@ -38,6 +37,7 @@ public: void BindExecutor(std::shared_ptr executors) override; std::string GetUnencryptedAccountId(int32_t userId = 0) const override; bool QueryForegroundUserId(int &foregroundUserId) override; + static bool Init(); private: ~AccountDelegateNormalImpl(); diff --git a/services/distributeddataservice/adapter/account/test/BUILD.gn b/services/distributeddataservice/adapter/account/test/BUILD.gn index 1fb62f2e83fa3f2df1de64e589511b4810ffb1fe..3b3df7fe0223d123b0e44b0675d0973c7e385ae6 100755 --- a/services/distributeddataservice/adapter/account/test/BUILD.gn +++ b/services/distributeddataservice/adapter/account/test/BUILD.gn @@ -18,10 +18,13 @@ module_output_path = "datamgr_service/distributeddatafwk" ohos_unittest("AccountDelegateTest") { module_out_path = module_output_path - sources = [ "account_delegate_test.cpp" ] + sources = [ + "${data_service_path}/framework/account/account_delegate.cpp", + "account_delegate_test.cpp", + ] include_dirs = [ "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/account", + "${data_service_path}/framework/include/account", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/autils", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/utils", @@ -51,6 +54,13 @@ ohos_unittest("AccountDelegateTest") { "os_account:libaccountkits", "os_account:os_account_innerkits", ] + if (os_account_part_is_enabled) { + sources += [ "${data_service_path}/adapter/account/src/account_delegate_normal_impl.cpp" ] + cflags_cc = [ "-DOS_ACCOUNT_PART_IS_ENABLED" ] + external_deps += [ "access_token:libaccesstoken_sdk" ] + } else { + sources += [ "${data_service_path}/adapter/account/src/account_delegate_default_impl.cpp" ] + } defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp index c29f60aa3d0be49a40992b09f5594275d52135bc..3820f25fef41ba6a9ec19acfe0022ce0fa48c9c6 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp @@ -43,8 +43,8 @@ AppPipeHandler::AppPipeHandler(const PipeInfo &pipeInfo) softbusAdapter_ = SoftBusAdapter::GetInstance(); } -Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { return softbusAdapter_->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h index 2a2508c5d7da9d6382f33f45acf62e77c6eeaee9..1fddf667b595c8175fb97d3c0ae580d3445bce4a 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h @@ -42,7 +42,7 @@ public: // stop DataChangeListener to watch data change; Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp index f379414703727351e2d30a629af032ce498124c3..8073d0c83587911bdf4c8dc40677266683c0931e 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp @@ -58,13 +58,13 @@ Status AppPipeMgr::StopWatchDataChange(const AppDataChangeListener *observer, co } // Send data to other device, function will be called back after sent to notify send result. -Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { if (dataInfo.length > DataBuffer::MAX_TRANSFER_SIZE || dataInfo.length == 0 || dataInfo.data == nullptr || pipeInfo.pipeId.empty() || deviceId.deviceId.empty()) { ZLOGW("Input is invalid, maxSize:%u, current size:%u", DataBuffer::MAX_TRANSFER_SIZE, dataInfo.length); - return Status::ERROR; + return std::make_pair(Status::ERROR, 0); } ZLOGD("pipeInfo:%s ,size:%u, total length:%u", pipeInfo.pipeId.c_str(), dataInfo.length, totalLength); std::shared_ptr appPipeHandler; @@ -73,7 +73,7 @@ Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, auto it = dataBusMap_.find(pipeInfo.pipeId); if (it == dataBusMap_.end()) { ZLOGW("pipeInfo:%s not found", pipeInfo.pipeId.c_str()); - return Status::KEY_NOT_FOUND; + return std::make_pair(Status::KEY_NOT_FOUND, 0); } appPipeHandler = it->second; } diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h index 222248c5adedd2c20e5d2068e35f35a64bd8ab69..1ffb565995e8607f10317aff649c539c8f0f7b82 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h @@ -36,7 +36,7 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info); // start server Status Start(const PipeInfo &pipeInfo); diff --git a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp index 8b8eb488839d033c53329db8cbee4698410892aa..65869012df1d6c6b6a8cd67e19b568f0b912f3a8 100644 --- a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp @@ -48,8 +48,8 @@ Status CommunicationProviderImpl::StopWatchDataChange(const AppDataChangeListene return appPipeMgr_.StopWatchDataChange(observer, pipeInfo); } -Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { return appPipeMgr_.SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } diff --git a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h index aac05a9fef635d346611bd54164181b8a9099937..5f13ab415ad69f25c80f6cab7d0186cacefbd5cc 100644 --- a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h +++ b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h @@ -36,7 +36,7 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) override; // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) override; // start 1 server to listen data from other devices; diff --git a/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp b/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp index 691b0aed2ad3aac69f4371fa18064de6dc14f0a6..76f63db9f18f27dedcacf9e5f37ec6601c610d08 100644 --- a/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp +++ b/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp @@ -17,6 +17,7 @@ #include "communicator_context.h" #include "log_print.h" #include "kvstore_utils.h" +#include "softbus_error_code.h" namespace OHOS::DistributedData { using KvUtils = OHOS::DistributedKv::KvStoreUtils; @@ -72,28 +73,32 @@ Status CommunicatorContext::UnRegSessionListener(const DevChangeListener *observ return Status::SUCCESS; } -void CommunicatorContext::NotifySessionReady(const std::string &deviceId) +void CommunicatorContext::NotifySessionReady(const std::string &deviceId, int32_t errCode) { if (deviceId.empty()) { ZLOGE("deviceId empty"); return; } - devices_.Insert(deviceId, deviceId); + if (errCode == SOFTBUS_OK) { + devices_.Insert(deviceId, deviceId); + } DeviceInfo devInfo; devInfo.uuid = deviceId; { std::lock_guard lock(mutex_); for (const auto &observer : observers_) { if (observer != nullptr) { - observer->OnSessionReady(devInfo); + observer->OnSessionReady(devInfo, errCode); } } ZLOGI("Notify session begin, deviceId:%{public}s, observer count:%{public}zu", KvUtils::ToBeAnonymous(deviceId).c_str(), observers_.size()); } - std::lock_guard sessionLockGard(sessionMutex_); - if (closeListener_) { - closeListener_(deviceId); + if (errCode == SOFTBUS_OK) { + std::lock_guard sessionLockGard(sessionMutex_); + if (closeListener_) { + closeListener_(deviceId); + } } } diff --git a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index 2de88fc750faab570c47d095b45618a76dbf1fda..b3d43e80a5802190c6a8a7ed77bd43a12536d027 100644 --- a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -139,14 +139,18 @@ DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const const DataInfo dataInfo = { const_cast(data), length}; DeviceId destination; destination.deviceId = dstDevInfo.identifier; - Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); + auto [errCode, softBusErrCode] = + CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); if (errCode == Status::RATE_LIMIT) { - ZLOGD("commProvider_ opening session, status:%{public}d.", static_cast(errCode)); + ZLOGD("commProvider_ opening session, status:%{public}d.", static_cast(softBusErrCode)); return DBStatus::RATE_LIMIT; } if (errCode != Status::SUCCESS) { - ZLOGE("commProvider_ SendData Fail."); - return DBStatus::DB_ERROR; + ZLOGE("commProvider_ SendData Fail. code:%{public}d", softBusErrCode); + if (softBusErrCode == 0) { + return DBStatus::DB_ERROR; + } + return static_cast(softBusErrCode); } return DBStatus::OK; } @@ -221,7 +225,7 @@ void ProcessCommunicatorImpl::OnDeviceChanged(const DeviceInfo &info, const Devi onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); } -void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info) const +void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info, int32_t errCode) const { std::lock_guard lock(sessionMutex_); if (sessionListener_ == nullptr) { @@ -229,7 +233,7 @@ void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info) const } DeviceInfos devInfos; devInfos.identifier = info.uuid; - sessionListener_(devInfos); + sessionListener_(devInfos, errCode); } std::shared_ptr ProcessCommunicatorImpl::GetExtendHeaderHandle(const ExtendInfo &info) diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index a87ff3eb14265c4d462641eec91b5eecd7add9e1..5069b47a2708517073f84903c7e5d91371969d64 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -28,6 +28,7 @@ #include "app_data_change_listener.h" #include "app_device_change_listener.h" #include "block_data.h" +#include "session.h" #include "socket.h" #include "softbus_bus_center.h" #include "softbus_client.h" @@ -52,8 +53,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t length, - const MessageInfo &info); + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t length, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); @@ -65,7 +66,7 @@ public: void NotifyDataListeners(const uint8_t *data, int size, const std::string &deviceId, const PipeInfo &pipeInfo); - std::string OnClientShutdown(int32_t socket); + std::string OnClientShutdown(int32_t socket, bool isForce = true); void OnBind(int32_t socket, PeerSocketInfo info); @@ -83,15 +84,16 @@ public: void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; - private: using Time = std::chrono::steady_clock::time_point; using Duration = std::chrono::steady_clock::duration; using Task = ExecutorPool::Task; - std::string DelConnect(int32_t socket); + std::string DelConnect(int32_t socket, bool isForce); void StartCloseSessionTask(const std::string &deviceId); Task GetCloseSessionTask(); bool CloseSession(const std::string &networkId); + void GetExpireTime(std::shared_ptr &conn); + std::pair OpenConnect(const std::shared_ptr &conn, const DeviceId &deviceId); static constexpr const char *PKG_NAME = "distributeddata-default"; static constexpr Time INVALID_NEXT = std::chrono::steady_clock::time_point::max(); static constexpr uint32_t QOS_COUNT = 3; diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index cdd171392fb4fe4cac929c1303870c1a78a0bacc..7246a043b49525f9c453a4015e6e53892328efe8 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -50,20 +50,21 @@ public: static void OnClientShutdown(int32_t socket, ShutdownReason reason); static void OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen); + static void OnClientSocketChanged(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount); static void OnServerBind(int32_t socket, PeerSocketInfo info); static void OnServerShutdown(int32_t socket, ShutdownReason reason); static void OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen); -public: +private: // notify all listeners when received message static void NotifyDataListeners(const uint8_t *data, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); static std::string GetPipeId(const std::string &name); -private: static SoftBusAdapter *softBusAdapter_; }; + SoftBusAdapter *AppDataListenerWrap::softBusAdapter_; std::shared_ptr SoftBusAdapter::instance_; @@ -95,6 +96,7 @@ SoftBusAdapter::SoftBusAdapter() clientListener_.OnShutdown = AppDataListenerWrap::OnClientShutdown; clientListener_.OnBytes = AppDataListenerWrap::OnClientBytesReceived; clientListener_.OnMessage = AppDataListenerWrap::OnClientBytesReceived; + clientListener_.OnQos = AppDataListenerWrap::OnClientSocketChanged; serverListener_.OnBind = AppDataListenerWrap::OnServerBind; serverListener_.OnShutdown = AppDataListenerWrap::OnServerShutdown; @@ -166,60 +168,73 @@ Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppData return Status::ERROR; } -Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t length, const MessageInfo &info) +void SoftBusAdapter::GetExpireTime(std::shared_ptr &conn) +{ + Time now = std::chrono::steady_clock::now(); + auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now; + lock_guard lock(taskMutex_); + if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) { + taskId_ = Context::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now); + next_ = expireTime; + } +} + +std::pair SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t length, const MessageInfo &info) { std::shared_ptr conn; - bool isReady = DmAdapter::GetInstance().IsDeviceReady(deviceId.deviceId); - uint32_t qosType = isReady ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; - connects_.Compute(deviceId.deviceId, - [&pipeInfo, &deviceId, &conn, qosType](const auto &key, - std::vector> &connects) -> bool { - for (auto &connect : connects) { - if (connect->GetQoSType() == qosType) { - conn = connect; - return true; - } + bool isOHOSType = DmAdapter::GetInstance().IsOHOSType(deviceId.deviceId); + uint32_t qosType = isOHOSType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; + connects_.Compute(deviceId.deviceId, [&pipeInfo, &deviceId, &conn, qosType, isOHOSType](const auto &key, + std::vector> &connects) -> bool { + for (auto &connect : connects) { + if (connect->GetQoSType() == qosType) { + conn = connect; + return true; } - auto connect = std::make_shared(pipeInfo, deviceId, qosType); - connects.emplace_back(connect); - conn = connect; - return true; - }); + } + auto connect = std::make_shared(pipeInfo, deviceId, qosType); + connects.emplace_back(connect); + conn = connect; + return true; + }); if (conn == nullptr) { - return Status::ERROR; + return std::make_pair(Status::ERROR, 0); } auto status = conn->CheckStatus(); if (status == Status::RATE_LIMIT) { - return Status::RATE_LIMIT; + return std::make_pair(Status::RATE_LIMIT, 0); } if (status != Status::SUCCESS) { - auto task = [this, conn]() { - conn->OpenConnect(&clientListener_); - }; - auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId.deviceId).networkId; - ConnectManager::GetInstance()->ApplyConnect(networkId, task); - return Status::RATE_LIMIT; + return OpenConnect(conn, deviceId); } - status = conn->SendData(dataInfo, &clientListener_); if ((status != Status::NETWORK_ERROR) && (status != Status::RATE_LIMIT)) { - Time now = std::chrono::steady_clock::now(); - auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now; - lock_guard lock(taskMutex_); - if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) { - taskId_ = Context::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now); - next_ = expireTime; - } + GetExpireTime(conn); } - return status; + auto errCode = conn->GetSoftBusError(); + return std::make_pair(status, errCode); +} + +std::pair SoftBusAdapter::OpenConnect(const std::shared_ptr &conn, + const DeviceId &deviceId) +{ + auto task = [this, connect = std::weak_ptr(conn)]() { + auto conn = connect.lock(); + if (conn != nullptr) { + conn->OpenConnect(&clientListener_); + } + }; + auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId.deviceId).networkId; + ConnectManager::GetInstance()->ApplyConnect(networkId, task); + return std::make_pair(Status::RATE_LIMIT, 0); } void SoftBusAdapter::StartCloseSessionTask(const std::string &deviceId) { std::shared_ptr conn; - bool isReady = DmAdapter::GetInstance().IsDeviceReady(deviceId); - uint32_t qosType = isReady ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; + bool isOHOSType = DmAdapter::GetInstance().IsOHOSType(deviceId); + uint32_t qosType = isOHOSType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; auto connects = connects_.Find(deviceId); if (!connects.first) { return; @@ -337,11 +352,14 @@ uint32_t SoftBusAdapter::GetTimeout(const DeviceId &deviceId) return interval; } -std::string SoftBusAdapter::DelConnect(int32_t socket) +std::string SoftBusAdapter::DelConnect(int32_t socket, bool isForce) { std::string name; std::set closedConnect; - connects_.EraseIf([socket, &name, &closedConnect](const auto &deviceId, auto &connects) -> bool { + connects_.EraseIf([socket, isForce, &name, &closedConnect](const auto &deviceId, auto &connects) -> bool { + if (!isForce && DmAdapter::GetInstance().IsOHOSType(deviceId)) { + return false; + } for (auto iter = connects.begin(); iter != connects.end();) { if (*iter != nullptr && **iter == socket) { name += deviceId; @@ -364,9 +382,9 @@ std::string SoftBusAdapter::DelConnect(int32_t socket) return name; } -std::string SoftBusAdapter::OnClientShutdown(int32_t socket) +std::string SoftBusAdapter::OnClientShutdown(int32_t socket, bool isForce) { - return DelConnect(socket); + return DelConnect(socket, isForce); } bool SoftBusAdapter::IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, @@ -472,6 +490,14 @@ void AppDataListenerWrap::OnClientShutdown(int32_t socket, ShutdownReason reason void AppDataListenerWrap::OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen) {} +void AppDataListenerWrap::OnClientSocketChanged(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount) +{ + if (eventId == QoSEvent::QOS_SATISFIED && qos != nullptr && qos[0].qos == QOS_TYPE_MIN_BW && qosCount == 1) { + auto name = softBusAdapter_->OnClientShutdown(socket, false); + ZLOGI("[SocketChanged] socket:%{public}d, name:%{public}s", socket, KvStoreUtils::ToBeAnonymous(name).c_str()); + } +} + void AppDataListenerWrap::OnServerBind(int32_t socket, PeerSocketInfo info) { softBusAdapter_->OnBind(socket, info); diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp b/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp index 304b8cd204974fd2da2bac1368c6ea046a50660c..9dfb23b2c525ed2a7dcf6647e5b633f19f649840 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -36,6 +36,7 @@ SoftBusClient::SoftBusClient(const PipeInfo& pipeInfo, const DeviceId& deviceId, SoftBusClient::~SoftBusClient() { + ZLOGI("Shutdown socket:%{public}d", socket_); if (socket_ > 0) { Shutdown(socket_); } @@ -74,12 +75,20 @@ Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener * if (ret != SOFTBUS_OK) { expireTime_ = std::chrono::steady_clock::now(); ZLOGE("send data to socket%{public}d failed, ret:%{public}d.", socket_, ret); + softBusError_ = ret; return Status::ERROR; } + softBusError_ = 0; expireTime_ = CalcExpireTime(); return Status::SUCCESS; } +int32_t SoftBusClient::GetSoftBusError() +{ + std::lock_guard lock(mutex_); + return softBusError_; +} + Status SoftBusClient::OpenConnect(const ISocketListener *listener) { std::lock_guard lock(mutex_); @@ -111,11 +120,10 @@ Status SoftBusClient::OpenConnect(const ISocketListener *listener) ZLOGE("OpenSessionByAsync client is nullptr."); return; } - ZLOGI("Bind Start, socket:%{public}d type:%{public}u", clientSocket, type); - auto status = client->Open(clientSocket, QOS_INFOS[type % QOS_BUTT], listener); - if (status == Status::SUCCESS) { - Context::GetInstance().NotifySessionReady(client->device_.deviceId); - } + ZLOGI("Bind Start, device:%{public}s socket:%{public}d type:%{public}u", + KvStoreUtils::ToBeAnonymous(client->device_.deviceId).c_str(), clientSocket, type); + int32_t status = client->Open(clientSocket, QOS_INFOS[type % QOS_BUTT], listener); + Context::GetInstance().NotifySessionReady(client->device_.deviceId, status); client->isOpening_.store(false); }; Context::GetInstance().GetThreadPool()->Execute(task); @@ -136,7 +144,7 @@ Status SoftBusClient::CheckStatus() return Status::ERROR; } -Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListener *listener) +int32_t SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListener *listener) { int32_t status = ::Bind(socket, qos, QOS_COUNT, listener); ZLOGI("Bind %{public}s,session:%{public}s,socketId:%{public}d", @@ -146,14 +154,15 @@ Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListe ZLOGE("[Bind] device:%{public}s socket failed, session:%{public}s,result:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), status); ::Shutdown(socket); - return Status::NETWORK_ERROR; + return status; } UpdateExpireTime(); uint32_t mtu = 0; std::tie(status, mtu) = GetMtu(socket); if (status != SOFTBUS_OK) { - ZLOGE("GetMtu failed, session:%{public}s, socket:%{public}d", pipe_.pipeId.c_str(), socket_); - return Status::NETWORK_ERROR; + ZLOGE("GetMtu failed, session:%{public}s, socket:%{public}d, status:%{public}d", pipe_.pipeId.c_str(), socket_, + status); + return status; } { std::lock_guard lock(mutex_); @@ -164,7 +173,7 @@ Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListe ZLOGI("open %{public}s, session:%{public}s success, socket:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), socket_); ConnectManager::GetInstance()->OnSessionOpen(DmAdapter::GetInstance().GetDeviceInfo(device_.deviceId).networkId); - return Status::SUCCESS; + return status; } SoftBusClient::Time SoftBusClient::GetExpireTime() const diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/services/distributeddataservice/adapter/communicator/src/softbus_client.h index 8f2b5a0dc6d899ed655006f12ced0a159912e5c4..5e682d726b446d4e7aa93eb9c9e39449700b317a 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -22,6 +22,7 @@ #include "commu_types.h" #include "executor_pool.h" +#include "session.h" #include "socket.h" #include "softbus_bus_center.h" namespace OHOS::AppDistributedKv { @@ -48,9 +49,10 @@ public: int32_t GetSocket() const; uint32_t GetQoSType() const; void UpdateExpireTime(); + int32_t GetSoftBusError(); private: - Status Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); + int32_t Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); std::pair GetMtu(int32_t socket); Time CalcExpireTime() const; @@ -83,6 +85,7 @@ private: int32_t socket_ = INVALID_SOCKET_ID; int32_t bindState_ = -1; + int32_t softBusError_ = 0; }; } // namespace OHOS::AppDistributedKv diff --git a/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp b/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp index 58c8e53401f2abd73da8db1915fc0d9ea0f10f28..6c82c8b7653a06cbe18f5e6132205c9409edbb0f 100644 --- a/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp +++ b/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp @@ -133,8 +133,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider005, TestSize.Level const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di17 = {"127.0.0.2"}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); - EXPECT_NE(status, Status::SUCCESS); + auto status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); + EXPECT_NE(status.first, Status::SUCCESS); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener17, id17); CommunicationProvider::GetInstance().Stop(id17); delete dataListener17; @@ -234,8 +234,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider011, TestSize.Level const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di = {"DeviceId"}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); - EXPECT_EQ(status, Status::ERROR); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -259,8 +259,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider012, TestSize.Level const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di = {""}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); - EXPECT_EQ(status, Status::ERROR); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -282,8 +282,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider013, TestSize.Level CommunicationProvider::GetInstance().Start(id); DeviceId di = {"DeviceId"}; DataInfo data = {nullptr, 0}; - Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); - EXPECT_EQ(status, Status::ERROR); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -307,8 +307,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider014, TestSize.Level const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di = {"DeviceId"}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); - EXPECT_EQ(status, Status::ERROR); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; diff --git a/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp b/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp index 455f5249a1ab34546d853718d2ccd41e1a4948f1..df8207da88f208ef66843313fc907ac653e165db 100644 --- a/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp +++ b/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp @@ -155,8 +155,8 @@ HWTEST_F(SoftbusAdapterStandardTest, SendData, TestSize.Level1) const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di = {"DeviceId"}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = SoftBusAdapter::GetInstance()->SendData(id, di, data, 11, { MessageType::DEFAULT }); - EXPECT_NE(status, Status::SUCCESS); + auto status = SoftBusAdapter::GetInstance()->SendData(id, di, data, 11, { MessageType::DEFAULT }); + EXPECT_NE(status.first, Status::SUCCESS); SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, id); delete dataListener; } diff --git a/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp b/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp index 7c981c90feccad9294ed146569401cf06048adfa..0a22c8f60eaced073e65f35d05dc9c35e68bbfcd 100644 --- a/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp +++ b/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp @@ -49,14 +49,14 @@ void RadarReporter::Report(const RadarParam ¶m, const char *funcName, int32_ BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, BIZ_STATE_LABEL, state, STAGE_RES_LABEL, res, ERROR_CODE_LABEL, param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, - std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.dataChange_); + std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.changeCount); } else { HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, eventName, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, ORG_PKG_LABEL, ORG_PKG, FUNC_LABEL, funcName, BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, STAGE_RES_LABEL, res, ERROR_CODE_LABEL, param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, - std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.dataChange_); + std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.changeCount); } return; } diff --git a/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h b/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h index 8d460299da417f83e7ece492016a321694b21129..94b6b9f83d42f5853f1917cee09b9fda736b2855 100644 --- a/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h +++ b/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h @@ -32,7 +32,7 @@ public: { return ChangeLevelType::HIGH; } - API_EXPORT virtual void OnSessionReady(const DeviceInfo &info) const {} + API_EXPORT virtual void OnSessionReady(const DeviceInfo &info, int32_t errCode) const {} }; } // namespace AppDistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/adapter/include/communicator/communication_provider.h b/services/distributeddataservice/adapter/include/communicator/communication_provider.h index e694ae534cbfbdb9bce57850a62a8a26ee8623f0..94cd0ed4e97324e189e7bfb7204ef3c011810b2a 100644 --- a/services/distributeddataservice/adapter/include/communicator/communication_provider.h +++ b/services/distributeddataservice/adapter/include/communicator/communication_provider.h @@ -45,8 +45,9 @@ public: virtual Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) = 0; // Send data to other device, function will be called back after sent to notify send result - virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info = { MessageType::DEFAULT }) = 0; + virtual std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, + const MessageInfo &info = { MessageType::DEFAULT }) = 0; // start one server to listen data from other devices; virtual Status Start(const PipeInfo &pipeInfo) = 0; diff --git a/services/distributeddataservice/adapter/include/communicator/communicator_context.h b/services/distributeddataservice/adapter/include/communicator/communicator_context.h index a77a2db3afe5b148a8842776aade8929b0707f46..ce09ab58a92c4e58d37bf62b8f497cbb7af93ecb 100644 --- a/services/distributeddataservice/adapter/include/communicator/communicator_context.h +++ b/services/distributeddataservice/adapter/include/communicator/communicator_context.h @@ -36,7 +36,7 @@ public: std::shared_ptr GetThreadPool(); Status RegSessionListener(const DevChangeListener *observer); Status UnRegSessionListener(const DevChangeListener *observer); - void NotifySessionReady(const std::string &deviceId); + void NotifySessionReady(const std::string &deviceId, int32_t errCode); void NotifySessionClose(const std::string &deviceId); void SetSessionListener(const OnCloseAble &closeAbleCallback); bool IsSessionReady(const std::string &deviceId); diff --git a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index ee32d1418fa1a9406ad10427c8cc6607b9d7e7a3..4620c0fc4df645a87f30ea4d3fa7b66eb46fd90d 100644 --- a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -57,7 +57,7 @@ public: std::vector GetRemoteOnlineDeviceInfosList() override; bool IsSameProcessLabelStartedOnPeerDevice(const DeviceInfos &peerDevInfo) override; void OnDeviceChanged(const DeviceInfo &info, const DeviceChangeType &type) const override; - void OnSessionReady(const DeviceInfo &info) const override; + void OnSessionReady(const DeviceInfo &info, int32_t errCode) const override; API_EXPORT std::shared_ptr GetExtendHeaderHandle( const DistributedDB::ExtendInfo &info) override; diff --git a/services/distributeddataservice/adapter/include/dfx/radar_reporter.h b/services/distributeddataservice/adapter/include/dfx/radar_reporter.h index 60a976b92b1954a9a8762479ab8f2c14f836e881..7a60cc064c10ea002fca58f968477249b0e74e31 100644 --- a/services/distributeddataservice/adapter/include/dfx/radar_reporter.h +++ b/services/distributeddataservice/adapter/include/dfx/radar_reporter.h @@ -71,7 +71,7 @@ struct RadarParam { int32_t stage_ = GENERAL_STAGE; uint64_t syncId_ = 0; int32_t triggerMode_ = 0; - bool dataChange_ = false; + uint64_t changeCount = 0; int32_t errCode_ = 0; int32_t res_ = RES_SUCCESS; }; diff --git a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h b/services/distributeddataservice/adapter/include/screenlock/screen_lock.h similarity index 61% rename from services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h rename to services/distributeddataservice/adapter/include/screenlock/screen_lock.h index da098deb1ff316284700c1371e63a2f89eefe608..db40555e3d797bac5d535b459933060907d7274d 100644 --- a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h +++ b/services/distributeddataservice/adapter/include/screenlock/screen_lock.h @@ -12,10 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H +#define DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H -#ifndef CUSTOM_UTD_INSTALLER_FUZZER_H -#define CUSTOM_UTD_INSTALLER_FUZZER_H +#include "visibility.h" +#include "screen/screen_manager.h" -#define FUZZ_PROJECT_NAME "customutdinstaller_fuzzer" - -#endif // CUSTOM_UTD_INSTALLER_FUZZER_H \ No newline at end of file +namespace OHOS { +namespace DistributedData { +class ScreenLock : public ScreenManager { +public: + API_EXPORT bool IsLocked(); +}; +} // namespace DistributedData +} // namespace OHOS +#endif //DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H diff --git a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init b/services/distributeddataservice/adapter/include/utils/visibility.h similarity index 59% rename from services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init rename to services/distributeddataservice/adapter/include/utils/visibility.h index 6198079a28e860189d4294f6598f8ac6804c0dff..a5aec5485e6debf4dbf3ac16e84b701785f638f9 100644 --- a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init +++ b/services/distributeddataservice/adapter/include/utils/visibility.h @@ -13,4 +13,17 @@ * limitations under the License. */ -FUZZ \ No newline at end of file +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_VISIBILITY_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_VISIBILITY_H + +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility ("default"))) +#endif +#ifndef API_LOCAL +#define API_LOCAL __attribute__((visibility ("hidden"))) +#endif +#ifndef KVSTORE_API +#define KVSTORE_API API_EXPORT +#endif + +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_VISIBILITY_H diff --git a/services/distributeddataservice/adapter/screenlock/BUILD.gn b/services/distributeddataservice/adapter/screenlock/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..cb30d1da49819d8bc735ede6017e23100b23ca80 --- /dev/null +++ b/services/distributeddataservice/adapter/screenlock/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +ohos_static_library("distributeddata_screenlock_static") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + boundary_sanitize = true + ubsan = true + } + sources = [ "src/screen_lock.cpp" ] + + cflags_cc = [ "-fvisibility=hidden" ] + + include_dirs = [ + "../include/screenlock", + "../include/utils", + "${data_service_path}/framework/include", + ] + + external_deps = [ + "c_utils:utils", + "screenlock_mgr:screenlock_client", + ] + subsystem_name = "distributeddatamgr" + part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] +} diff --git a/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp b/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a83e2bb49fb0cada46f8fa11e5afeb5163b77dcc --- /dev/null +++ b/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "screen_lock" +#include "screen_lock.h" + +#include "screenlock_manager.h" + +namespace OHOS::DistributedData { +using namespace OHOS::ScreenLock; +__attribute__((used)) static bool g_init = + ScreenManager::RegisterInstance(std::static_pointer_cast(std::make_shared())); +bool ScreenLock::IsLocked() +{ + auto manager = ScreenLockManager::GetInstance(); + if (manager == nullptr) { + return false; + } + return manager->IsScreenLocked(); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index cc59341fc4437a88df48cabd6e25960c1666013f..61a689385968efa39441c94daf08ac873263efd6 100644 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -58,6 +58,7 @@ config("module_private_config") { "${data_service_path}/service/permission/include", "${data_service_path}/service/matrix/include", "${data_service_path}/service/backup/include", + "${data_service_path}/service/app_id_mapping/include", "${data_service_path}/service/kvdb", "${data_service_path}/service/waterversion", "${data_service_path}/service/dumper/include", @@ -69,7 +70,10 @@ config("module_private_config") { "src/backup_rule/include", ] - cflags = [ "-Wno-multichar" ] + cflags = [ + "-Wno-multichar", + "-D_LIBCPP_HAS_COND_CLOCKWAIT", + ] cflags_cc = [ "-fvisibility=hidden" ] } diff --git a/services/distributeddataservice/app/distributed_data.cfg b/services/distributeddataservice/app/distributed_data.cfg index a9e48f7b498d4e214577dbbacc4fae5396c97c6d..65e8ac880c053d0127039baf03f077fdf5034fd0 100644 --- a/services/distributeddataservice/app/distributed_data.cfg +++ b/services/distributeddataservice/app/distributed_data.cfg @@ -17,7 +17,7 @@ "name" : "distributeddata", "path" : ["/system/bin/sa_main","/system/profile/distributeddata.json"], "uid" : "ddms", - "gid" : ["system","shell","readproc","ddms","dfs_share","netsys_socket"], + "gid" : ["system","shell","readproc","ddms","dfs_share","netsys_socket","data_reserve"], "writepid":[ "/dev/cpuset/foreground/tasks", "/dev/stune/foreground/tasks", @@ -31,14 +31,15 @@ "sandbox" : 0, "permission" : [ "ohos.permission.DISTRIBUTED_DATASYNC", + "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS", "ohos.permission.MANAGE_LOCAL_ACCOUNTS", "ohos.permission.ACCESS_SERVICE_DM", "ohos.permission.PROXY_AUTHORIZATION_URI", "ohos.permission.CLOUDFILE_SYNC", "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT", "ohos.permission.GET_BUNDLE_INFO", + "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", "ohos.permission.GET_NETWORK_INFO", - "ohos.permission.INTERNET", "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER", "ohos.permission.MONITOR_DEVICE_NETWORK_STATE", "ohos.permission.USE_CLOUD_DRIVE_SERVICE", diff --git a/services/distributeddataservice/app/src/installer/installer_impl.cpp b/services/distributeddataservice/app/src/installer/installer_impl.cpp index 0ec512f6fe1dd46a6381d4e4a726147de17fb957..98de6baf3058e82e4b990cb20638342d90d2fb54 100644 --- a/services/distributeddataservice/app/src/installer/installer_impl.cpp +++ b/services/distributeddataservice/app/src/installer/installer_impl.cpp @@ -60,10 +60,6 @@ void InstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) int32_t appIndex = want.GetIntParam(SANDBOX_APP_INDEX, 0); ZLOGI("bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); (this->*(it->second))(bundleName, userId, appIndex); - } else if (action == CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) { - int32_t userId = want.GetIntParam(USER_ID, -1); - ZLOGI("user:%{public}d ScreenUnlocked", userId); - OnScreenUnlocked(userId); } } @@ -84,12 +80,14 @@ void InstallEventSubscriber::OnUninstall(const std::string &bundleName, int32_t bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), userId, appIndex); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); - PermitDelegate::GetInstance().DelCache(meta.GetKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); + PermitDelegate::GetInstance().DelCache(meta.GetKey()); } } } @@ -119,11 +117,6 @@ void InstallEventSubscriber::OnInstall(const std::string &bundleName, int32_t us kvStoreDataService_->OnInstall(bundleName, userId, appIndex); } -void InstallEventSubscriber::OnScreenUnlocked(int32_t userId) -{ - kvStoreDataService_->OnScreenUnlocked(userId); -} - InstallerImpl::~InstallerImpl() { ZLOGD("destruct"); @@ -153,7 +146,6 @@ Status InstallerImpl::Init(KvStoreDataService *kvStoreDataService, std::shared_p matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_ADDED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); CommonEventSubscribeInfo info(matchingSkills); auto subscriber = std::make_shared(info, kvStoreDataService); diff --git a/services/distributeddataservice/app/src/installer/installer_impl.h b/services/distributeddataservice/app/src/installer/installer_impl.h index aabcd933ec4039e4ac95513f34c4213f0d3bdb55..683ae72999006e46b2217958bcde2b610796eecf 100644 --- a/services/distributeddataservice/app/src/installer/installer_impl.h +++ b/services/distributeddataservice/app/src/installer/installer_impl.h @@ -36,7 +36,6 @@ private: void OnUninstall(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnUpdate(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnInstall(const std::string &bundleName, int32_t userId, int32_t appIndex); - void OnScreenUnlocked(int32_t userId); std::map callbacks_; KvStoreDataService *kvStoreDataService_; }; diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index 765700f7b934d3f576af5766668ca43f9c6bc78a..e3a753dd8b0dc71c57a592bcb794d20d257cdf31 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -61,6 +61,7 @@ #include "utils/block_integer.h" #include "utils/crypto.h" #include "water_version_manager.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace std::chrono; @@ -136,9 +137,16 @@ void KvStoreDataService::Initialize() meta.bundleName = appIdMeta.bundleName; meta.storeId = info.storeId; meta.user = info.userId; - meta.deviceId = oriDevId; - MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta); - return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true); + std::string uuid; + if (OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(meta.tokenId) == + OHOS::Security::AccessToken::TOKEN_HAP) { + uuid = DmAdapter::GetInstance().CalcClientUuid(meta.appId, oriDevId); + } else { + uuid = DmAdapter::GetInstance().CalcClientUuid(" ", oriDevId); + } + return uuid; }; DBConfig::SetTranslateToDeviceIdCallback(translateCall); } @@ -274,12 +282,7 @@ void KvStoreDataService::OnStart() ZLOGW("GetLocalDeviceId failed, retry count:%{public}d", static_cast(retry)); } ZLOGI("Bootstrap configs and plugins."); - Bootstrap::GetInstance().LoadComponents(); - Bootstrap::GetInstance().LoadDirectory(); - Bootstrap::GetInstance().LoadCheckers(); - Bootstrap::GetInstance().LoadNetworks(); - Bootstrap::GetInstance().LoadBackup(executors_); - Bootstrap::GetInstance().LoadCloud(); + LoadConfigs(); Initialize(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr != nullptr) { @@ -308,6 +311,17 @@ void KvStoreDataService::OnStart() StartService(); } +void KvStoreDataService::LoadConfigs() +{ + Bootstrap::GetInstance().LoadComponents(); + Bootstrap::GetInstance().LoadDirectory(); + Bootstrap::GetInstance().LoadCheckers(); + Bootstrap::GetInstance().LoadNetworks(); + Bootstrap::GetInstance().LoadBackup(executors_); + Bootstrap::GetInstance().LoadCloud(); + Bootstrap::GetInstance().LoadAppIdMappings(); +} + void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) { ZLOGI("add system abilityid:%{public}d", systemAbilityId); @@ -355,12 +369,11 @@ void KvStoreDataService::StartService() // subscribe account event listener to EventNotificationMgr auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -> bool { - auto status = ResolveAutoLaunchParamByIdentifier(identifier, param); features_.ForEachCopies([&identifier, ¶m](const auto &, sptr &value) { value->ResolveAutoLaunch(identifier, param); return false; }); - return status; + return false; }; KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch); ZLOGI("Start distributedata Success, Publish ret: %{public}d", static_cast(ret)); @@ -388,162 +401,6 @@ void KvStoreDataService::OnStoreMetaChanged( ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str()); } -bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( - const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -{ - std::vector entries; - std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) { - ZLOGE("get full meta failed"); - return false; - } - - auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); - for (const auto &storeMeta : entries) { - if ((!param.userId.empty() && (param.userId != storeMeta.user)) || (localDeviceId != storeMeta.deviceId) || - ((StoreMetaData::STORE_RELATIONAL_BEGIN <= storeMeta.storeType) && - (StoreMetaData::STORE_RELATIONAL_END >= storeMeta.storeType))) { - // judge local userid and local meta - continue; - } - const std::string &itemTripleIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(accountId, storeMeta.appId, - storeMeta.storeId, false); - const std::string &itemDualIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); - if (identifier == itemTripleIdentifier && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) { - ResolveAutoLaunchCompatible(storeMeta, identifier, accountId); - } - if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) { - ZLOGI("identifier find"); - DistributedDB::AutoLaunchOption option; - option.createIfNecessary = false; - option.isEncryptedDb = storeMeta.isEncrypt; - - SecretKeyMeta secretKey; - if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) { - std::vector decryptKey; - CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey); - option.passwd.SetValue(decryptKey.data(), decryptKey.size()); - std::fill(decryptKey.begin(), decryptKey.end(), 0); - } - - if (storeMeta.bundleName == Bootstrap::GetInstance().GetProcessLabel()) { - param.userId = storeMeta.user; - } - option.schema = storeMeta.schema; - option.createDirByStoreIdOnly = true; - option.dataDir = storeMeta.dataDir; - option.secOption = 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; -} - -DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLevel) -{ - if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) { - return {DistributedDB::NOT_SET, DistributedDB::ECE}; - } - switch (securityLevel) { - case SecurityLevel::S3: - return {DistributedDB::S3, DistributedDB::SECE}; - case SecurityLevel::S4: - return {DistributedDB::S4, DistributedDB::ECE}; - default: - return {securityLevel, DistributedDB::ECE}; - } -} - -void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, - const std::string &accountId) -{ - if (storeMeta.storeType > KvStoreType::SINGLE_VERSION) { - ZLOGW("no longer support multi or higher version store type"); - return; - } - ZLOGI("AutoLaunch:peer device is old tuple, begin to open store, storeId: %{public}s", - Anonymous::Change(storeMeta.storeId).c_str()); - // open store and SetEqualIdentifier, then close store after 60s - DistributedDB::KvStoreDelegateManager delegateManager(storeMeta.appId, storeMeta.user); - delegateManager.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(storeMeta) }); - Options options = { - .createIfMissing = false, - .encrypt = storeMeta.isEncrypt, - .autoSync = storeMeta.isAutoSync, - .securityLevel = storeMeta.securityLevel, - .kvStoreType = static_cast(storeMeta.storeType), - }; - DistributedDB::KvStoreNbDelegate::Option dbOptions; - SecretKeyMeta secretKey; - if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) { - std::vector decryptKey; - CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey); - std::fill(secretKey.sKey.begin(), secretKey.sKey.end(), 0); - secretKey.sKey = std::move(decryptKey); - std::fill(decryptKey.begin(), decryptKey.end(), 0); - } - InitNbDbOption(options, secretKey.sKey, dbOptions); - DistributedDB::KvStoreNbDelegate *store = nullptr; - delegateManager.GetKvStore(storeMeta.storeId, dbOptions, - [&store, &storeMeta, &accountId](int status, DistributedDB::KvStoreNbDelegate *delegate) { - ZLOGI("temporary open db for equal identifier, ret:%{public}d", status); - if (delegate != nullptr) { - KvStoreTuple tuple = { accountId, storeMeta.appId, storeMeta.storeId }; - UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple); - store = delegate; - } - }); - ExecutorPool::Task delayTask([store]() { - ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied"); - DistributedDB::KvStoreDelegateManager delegateManager("", ""); - delegateManager.CloseKvStore(store); - }); - constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds - executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask)); -} - -Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector &cipherKey, - DistributedDB::KvStoreNbDelegate::Option &dbOption) -{ - DistributedDB::CipherPassword password; - auto status = password.SetValue(cipherKey.data(), cipherKey.size()); - if (status != DistributedDB::CipherPassword::ErrorCode::OK) { - ZLOGE("Failed to set the passwd."); - return Status::DB_ERROR; - } - - dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) - dbOption.createIfNecessary = options.createIfMissing; - dbOption.isMemoryDb = (!options.persistent); - dbOption.isEncryptedDb = options.encrypt; - if (options.encrypt) { - dbOption.cipher = DistributedDB::CipherType::AES_256_GCM; - dbOption.passwd = password; - } - - if (options.kvStoreType == KvStoreType::SINGLE_VERSION) { - dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; - } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) { - dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION; - } else { - ZLOGE("kvStoreType is invalid"); - return Status::INVALID_ARGUMENT; - } - - dbOption.schema = options.schema; - dbOption.createDirByStoreIdOnly = true; - dbOption.secOption = ConvertSecurity(options.securityLevel); - return Status::SUCCESS; -} - void KvStoreDataService::OnStop() { ZLOGI("begin."); @@ -663,10 +520,13 @@ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) ZLOGI("bundleName:%{public}s, user:%{public}s", meta.bundleName.c_str(), meta.user.c_str()); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); - MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); PermitDelegate::GetInstance().DelCache(meta.GetKey()); } g_kvStoreAccountEventStatus = 0; @@ -802,8 +662,9 @@ int32_t KvStoreDataService::OnScreenUnlocked(int32_t user) int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex, int32_t tokenId) { + auto callerToken = IPCSkeleton::GetCallingTokenID(); NativeTokenInfo nativeTokenInfo; - if (AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo) != RET_SUCCESS || + if (AccessTokenKit::GetNativeTokenInfo(callerToken, nativeTokenInfo) != RET_SUCCESS || nativeTokenInfo.processName != FOUNDATION_PROCESS_NAME) { ZLOGE("passed wrong, tokenId: %{public}u, bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", tokenId, bundleName.c_str(), userId, appIndex); @@ -832,10 +693,13 @@ int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32 Anonymous::Change(meta.storeId).c_str(), appIndex); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); PermitDelegate::GetInstance().DelCache(meta.GetKey()); } } diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index ca8c5d7a328789a8c45e22a72188b4cb3cf9b757..981c25cfd0fa76d1aa9ac1a93bdf50ef58922e1f 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -166,12 +166,7 @@ private: Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId); - bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); - void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, - const std::string &accountId); - static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); - static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, - DistributedDB::KvStoreNbDelegate::Option &dbOption); + void LoadConfigs(); static constexpr int TEN_SEC = 10; diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.cpp b/services/distributeddataservice/app/src/kvstore_device_listener.cpp index 1104cfc1299923e4d0fa05451056935c6c6d53bf..65a741b59746a87cd393c4aff58695fe17d831a0 100644 --- a/services/distributeddataservice/app/src/kvstore_device_listener.cpp +++ b/services/distributeddataservice/app/src/kvstore_device_listener.cpp @@ -34,8 +34,9 @@ void KvStoreDeviceListener::OnDeviceChanged( ZLOGI("device is %{public}d", type); } -void KvStoreDeviceListener::OnSessionReady(const AppDistributedKv::DeviceInfo &info) const +void KvStoreDeviceListener::OnSessionReady(const AppDistributedKv::DeviceInfo &info, int32_t errCode) const { + (void)errCode; kvStoreDataService_.OnSessionReady(info); } diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.h b/services/distributeddataservice/app/src/kvstore_device_listener.h index 037c367d163c955a1c2efa22aaa3dcd0b0eb4105..f9ee50585c5f27277cfc3835009d4bb18b64a7ea 100644 --- a/services/distributeddataservice/app/src/kvstore_device_listener.h +++ b/services/distributeddataservice/app/src/kvstore_device_listener.h @@ -26,7 +26,7 @@ public: void OnDeviceChanged( const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; AppDistributedKv::ChangeLevelType GetChangeLevelType() const override; - void OnSessionReady(const AppDistributedKv::DeviceInfo &info) const override; + void OnSessionReady(const AppDistributedKv::DeviceInfo &info, int32_t errCode = 0) const override; private: KvStoreDataService &kvStoreDataService_; diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 31a5fd7611856b56afa115b463dab0abfa6dc9f8..d085aa0f381f053c53b2f462160a3eb7f63dc5b2 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -42,6 +42,7 @@ #include "store/store_info.h" #include "utils/anonymous.h" #include "utils/block_integer.h" +#include "utils/corrupt_reporter.h" #include "utils/crypto.h" #include "utils/ref_count.h" #include "utils/converter.h" @@ -239,7 +240,19 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore() return metaDelegate_; } - metaDelegate_ = CreateMetaKvStore(); + auto metaDbName = Bootstrap::GetInstance().GetMetaDBName(); + if (CorruptReporter::HasCorruptedFlag(metaDBDirectory_, metaDbName)) { + DistributedDB::DBStatus dbStatus = delegateManager_.DeleteKvStore(metaDbName); + if (dbStatus != DistributedDB::DBStatus::OK) { + ZLOGE("delete meta store failed! dbStatus: %{public}d", dbStatus); + } + metaDelegate_ = CreateMetaKvStore(true); + if (metaDelegate_ != nullptr) { + CorruptReporter::DeleteCorruptedFlag(metaDBDirectory_, metaDbName); + } + } else { + metaDelegate_ = CreateMetaKvStore(); + } auto fullName = GetBackupPath(); auto backup = [executors = executors_, queue = std::make_shared>(MAX_TASK_COUNT), fullName]( const auto &store) -> int32_t { @@ -252,7 +265,7 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore() executors->Schedule(std::chrono::hours(RETRY_INTERVAL), GetBackupTask(queue, executors, store)); return OK; }; - MetaDataManager::GetInstance().Initialize(metaDelegate_, backup); + MetaDataManager::GetInstance().Initialize(metaDelegate_, backup, metaDbName); return metaDelegate_; } @@ -270,35 +283,28 @@ ExecutorPool::Task KvStoreMetaManager::GetBackupTask( }; } -KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() +KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore(bool isRestore) { DistributedDB::DBStatus dbStatusTmp = DistributedDB::DBStatus::NOT_SUPPORT; - DistributedDB::KvStoreNbDelegate::Option option; - InitDBOption(option); + auto option = InitDBOption(); DistributedDB::KvStoreNbDelegate *delegate = nullptr; - delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, - [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) { - delegate = nbDelegate; - dbStatusTmp = dbStatus; - }); - - if (dbStatusTmp == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + if (!isRestore) { + delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, + [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) { + delegate = nbDelegate; + dbStatusTmp = dbStatus; + }); + } + if (dbStatusTmp == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB || isRestore) { ZLOGE("meta data corrupted!"); option.isNeedRmCorruptedDb = true; - auto fullName = GetBackupPath(); delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, - [&delegate, &dbStatusTmp, &fullName](DistributedDB::DBStatus dbStatus, + [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) { delegate = nbDelegate; dbStatusTmp = dbStatus; - if (dbStatusTmp == DistributedDB::DBStatus::OK && delegate != nullptr) { - ZLOGI("start to recover meta data"); - DistributedDB::CipherPassword password; - delegate->Import(fullName, password); - } }); } - if (dbStatusTmp != DistributedDB::DBStatus::OK || delegate == nullptr) { ZLOGE("GetKvStore return error status: %{public}d or delegate is nullptr", static_cast(dbStatusTmp)); return nullptr; @@ -311,11 +317,10 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() auto data = static_cast(¶m); delegate->Pragma(DistributedDB::SET_SYNC_RETRY, data); auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) { - ZLOGI("release meta data kv store"); + ZLOGI("release meta data kv store"); if (delegate == nullptr) { return; } - auto result = delegateManager_.CloseKvStore(delegate); if (result != DistributedDB::DBStatus::OK) { ZLOGE("CloseMetaKvStore return error status: %{public}d", static_cast(result)); @@ -324,8 +329,9 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() return NbDelegate(delegate, release); } -void KvStoreMetaManager::InitDBOption(DistributedDB::KvStoreNbDelegate::Option &option) +DistributedDB::KvStoreNbDelegate::Option KvStoreMetaManager::InitDBOption() { + DistributedDB::KvStoreNbDelegate::Option option; option.createIfNecessary = true; option.isMemoryDb = false; option.createDirByStoreIdOnly = true; @@ -335,6 +341,7 @@ void KvStoreMetaManager::InitDBOption(DistributedDB::KvStoreNbDelegate::Option & option.isNeedCompressOnSync = true; option.compressionRate = COMPRESS_RATE; option.secOption = { DistributedDB::S1, DistributedDB::ECE }; + return option; } void KvStoreMetaManager::SetCloudSyncer() @@ -357,17 +364,7 @@ std::function KvStoreMetaManager::CloudSyncTask() std::lock_guard lock(mutex_); delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID; } - auto bundleName = Bootstrap::GetInstance().GetProcessLabel(); - auto storeName = Bootstrap::GetInstance().GetMetaDBName(); DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); - DistributedData::StoreInfo storeInfo; - storeInfo.bundleName = bundleName; - storeInfo.storeName = storeName; - auto mixMode = static_cast(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST, - GeneralStore::AUTO_SYNC_MODE)); - auto info = ChangeEvent::EventInfo(mixMode, 0, true, nullptr, nullptr); - auto evt = std::make_unique(std::move(storeInfo), std::move(info)); - EventCenter::GetInstance().PostEvent(std::move(evt)); }; } diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index 492cc1ffa619753b7083520e1a5004c762a0f1ba..87bcc7162d8ad9f84f9ac437a5cbd233ca119677 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -65,7 +65,7 @@ private: using TaskQueue = std::shared_ptr>; NbDelegate GetMetaKvStore(); - NbDelegate CreateMetaKvStore(); + NbDelegate CreateMetaKvStore(bool isRestore = false); void SetCloudSyncer(); @@ -94,7 +94,7 @@ private: ExecutorPool::Task GetTask(uint32_t retry); - void InitDBOption(DistributedDB::KvStoreNbDelegate::Option &option); + DistributedDB::KvStoreNbDelegate::Option InitDBOption(); static ExecutorPool::Task GetBackupTask( TaskQueue queue, std::shared_ptr executors, const NbDelegate store); 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 5d5dc15e4ccad8a9b7f9917bc1888c35b0b53373..d602b206c82f3f0824c67076fef43e23fad95ba6 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 @@ -34,6 +34,7 @@ using namespace OHOS::DistributedKv; using namespace std::chrono; using DmAdapter = DistributedData::DeviceManagerAdapter; constexpr const int ALIGN_WIDTH = 8; +constexpr const char *DEFAULT_USERID = "0"; std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) { auto handler = std::make_shared(info); @@ -58,6 +59,9 @@ void RouteHeadHandlerImpl::Init() if (deviceId_.empty()) { return; } + if (!DmAdapter::GetInstance().IsOHOSType(deviceId_) && userId_ != DEFAULT_USERID) { + userId_ = DEFAULT_USERID; + } SessionPoint localPoint { DmAdapter::GetInstance().GetLocalDevice().uuid, static_cast(atoi(userId_.c_str())), appId_, storeId_ }; session_ = SessionManager::GetInstance().GetSession(localPoint, deviceId_); @@ -74,15 +78,14 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize ZLOGI("meta data permitted"); return DistributedDB::OK; } - bool flag = false; - auto peerCap = UpgradeManager::GetInstance().GetCapability(session_.targetDeviceId, flag); auto devInfo = DmAdapter::GetInstance().GetDeviceInfo(session_.targetDeviceId); - if (devInfo.osType != OH_OS_TYPE && devInfo.deviceType == - static_cast(DistributedHardware::DmDeviceType::DEVICE_TYPE_CAR)) { - ZLOGI("type car set version. devicdId:%{public}s", Anonymous::Change(session_.targetDeviceId).c_str()); - flag = true; - peerCap.version = CapMetaData::CURRENT_VERSION; + if (devInfo.osType != OH_OS_TYPE) { + ZLOGD("devicdId:%{public}s is not oh type", + Anonymous::Change(session_.targetDeviceId).c_str()); + 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; diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index 0627708fe8570dc0c352860b9ec0b0889ffc2339..4055f30f131ba62cb609b7d17a3bae9ae415bc51 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -23,6 +23,7 @@ #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" #include "utils/constant.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; @@ -86,53 +87,4 @@ bool UpgradeManager::InitLocalCapability() ZLOGI("put capability meta data ret %{public}d", status); return status; } - -void UpgradeManager::GetIdentifierParams(std::vector &devices, - const std::vector &uuids, int32_t authType) -{ - for (const auto &devId : uuids) { - if (DmAdapter::GetInstance().IsOHOSType(devId)) { - continue; - } - if (DmAdapter::GetInstance().GetAuthType(devId) != authType) { - continue; - } - devices.push_back(devId); - } -} - -void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate, - const KvStoreTuple &tuple) -{ - if (storeDelegate == nullptr) { - ZLOGE("null store delegate"); - return; - } - auto uuids = DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()); - if (uuids.empty()) { - ZLOGI("no remote devs"); - return; - } - - std::vector sameAccountDevs {}; - std::vector defaultAccountDevs {}; - GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); - GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); - if (!sameAccountDevs.empty()) { - auto syncIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(tuple.userId, tuple.appId, tuple.storeId); - ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", - Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(tuple.userId).c_str(), - DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); - storeDelegate->SetEqualIdentifier(syncIdentifier, sameAccountDevs); - } - if (!defaultAccountDevs.empty()) { - auto syncIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(defaultAccountId, tuple.appId, tuple.storeId); - ZLOGI("no account set compatible identifier, store:%{public}s, device:%{public}.10s", - Anonymous::Change(tuple.storeId).c_str(), - DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); - storeDelegate->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); - } -} } // 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 index 9fc71a2fd457682a7f7b4097b3b2026f12339a51..411181e38e372792d92b7b4dc7c30b57b9ae4730 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.h +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -32,11 +32,6 @@ public: static UpgradeManager &GetInstance(); void Init(std::shared_ptr executors); CapMetaData GetCapability(const std::string &deviceId, bool &status); - static std::string GetIdentifierByType(int32_t groupType, bool &isSuccess); - static void SetCompatibleIdentifyByType( - KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple); - static void GetIdentifierParams(std::vector &devices, - const std::vector &uuids, int32_t authType); private: static constexpr int RETRY_INTERVAL = 500; // milliseconds @@ -47,7 +42,7 @@ private: static constexpr int32_t NO_ACCOUNT = 0; static constexpr int32_t IDENTICAL_ACCOUNT = 1; - static constexpr const char *defaultAccountId = "default"; + static constexpr const char *defaultAccountId = "ohosAnonymousUid"; }; } // namespace OHOS::DistributedData #endif // DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H diff --git a/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp index e81792321cdec17037ef4b05d8dea317510e9309..25ecbed224a5a44436e2dd4fb5837273487fed23 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp @@ -45,11 +45,8 @@ class KvStoreDataServiceClearTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); - void SetUp(); void TearDown(); - - NativeTokenInfoParams infoInstance {0}; protected: static constexpr const char *TEST_USER = "100"; static constexpr const char *TEST_BUNDLE = "ohos.test.demo"; @@ -57,16 +54,10 @@ protected: static constexpr int32_t TEST_UID = 2000000; static constexpr int32_t TEST_USERID = 100; static constexpr const char *BUNDLE_NAME = "ohos.test.demo"; - static constexpr const char *BUNDLENAME_NO = "com.sample.helloworld"; static constexpr int32_t USER_ID = 100; - static constexpr int32_t USERID_NO = 10; static constexpr int32_t APP_INDEX = 0; - static constexpr int32_t APPINDEX_NO = 2; - static constexpr int32_t INVALID_TOKEN = 222; - DistributedData::StoreMetaData metaData_; DistributedData::StoreMetaDataLocal localMeta_; - void InitMetaData(); }; @@ -80,55 +71,12 @@ void KvStoreDataServiceClearTest::TearDownTestCase(void) void KvStoreDataServiceClearTest::SetUp(void) { - DistributedData::Bootstrap::GetInstance().LoadComponents(); DistributedData::Bootstrap::GetInstance().LoadDirectory(); DistributedData::Bootstrap::GetInstance().LoadCheckers(); - - infoInstance.dcapsNum = 0; - infoInstance.permsNum = 0; - infoInstance.aclsNum = 0; - infoInstance.dcaps = nullptr; - infoInstance.perms = nullptr; - infoInstance.acls = nullptr; - infoInstance.processName = "KvStoreDataServiceClearTest"; - infoInstance.aplStr = "system_core"; - - HapInfoParams info = { - .userID = TEST_USERID, - .bundleName = TEST_BUNDLE, - .instIndex = 0, - .appIDDesc = TEST_BUNDLE - }; - PermissionDef infoManagerTestPermDef = { - .permissionName = "ohos.permission.test", - .bundleName = TEST_BUNDLE, - .grantMode = 1, - .availableLevel = APL_NORMAL, - .label = "label", - .labelId = 1, - .description = "open the door", - .descriptionId = 1 - }; - PermissionStateFull infoManagerTestState = { - .permissionName = "ohos.permission.test", - .isGeneral = true, - .resDeviceID = {"local"}, - .grantStatus = {PermissionState::PERMISSION_GRANTED}, - .grantFlags = {1} - }; - HapPolicyParams policy = { - .apl = APL_NORMAL, - .domain = "test.domain", - .permList = {infoManagerTestPermDef}, - .permStateList = {infoManagerTestState} - }; - AccessTokenKit::AllocHapToken(info, policy); } void KvStoreDataServiceClearTest::TearDown(void) { - auto tokenId = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - AccessTokenKit::DeleteToken(tokenId); } void KvStoreDataServiceClearTest::InitMetaData() @@ -155,7 +103,7 @@ void KvStoreDataServiceClearTest::InitMetaData() /** * @tc.name: ClearAppStorage001 - * @tc.desc: Test that the parameters are entered correctly + * @tc.desc: The parameters are valid but have no metaData * @tc.type: FUNC * @tc.require: * @tc.author: suoqilong @@ -163,49 +111,23 @@ void KvStoreDataServiceClearTest::InitMetaData() HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage001, TestSize.Level1) { auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, INVALID_TOKEN); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLENAME_NO, USER_ID, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USERID_NO, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APPINDEX_NO, tokenIdOk); + auto tokenIdOk = AccessTokenKit::GetNativeTokenId("foundation"); + SetSelfTokenID(tokenIdOk); + auto ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); EXPECT_EQ(ret, Status::ERROR); } /** * @tc.name: ClearAppStorage002 - * @tc.desc: The parameters are valid but have no metaData - * @tc.type: FUNC - * @tc.require: - * @tc.author: suoqilong - */ -HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage002, TestSize.Level1) -{ - auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); -} - -/** - * @tc.name: ClearAppStorage003 * @tc.desc: Test that the cleanup is implemented * @tc.type: FUNC * @tc.require: * @tc.author: suoqilong */ -HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage003, TestSize.Level1) +HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage002, TestSize.Level1) { - auto executors = std::make_shared(12, 5); - // Create an object of the ExecutorPool class and pass 12 and 5 as arguments to the constructor of the class + auto executors = std::make_shared(2, 1); + // Create an object of the ExecutorPool class and pass 2 and 1 as arguments to the constructor of the class KvStoreMetaManager::GetInstance().BindExecutor(executors); KvStoreMetaManager::GetInstance().InitMetaParameter(); DmAdapter::GetInstance().Init(executors); @@ -226,17 +148,17 @@ HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage003, TestSize.Level1) EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.appId, metaData_, true)); EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKeyLocal(), localMeta_, true)); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); + auto tokenIdOk = AccessTokenKit::GetNativeTokenId("foundation"); + SetSelfTokenID(tokenIdOk); auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); + auto ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); + EXPECT_EQ(ret, Status::SUCCESS); - EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKey(), metaData_)); - EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetSecretKey(), metaData_, true)); - EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetStrategyKey(), metaData_)); - EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.appId, metaData_, true)); - EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKeyLocal(), localMeta_, true)); + EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKey(), metaData_)); + EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetSecretKey(), metaData_, true)); + EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetStrategyKey(), metaData_)); + EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.appId, metaData_, true)); + EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKeyLocal(), localMeta_, true)); MetaDataManager::GetInstance().DelMeta(metaData_.GetKey()); EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKey(), metaData_)); diff --git a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp index 581d6f6a00bf26f9a0d7869f011ee1d25778ab57..2d45ffddf7e2ede3e369a613a6f0d50a754213fb 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp @@ -177,57 +177,4 @@ HWTEST_F(KvStoreDataServiceTest, AppExit001, TestSize.Level1) OHOS::DistributedKv::AppId appId = { "ohos.test.kvstoredataservice" }; Status status = kvStoreDataServiceTest.AppExit(uid, pid, token, appId); EXPECT_EQ(status, SUCCESS); -} - -/** -* @tc.name: ResolveAutoLaunchParamByIdentifier001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, ResolveAutoLaunchParamByIdentifier001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - std::string identifier = "kvstoredataservicetest"; - DistributedDB::AutoLaunchParam param; - auto status = kvStoreDataServiceTest.ResolveAutoLaunchParamByIdentifier(identifier, param); - EXPECT_EQ(status, SUCCESS); -} - -/** -* @tc.name: ConvertSecurity001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, ConvertSecurity001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - auto object = kvStoreDataServiceTest.ConvertSecurity(0); - ASSERT_NE(&object, nullptr); -} - -/** -* @tc.name: InitNbDbOption001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, InitNbDbOption001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - DistributedDB::KvStoreNbDelegate::Option dbOption; - Options options = { - .createIfMissing = false, - .encrypt = true, - .autoSync = false, - .securityLevel = 1, - }; - std::vector decryptKey; - DistributedDB::KvStoreNbDelegate::Option dbOptions; - auto status = kvStoreDataServiceTest.InitNbDbOption(options, decryptKey, dbOptions); - EXPECT_EQ(status, SUCCESS); } \ No newline at end of file diff --git a/services/distributeddataservice/app/test/unittest/session_manager_test.cpp b/services/distributeddataservice/app/test/unittest/session_manager_test.cpp index 554891ba8588124854e9f1d80af250e12c48e8d2..96fa8ca77c257a42bb9749b9b1ccc184992b25ec 100644 --- a/services/distributeddataservice/app/test/unittest/session_manager_test.cpp +++ b/services/distributeddataservice/app/test/unittest/session_manager_test.cpp @@ -93,6 +93,7 @@ public: StoreMetaData metaData; metaData.bundleName = "ohos.test.demo"; + metaData.appId = "ohos.test.demo"; metaData.storeId = "test_store"; metaData.user = "100"; metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -110,6 +111,7 @@ public: MetaDataManager::GetInstance().DelMeta(std::string(peerCapMetaKey.begin(), peerCapMetaKey.end())); StoreMetaData metaData; metaData.bundleName = "ohos.test.demo"; + metaData.appId = "ohos.test.demo"; metaData.storeId = "test_store"; metaData.user = "100"; metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -142,7 +144,7 @@ HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level2) ASSERT_NE(sendHandler, nullptr); uint32_t routeHeadSize = 0; sendHandler->GetHeadDataSize(routeHeadSize); - ASSERT_GT(routeHeadSize, 0); + ASSERT_EQ(routeHeadSize, 0); std::unique_ptr data = std::make_unique(routeHeadSize); sendHandler->FillHeadData(data.get(), routeHeadSize, routeHeadSize); @@ -152,7 +154,6 @@ HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level2) uint32_t parseSize = 1; recvHandler->ParseHeadData(data.get(), routeHeadSize, parseSize, users); EXPECT_EQ(routeHeadSize, parseSize); - ASSERT_EQ(users.size(), 1); - EXPECT_EQ(users[0], "100"); + ASSERT_EQ(users.size(), 0); } } // namespace \ No newline at end of file diff --git a/services/distributeddataservice/framework/BUILD.gn b/services/distributeddataservice/framework/BUILD.gn index 99934dbfd2bce6104239f58f8f50ef51f6f61a41..f9329d03144231017598773f4d1c0d9df5442bed 100644 --- a/services/distributeddataservice/framework/BUILD.gn +++ b/services/distributeddataservice/framework/BUILD.gn @@ -33,6 +33,7 @@ config("module_public_config") { visibility = [ ":*" ] include_dirs = [ "include", + "${data_service_path}/framework/include/account", "${kv_store_common_path}", ] } @@ -47,6 +48,8 @@ ohos_shared_library("distributeddatasvcfwk") { debug = false } sources = [ + "account/account_delegate.cpp", + "app_id_mapping/app_id_mapping_config_manager.cpp", "backuprule/backup_rule_manager.cpp", "changeevent/remote_change_event.cpp", "checker/checker_manager.cpp", @@ -56,6 +59,8 @@ ohos_shared_library("distributeddatasvcfwk") { "cloud/cloud_event.cpp", "cloud/cloud_extra_data.cpp", "cloud/cloud_info.cpp", + "cloud/cloud_lock_event.cpp", + "cloud/cloud_report.cpp", "cloud/cloud_server.cpp", "cloud/cloud_share_event.cpp", "cloud/cloud_sync_finished_event.cpp", @@ -81,12 +86,14 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/meta_data.cpp", "metadata/meta_data_manager.cpp", "metadata/secret_key_meta_data.cpp", + "metadata/store_debug_info.cpp", "metadata/store_meta_data.cpp", "metadata/store_meta_data_local.cpp", "metadata/strategy_meta_data.cpp", "metadata/switches_meta_data.cpp", "metadata/user_meta_data.cpp", "metadata/version_meta_data.cpp", + "screen/screen_manager.cpp", "serializable/serializable.cpp", "snapshot/bind_event.cpp", "snapshot/snapshot.cpp", @@ -95,10 +102,14 @@ ohos_shared_library("distributeddatasvcfwk") { "utils/block_integer.cpp", "utils/constant.cpp", "utils/converter.cpp", + "utils/corrupt_reporter.cpp", "utils/crypto.cpp", "utils/ref_count.cpp", ] - cflags = [ "-Wno-multichar" ] + cflags = [ + "-Wno-multichar", + "-D_LIBCPP_HAS_COND_CLOCKWAIT", + ] cflags_cc = [ "-fvisibility=hidden" ] diff --git a/services/distributeddataservice/adapter/account/src/account_delegate.cpp b/services/distributeddataservice/framework/account/account_delegate.cpp similarity index 63% rename from services/distributeddataservice/adapter/account/src/account_delegate.cpp rename to services/distributeddataservice/framework/account/account_delegate.cpp index 17737f1e5bee6c5aa9a25d7a689ef2424013f90a..1734d6541b80be85e2bbb28e63018590ba27242f 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate.cpp +++ b/services/distributeddataservice/framework/account/account_delegate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,16 +13,24 @@ * limitations under the License. */ -#include "account_delegate_impl.h" +#include "account_delegate.h" namespace OHOS { namespace DistributedKv { -AccountDelegate *AccountDelegate::GetInstance() +AccountDelegate *AccountDelegate::instance_ = nullptr; + +bool AccountDelegate::RegisterAccountInstance(AccountDelegate *instance) { - if (getInstance_ == nullptr) { - return nullptr; + if (instance_ != nullptr) { + return false; } - return getInstance_(); + instance_ = instance; + return true; +} + +AccountDelegate *AccountDelegate::GetInstance() +{ + return instance_; } -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp b/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d03d5246261b7ba873aa408d3454edf801dd335 --- /dev/null +++ b/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AppIdMappingConfigManager" +#include "app_id_mapping/app_id_mapping_config_manager.h" + +namespace OHOS::DistributedData { +AppIdMappingConfigManager &AppIdMappingConfigManager::GetInstance() +{ + static AppIdMappingConfigManager instance; + return instance; +} + +void AppIdMappingConfigManager::Initialize(const std::vector &mapper) +{ + for (const auto &info : mapper) { + toDstMapper_.insert_or_assign(info.srcAppId, info.dstAppId); + } +} + +std::pair AppIdMappingConfigManager::Convert(const std::string &appId, + const std::string &accountId) +{ + auto it = toDstMapper_.find(appId); + if (it == toDstMapper_.end()) { + return std::make_pair(appId, accountId); + } + return std::make_pair(it->second, "default"); +} + +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/asset_loader.cpp b/services/distributeddataservice/framework/cloud/asset_loader.cpp index 70c1b677b4b669d8d35b74184b681272907d2ae6..711879f758e757d1d0951bd05ea71a9a6d7486da 100644 --- a/services/distributeddataservice/framework/cloud/asset_loader.cpp +++ b/services/distributeddataservice/framework/cloud/asset_loader.cpp @@ -25,4 +25,8 @@ int32_t AssetLoader::RemoveLocalAssets(const std::string &tableName, const std:: { return E_NOT_SUPPORT; } +int32_t AssetLoader::Cancel() +{ + return E_NOT_SUPPORT; +} } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/cloud/cloud_db.cpp b/services/distributeddataservice/framework/cloud/cloud_db.cpp index 0e3c2a4c607d79173d4e437cea11c2c61336741c..0e579a28a5bd16a95ea3bb79cbb9ce011d2e1589 100644 --- a/services/distributeddataservice/framework/cloud/cloud_db.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_db.cpp @@ -99,4 +99,10 @@ std::pair CloudDB::GetEmptyCursor(const std::string &table { return { E_NOT_SUPPORT, "" }; } + +void CloudDB::SetPrepareTraceId(const std::string &prepareTraceId) +{ + (void)prepareTraceId; + return; +} } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/cloud/cloud_event.cpp b/services/distributeddataservice/framework/cloud/cloud_event.cpp index bfaf3c9eb16bf519dc41416ba55176eede336adc..701bce29cfc04cf90646f386c1dfeb254632c579 100644 --- a/services/distributeddataservice/framework/cloud/cloud_event.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_event.cpp @@ -17,7 +17,7 @@ namespace OHOS::DistributedData { CloudEvent::CloudEvent(int32_t evtId, StoreInfo storeInfo) - : Event(evtId), storeInfo_(std::move(storeInfo)) + : Event(evtId), eventId_(evtId), storeInfo_(std::move(storeInfo)) { } @@ -25,4 +25,9 @@ const StoreInfo& CloudEvent::GetStoreInfo() const { return storeInfo_; } + +int32_t CloudEvent::GetEventId() const +{ + return eventId_; +} } \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/cloud_extra_data.cpp b/services/distributeddataservice/framework/cloud/cloud_extra_data.cpp index 2527c69f1e98a96054b440468db6323cca0925db..82c5341fa4c8861112b3769568635189bd38ae7a 100644 --- a/services/distributeddataservice/framework/cloud/cloud_extra_data.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_extra_data.cpp @@ -12,11 +12,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "cloud/cloud_extra_data.h" #include "cloud/cloud_config_manager.h" namespace OHOS::DistributedData { +bool Context::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(traceId)], traceId); + SetValue(node[GET_NAME(prepareTraceId)], prepareTraceId); + return true; +} + +bool Context::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(traceId), traceId); + GetValue(node, GET_NAME(prepareTraceId), prepareTraceId); + return true; +} + bool ExtensionInfo::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(accountId)], accountId); @@ -38,7 +51,15 @@ bool ExtensionInfo::Unmarshal(const Serializable::json &node) return false; } GetValue(node, GET_NAME(recordTypes), recordTypes); - return Unmarshall(recordTypes, tables); + if (!Unmarshall(recordTypes, tables)) { + return false; + } + std::string data; + GetValue(node, GET_NAME(context), data); + if (data.empty()) { + return true; + } + return context.Unmarshall(data); } bool ExtraData::Marshal(Serializable::json &node) const diff --git a/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp b/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0bf9a1ad79953e6d62cd28bd48b2dece6a6cd8f --- /dev/null +++ b/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "cloud/cloud_lock_event.h" + +namespace OHOS::DistributedData { +CloudLockEvent::CloudLockEvent(int32_t evtId, StoreInfo storeInfo, Callback callback) + :CloudEvent(evtId, storeInfo), callback_(std::move(callback)) +{ +} +CloudLockEvent::Callback CloudLockEvent::GetCallback() const +{ + return callback_; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp b/services/distributeddataservice/framework/cloud/cloud_report.cpp similarity index 41% rename from services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp rename to services/distributeddataservice/framework/cloud/cloud_report.cpp index 36670b42e800a5e2271154971fb033149fd618e6..34e44bc20d9faa5b2c50cdad97e555f4252fe422 100644 --- a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_report.cpp @@ -13,45 +13,37 @@ * limitations under the License. */ -#include "customutdinstaller_fuzzer.h" -#include -#include +#include "cloud/cloud_report.h" -#include "ipc_skeleton.h" -#include "custom_utd_installer.h" -#include "message_parcel.h" -#include "securec.h" +namespace OHOS::DistributedData { +CloudReport *CloudReport::instance_ = nullptr; -using namespace OHOS::UDMF; - -namespace OHOS { - -bool InstallUtdFuzz(const uint8_t* data, size_t size) +CloudReport *CloudReport::GetInstance() { - int32_t user = static_cast(*data); - std::string bundleName(reinterpret_cast(data), size); - CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); - return true; + return instance_; } -bool UninstallUtdFuzz(const uint8_t* data, size_t size) +bool CloudReport::RegisterCloudReportInstance(CloudReport *instance) { - int32_t user = static_cast(*data); - std::string bundleName(reinterpret_cast(data), size); - CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); + if (instance_ != nullptr) { + return false; + } + instance_ = instance; return true; } -} -/* Fuzzer entry point */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +std::string CloudReport::GetPrepareTraceId(int32_t userId) { - if (data == nullptr) { - return 0; - } + return ""; +} - OHOS::InstallUtdFuzz(data, size); - OHOS::UninstallUtdFuzz(data, size); +std::string CloudReport::GetRequestTraceId(int32_t userId) +{ + return ""; +} - return 0; -} \ No newline at end of file +bool CloudReport::Report(const ReportParam &reportParam) +{ + return true; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/sync_event.cpp b/services/distributeddataservice/framework/cloud/sync_event.cpp index f2c78e6c34e8b67735832ffe3d76785644c7f585..2d1dc05f6486711d27fce1827aa96a9fc99eaa55 100644 --- a/services/distributeddataservice/framework/cloud/sync_event.cpp +++ b/services/distributeddataservice/framework/cloud/sync_event.cpp @@ -20,9 +20,11 @@ SyncEvent::EventInfo::EventInfo(int32_t mode, int32_t wait, bool retry, std::sha : retry_(retry), mode_(mode), wait_(wait), query_(std::move(query)), asyncDetail_(std::move(async)) { } + SyncEvent::EventInfo::EventInfo(const SyncParam &syncParam, bool retry, std::shared_ptr query, GenAsync async) : retry_(retry), mode_(syncParam.mode), wait_(syncParam.wait), query_(std::move(query)), - asyncDetail_(std::move(async)), isCompensation_(syncParam.isCompensation), triggerMode_(syncParam.triggerMode) + asyncDetail_(std::move(async)), isCompensation_(syncParam.isCompensation), triggerMode_(syncParam.triggerMode), + prepareTraceId_(syncParam.prepareTraceId), user_(syncParam.user) { } @@ -43,6 +45,8 @@ SyncEvent::EventInfo &SyncEvent::EventInfo::operator=(SyncEvent::EventInfo &&inf asyncDetail_ = std::move(info.asyncDetail_); isCompensation_ = info.isCompensation_; triggerMode_ = info.triggerMode_; + prepareTraceId_ = info.prepareTraceId_; + user_ = info.user_; return *this; } @@ -90,4 +94,14 @@ int32_t SyncEvent::GetTriggerMode() const { return info_.triggerMode_; } + +std::string SyncEvent::GetPrepareTraceId() const +{ + return info_.prepareTraceId_; +} + +int32_t SyncEvent::GetUser() const +{ + return info_.user_; +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/directory/directory_manager.cpp b/services/distributeddataservice/framework/directory/directory_manager.cpp index 6c541df7f1b3677763ccfe9021cdaa64697b2101..4007e37e3c101d50ce9d51fb4c876b8f7c2da15f 100644 --- a/services/distributeddataservice/framework/directory/directory_manager.cpp +++ b/services/distributeddataservice/framework/directory/directory_manager.cpp @@ -158,7 +158,7 @@ std::string DirectoryManager::GetArea(const StoreMetaData &metaData) const std::string DirectoryManager::GetUserId(const StoreMetaData &metaData) const { auto type = AccessTokenKit::GetTokenTypeFlag(metaData.tokenId); - if (type == TOKEN_NATIVE || type == TOKEN_SHELL) { + if ((type == TOKEN_NATIVE || type == TOKEN_SHELL) && (metaData.user == StoreMetaData::ROOT_USER)) { return "public"; } return metaData.user; @@ -169,7 +169,7 @@ std::string DirectoryManager::GetBundleName(const StoreMetaData &metaData) const if (metaData.instanceId == 0) { return metaData.bundleName; } - return metaData.bundleName + "_" + std::to_string(metaData.instanceId); + return "+clone-" + std::to_string(metaData.instanceId) + "+" + metaData.bundleName; } std::string DirectoryManager::GetHapName(const StoreMetaData &metaData) const diff --git a/services/distributeddataservice/adapter/include/account/account_delegate.h b/services/distributeddataservice/framework/include/account/account_delegate.h similarity index 82% rename from services/distributeddataservice/adapter/include/account/account_delegate.h rename to services/distributeddataservice/framework/include/account/account_delegate.h index 4c6458158d39809e891642f80c566b7e2b0bae64..41d2e98566e441dcca1ed7d69d0565729a606994 100644 --- a/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/services/distributeddataservice/framework/include/account/account_delegate.h @@ -16,8 +16,9 @@ #ifndef DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H #define DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H -#include #include +#include + #include "executor_pool.h" #include "types.h" #include "visibility.h" @@ -26,11 +27,11 @@ namespace OHOS { namespace DistributedKv { enum class AccountStatus { HARMONY_ACCOUNT_LOGIN = 0, // the openHarmony account is logged in - 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 - DEVICE_ACCOUNT_UNLOCKED, // the device account is unlocked + 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 + DEVICE_ACCOUNT_UNLOCKED, // the device account is unlocked }; struct AccountEventInfo { @@ -54,7 +55,7 @@ public: API_EXPORT virtual std::string Name() = 0; API_EXPORT virtual LevelType GetLevel() = 0; }; - using HashFunc = std::string(*)(const void *data, size_t size, bool isUpper); + using HashFunc = std::string (*)(const void *data, size_t size, bool isUpper); API_EXPORT virtual ~AccountDelegate() = default; API_EXPORT virtual Status Subscribe(std::shared_ptr observer) = 0; API_EXPORT virtual Status Unsubscribe(std::shared_ptr observer) = 0; @@ -64,18 +65,18 @@ public: API_EXPORT virtual void UnsubscribeAccountEvent() = 0; API_EXPORT virtual bool QueryUsers(std::vector &users) = 0; API_EXPORT virtual bool QueryForegroundUsers(std::vector &users) = 0; - API_EXPORT virtual bool IsLoginAccount() = 0; API_EXPORT virtual bool QueryForegroundUserId(int &foregroundUserId) = 0; + API_EXPORT virtual bool IsLoginAccount() = 0; API_EXPORT virtual bool IsVerified(int userId) = 0; API_EXPORT virtual bool RegisterHashFunc(HashFunc hash) = 0; API_EXPORT virtual void BindExecutor(std::shared_ptr executors) = 0; API_EXPORT virtual std::string GetUnencryptedAccountId(int32_t userId = 0) const = 0; API_EXPORT static AccountDelegate *GetInstance(); + API_EXPORT static bool RegisterAccountInstance(AccountDelegate *instance); private: - using BaseInstance = AccountDelegate *(*)(); - static BaseInstance getInstance_; + static AccountDelegate *instance_; }; -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS #endif // DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h b/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..9799f9af673fa969a71d9d01cf57b249b6b09592 --- /dev/null +++ b/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H +#include +#include +#include +#include "visibility.h" +namespace OHOS { +namespace DistributedData { +class AppIdMappingConfigManager { +public: + struct AppMappingInfo { + std::string srcAppId; + std::string dstAppId; + }; + API_EXPORT static AppIdMappingConfigManager &GetInstance(); + API_EXPORT void Initialize(const std::vector &mapper); + API_EXPORT std::pair Convert(const std::string &appId, + const std::string &accountId); + +private: + std::map toDstMapper_; +}; + +} // namespace DistributedData +} // namespace OHOS +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H diff --git a/services/distributeddataservice/framework/include/changeevent/remote_change_event.h b/services/distributeddataservice/framework/include/changeevent/remote_change_event.h index 8236df1b429e76c7c73768e2152762389bb24741..aa6ca90dcb8f62a48310b321053719c4d0356c0b 100644 --- a/services/distributeddataservice/framework/include/changeevent/remote_change_event.h +++ b/services/distributeddataservice/framework/include/changeevent/remote_change_event.h @@ -34,6 +34,7 @@ public: std::string deviceId; std::string bundleName; std::vector tables; + int changeType = 0; // 0 means CLOUD_DATA_CHANGE }; RemoteChangeEvent(int32_t evtId, DataInfo&& info); diff --git a/services/distributeddataservice/framework/include/cloud/asset_loader.h b/services/distributeddataservice/framework/include/cloud/asset_loader.h index 6ea12ffff1cada7f1414520ddb974545d55294ed..fc9dcdcc4c8b8a51727719643d01b04fbde23e7f 100644 --- a/services/distributeddataservice/framework/include/cloud/asset_loader.h +++ b/services/distributeddataservice/framework/include/cloud/asset_loader.h @@ -26,6 +26,7 @@ public: VBucket &assets); virtual int32_t RemoveLocalAssets(const std::string &tableName, const std::string &gid, const Value &prefix, VBucket &assets); + virtual int32_t Cancel(); }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_db.h b/services/distributeddataservice/framework/include/cloud/cloud_db.h index 6927a277a20fdcf004960657e8d778e9c8c732ba..a6818dbb5473055590eb40b4dc22feffe3f6165d 100644 --- a/services/distributeddataservice/framework/include/cloud/cloud_db.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_db.h @@ -63,6 +63,8 @@ public: virtual int32_t Close(); virtual std::pair GetEmptyCursor(const std::string &tableName); + + virtual void SetPrepareTraceId(const std::string &prepareTraceId); }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_DB_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_event.h b/services/distributeddataservice/framework/include/cloud/cloud_event.h index 0ac070ad609a5f1731da69ace445f0b33adf2d40..0c2507a0421f4ce6e16216c8dfaf61dcf8071fed 100644 --- a/services/distributeddataservice/framework/include/cloud/cloud_event.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_event.h @@ -27,21 +27,28 @@ public: FEATURE_INIT = EVT_CLOUD, GET_SCHEMA, LOCAL_CHANGE, + CLEAN_DATA, CLOUD_SYNC, DATA_CHANGE, + SET_SEARCHABLE, CLOUD_SHARE, MAKE_QUERY, CLOUD_SYNC_FINISHED, DATA_SYNC, + LOCK_CLOUD_CONTAINER, + UNLOCK_CLOUD_CONTAINER, + SET_SEARCH_TRIGGER, CLOUD_BUTT }; CloudEvent(int32_t evtId, StoreInfo storeInfo); ~CloudEvent() = default; const StoreInfo& GetStoreInfo() const; + int32_t GetEventId() const; private: + int32_t eventId_; StoreInfo storeInfo_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H \ No newline at end of file +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_extra_data.h b/services/distributeddataservice/framework/include/cloud/cloud_extra_data.h index c4d89192a57f39d65d96d2f0f65349b20a86c803..2d96d4951a2c4af290224fbc02ad5edbaf276c0b 100644 --- a/services/distributeddataservice/framework/include/cloud/cloud_extra_data.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_extra_data.h @@ -20,6 +20,14 @@ #include "serializable/serializable.h" namespace OHOS::DistributedData { +class API_EXPORT Context final : public Serializable { +public: + std::string traceId; + std::string prepareTraceId; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; + class API_EXPORT ExtensionInfo final : public Serializable { public: std::string accountId; @@ -29,6 +37,7 @@ public: std::vector scopes; std::string recordTypes; std::vector tables; + Context context; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; diff --git a/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h b/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h new file mode 100644 index 0000000000000000000000000000000000000000..cbced1b0324d1f5046b263c1ddeed1af5ad1e8f4 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H +#include "cloud/cloud_event.h" +#include "store/general_value.h" +#include "store/general_store.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +class API_EXPORT CloudLockEvent : public CloudEvent { +public: + using Callback = std::function; + CloudLockEvent(int32_t evtId, StoreInfo storeInfo, Callback callback); + ~CloudLockEvent() override = default; + Callback GetCallback() const; +private: + Callback callback_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/cloud/cloud_report.h b/services/distributeddataservice/framework/include/cloud/cloud_report.h new file mode 100644 index 0000000000000000000000000000000000000000..5b1a19e8e98bc63e5d77fc6cf97f62cbbe0ff82f --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/cloud_report.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_REPORT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_REPORT_H + +#include "store/general_value.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +class API_EXPORT CloudReport { +public: + using ReportParam = DistributedData::ReportParam; + API_EXPORT static CloudReport *GetInstance(); + API_EXPORT static bool RegisterCloudReportInstance(CloudReport *instance); + virtual std::string GetPrepareTraceId(int32_t userId); + virtual std::string GetRequestTraceId(int32_t userId); + virtual bool Report(const ReportParam &reportParam); + +private: + static CloudReport *instance_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_REPORT_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/cloud/sync_event.h b/services/distributeddataservice/framework/include/cloud/sync_event.h index 22a06c077f1d891121c71d1278b2462dad24349e..8d73a0f076707ddbd2dc275440296a23f067071e 100644 --- a/services/distributeddataservice/framework/include/cloud/sync_event.h +++ b/services/distributeddataservice/framework/include/cloud/sync_event.h @@ -38,6 +38,8 @@ public: GenAsync asyncDetail_; bool isCompensation_ = false; int32_t triggerMode_ = MODE_DEFAULT; + std::string prepareTraceId_; + int32_t user_ = 0; }; SyncEvent(StoreInfo storeInfo, EventInfo info); ~SyncEvent() override = default; @@ -48,6 +50,8 @@ public: GenAsync GetAsyncDetail() const; bool IsCompensation() const; int32_t GetTriggerMode() const; + std::string GetPrepareTraceId() const; + int32_t GetUser() const; protected: SyncEvent(int32_t evtId, StoreInfo storeInfo, EventInfo info); diff --git a/services/distributeddataservice/framework/include/commonevent/data_change_event.h b/services/distributeddataservice/framework/include/commonevent/data_change_event.h index be3970cdf26bccc83eb53587e9b60d24c7d9553f..d66482886b232bf3715f5073b8347b9a4b5f2b84 100644 --- a/services/distributeddataservice/framework/include/commonevent/data_change_event.h +++ b/services/distributeddataservice/framework/include/commonevent/data_change_event.h @@ -27,6 +27,7 @@ public: using TableProperties = std::map; struct EventInfo { TableProperties tableProperties; + bool isFull; }; DataChangeEvent(StoreInfo storeInfo, EventInfo evtInfo) @@ -40,6 +41,11 @@ public: { return info_.tableProperties; } + + bool IsFull() const + { + return info_.isFull; + } private: EventInfo info_; }; diff --git a/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h b/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h new file mode 100644 index 0000000000000000000000000000000000000000..14e0f0bc05eb581ed4a58b7784dac8805be8cf52 --- /dev/null +++ b/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H + +#include "cloud/cloud_event.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT SetSearchableEvent : public CloudEvent { +public: + struct EventInfo { + bool isSearchable; + bool isRebuild; + }; + + SetSearchableEvent(StoreInfo storeInfo, EventInfo evtInfo, int32_t evtId = SET_SEARCHABLE) + : CloudEvent(evtId, std::move(storeInfo)), info_(std::move(evtInfo)) + { + } + + ~SetSearchableEvent() override = default; + + bool GetIsSearchabl() const + { + return info_.isSearchable; + } + + bool GetIsRebuild() const + { + return info_.isRebuild; + } +private: + EventInfo info_; +}; +} // OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/error/general_error.h b/services/distributeddataservice/framework/include/error/general_error.h index 25c3cdf861df2ae428d4919c96bb66704375fcf4..f798cecfceb7cb07164ccbcb8b90f63fa41117bc 100644 --- a/services/distributeddataservice/framework/include/error/general_error.h +++ b/services/distributeddataservice/framework/include/error/general_error.h @@ -39,6 +39,19 @@ enum GeneralError : int32_t { E_RECORD_EXIST_CONFLICT, E_WITH_INVENTORY_DATA, E_SYNC_TASK_MERGED, + E_RECORD_NOT_FOUND, + E_RECORD_ALREADY_EXISTED, + E_DB_ERROR, + E_INVALID_VALUE_FIELDS, + E_INVALID_FIELD_TYPE, + E_CONSTRAIN_VIOLATION, + E_INVALID_FORMAT, + E_INVALID_QUERY_FORMAT, + E_INVALID_QUERY_FIELD, + E_TIME_OUT, + E_OVER_MAX_LIMITS, + E_SECURITY_LEVEL_ERROR, + E_FILE_NOT_EXIST, E_BUTT, }; } diff --git a/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h b/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h index de1da05c6dbd09d4a4e1a03440b711f3afdf12d1..293e3c2a021e9ac20ba9c5147f7feb503465191d 100644 --- a/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h @@ -21,6 +21,7 @@ namespace OHOS::DistributedData { struct API_EXPORT AutoLaunchMetaData final : public Serializable { std::map> datas; + bool launchForCleanData = false; API_EXPORT AutoLaunchMetaData(); API_EXPORT ~AutoLaunchMetaData() = default; diff --git a/services/distributeddataservice/framework/include/metadata/meta_data_manager.h b/services/distributeddataservice/framework/include/metadata/meta_data_manager.h index 4c5fb86988308374e69a2e5f3b6c819a390d841f..bbe2890d4b2617e53f0d1fafbf1c442799027553 100644 --- a/services/distributeddataservice/framework/include/metadata/meta_data_manager.h +++ b/services/distributeddataservice/framework/include/metadata/meta_data_manager.h @@ -52,7 +52,7 @@ public: using Bytes = std::vector; using OnComplete = std::function &)>; API_EXPORT static MetaDataManager &GetInstance(); - API_EXPORT void Initialize(std::shared_ptr metaStore, const Backup &backup); + API_EXPORT void Initialize(std::shared_ptr metaStore, const Backup &backup, const std::string &storeId); API_EXPORT void SetSyncer(const Syncer &syncer); API_EXPORT void SetCloudSyncer(const CloudSyncer &cloudSyncer); API_EXPORT bool SaveMeta(const std::string &key, const Serializable &value, bool isLocal = false); @@ -85,6 +85,7 @@ private: ~MetaDataManager(); API_EXPORT bool GetEntries(const std::string &prefix, std::vector &entries, bool isLocal); + void StopSA(); bool inited_ = false; std::mutex mutex_; @@ -93,6 +94,7 @@ private: Backup backup_; Syncer syncer_; CloudSyncer cloudSyncer_; + std::string storeId_; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_META_DATA_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/metadata/store_debug_info.h b/services/distributeddataservice/framework/include/metadata/store_debug_info.h new file mode 100644 index 0000000000000000000000000000000000000000..5a25972fbfe7e3df6875fbeae926e1ce5ca1c0ad --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/store_debug_info.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H +#include "serializable/serializable.h" +#include +namespace OHOS::DistributedData { +struct API_EXPORT StoreDebugInfo final : public Serializable { + struct FileInfo final : public Serializable { + uint64_t inode = 0; + int64_t size = 0; + uint32_t dev = 0; + uint32_t mode = 0; + uint32_t uid = 0; + uint32_t gid = 0; + bool Marshal(Serializable::json &node) const override; + bool Unmarshal(const Serializable::json &node) override; + + }; + std::map fileInfos; + API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); + bool Marshal(Serializable::json &node) const override; + bool Unmarshal(const Serializable::json &node) override; +private: + static constexpr const char *KEY_PREFIX = "StoreDebugInfo"; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H diff --git a/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/services/distributeddataservice/framework/include/metadata/store_meta_data.h index bad7ec20dc39e67812e72fac1705c4928fe6c0a8..007fd6ab06b524ccbfe13bf34619682fc88ba01d 100644 --- a/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -45,6 +45,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { int32_t area = 0; int32_t uid = -1; int32_t instanceId = 0; + int32_t haMode = 0; uint32_t tokenId = 0; std::string appId = ""; std::string appType = ""; @@ -83,6 +84,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT std::string GetStrategyKey() const; API_EXPORT std::string GetBackupSecretKey() const; API_EXPORT std::string GetAutoLaunchKey() const; + API_EXPORT std::string GetDebugInfoKey() const; API_EXPORT std::string GetStoreAlias() const; API_EXPORT StoreInfo GetStoreInfo() const; API_EXPORT static std::string GetKey(const std::initializer_list &fields); diff --git a/services/distributeddataservice/framework/include/metadata/version_meta_data.h b/services/distributeddataservice/framework/include/metadata/version_meta_data.h index e21247d88300530e86cebccb140bda25cc6dc718..c83522c6724915282044e085fae75be02d2e95e7 100755 --- a/services/distributeddataservice/framework/include/metadata/version_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/version_meta_data.h @@ -20,7 +20,7 @@ namespace OHOS::DistributedData { class API_EXPORT VersionMetaData final : public Serializable { public: - static constexpr int32_t CURRENT_VERSION = 3; + static constexpr int32_t CURRENT_VERSION = 4; static constexpr int32_t INVALID_VERSION = -1; int32_t version = INVALID_VERSION; diff --git a/services/distributeddataservice/framework/include/screen/screen_manager.h b/services/distributeddataservice/framework/include/screen/screen_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..cbf7c8666ed2fe73674f5e5039b4ae1805b14908 --- /dev/null +++ b/services/distributeddataservice/framework/include/screen/screen_manager.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H +#define DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H + +#include +#include +#include "visibility.h" + +namespace OHOS { +namespace DistributedData { +class ScreenManager { +public: + API_EXPORT static std::shared_ptr GetInstance(); + API_EXPORT static bool RegisterInstance(std::shared_ptr instance); + ScreenManager() = default; + virtual ~ScreenManager() = default; + virtual bool IsLocked(); + +private: + static std::mutex mutex_; + static std::shared_ptr instance_; +}; +} // namespace DistributedData +} // namespace OHOS +#endif //DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H diff --git a/services/distributeddataservice/framework/include/store/auto_cache.h b/services/distributeddataservice/framework/include/store/auto_cache.h index 9fcf14a4c1e0bed70eacfa045f442bbf9a52a402..0ee41a97222dd952e1d31258874cbfa73fb070c7 100644 --- a/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/services/distributeddataservice/framework/include/store/auto_cache.h @@ -50,9 +50,7 @@ public: API_EXPORT Stores GetStoresIfPresent(uint32_t tokenId, const std::string &storeName = ""); - API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); - - API_EXPORT void CloseStore(uint32_t tokenId); + API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId = ""); API_EXPORT void CloseExcept(const std::set &users); @@ -69,11 +67,14 @@ private: void StartTimer(); struct Delegate : public GeneralWatcher { Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, const StoreMetaData &meta); + Delegate(const Delegate& delegate); ~Delegate(); operator Store(); bool operator<(const Time &time) const; bool Close(); int32_t GetUser() const; + int32_t GetArea() const; + const std::string& GetDataDir() const; void SetObservers(const Watchers &watchers); int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override; @@ -84,7 +85,7 @@ private: GeneralStore *store_ = nullptr; Watchers watchers_; int32_t user_; - StoreMetaData meta_; + const StoreMetaData meta_; std::shared_mutex mutex_; }; @@ -96,6 +97,7 @@ private: ConcurrentMap> stores_; ConcurrentMap> disables_; Creator creators_[MAX_CREATOR_NUM]; + std::set disableStores_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/store/general_store.h b/services/distributeddataservice/framework/include/store/general_store.h index 1e2db5c4cb7a31bbde62f9a2e5d510a8d24e1815..52f8e974aa7ca7c10b57967f18653c75e7e1decd 100644 --- a/services/distributeddataservice/framework/include/store/general_store.h +++ b/services/distributeddataservice/framework/include/store/general_store.h @@ -20,10 +20,12 @@ #include #include +#include "executor_pool.h" #include "snapshot/snapshot.h" #include "store/cursor.h" #include "store/general_value.h" #include "store/general_watcher.h" + namespace OHOS::DistributedData { class CloudDB; class AssetLoader; @@ -33,6 +35,7 @@ public: using Watcher = GeneralWatcher; using DetailAsync = GenAsync; using Devices = std::vector; + using Executor = ExecutorPool; enum SyncMode { NEARBY_BEGIN, NEARBY_PUSH = NEARBY_BEGIN, @@ -60,6 +63,15 @@ public: CLEAN_MODE_BUTT }; + enum Area : int32_t { + EL0, + EL1, + EL2, + EL3, + EL4, + EL5 + }; + static inline uint32_t MixMode(uint32_t syncMode, uint32_t highMode) { return syncMode | highMode; @@ -100,13 +112,17 @@ public: bool enableCloud_ = false; }; - enum DistributedDb { + enum ErrOffset { DB_MODE_ID = 1, + CLOUD_MODE_ID = 10, }; static const int32_t DB_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, DB_MODE_ID); + static const int32_t CLOUD_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, CLOUD_MODE_ID); virtual ~GeneralStore() = default; + virtual void SetExecutor(std::shared_ptr executor) = 0; + virtual int32_t Bind(Database &database, const std::map &bindInfos, const CloudConfig &config) = 0; @@ -118,7 +134,7 @@ public: const std::vector &tables, int type, const std::vector &references) = 0; virtual int32_t SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, - const std::string &extendColName) = 0; + const std::string &extendColName, bool isForceUpgrade) = 0; virtual int32_t Insert(const std::string &table, VBuckets &&values) = 0; @@ -134,7 +150,8 @@ public: virtual std::pair> Query(const std::string &table, GenQuery &query) = 0; - virtual int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) = 0; + virtual std::pair Sync(const Devices &devices, GenQuery &query, + DetailAsync async, const SyncParam &syncParm) = 0; virtual std::pair> PreSharing(GenQuery &query) = 0; @@ -158,11 +175,17 @@ public: virtual int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) = 0; + virtual int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) = 0; + virtual std::vector GetWaterVersion(const std::string &deviceId) = 0; - virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId) {}; + virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account = "") {}; virtual void SetConfig(const StoreConfig &storeConfig) {}; + + virtual std::pair LockCloudDB() = 0; + + virtual int32_t UnLockCloudDB() = 0; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/store/general_value.h b/services/distributeddataservice/framework/include/store/general_value.h index 43d1fa25681881cc5b3ac77844b1d24ae4434cff..a0b22bd0bca627d5d5e924b0c2488fbf84e5e457 100644 --- a/services/distributeddataservice/framework/include/store/general_value.h +++ b/services/distributeddataservice/framework/include/store/general_value.h @@ -37,6 +37,7 @@ enum SyncTriggerMode { MODE_ONLINE, MODE_UNLOCK, MODE_BROADCASTER, + MODE_CONSISTENCY, }; struct GenStatistic { @@ -55,7 +56,7 @@ struct GenProgressDetail { int32_t progress; int32_t code; int32_t dbCode; - bool dataChange = false; + uint64_t changeCount = 0; std::map details; }; @@ -96,6 +97,22 @@ struct SyncParam { int32_t wait; bool isCompensation = false; int32_t triggerMode = MODE_DEFAULT; + std::string prepareTraceId; + int32_t user; +}; + +enum SyncStage : int8_t { + PREPARE = 0, + START, + END +}; + +struct ReportParam { + int32_t user = 0; + std::string bundleName; + std::string prepareTraceId; + SyncStage syncStage = SyncStage::PREPARE; + int32_t errCode = 0; }; using Assets = std::vector; diff --git a/services/distributeddataservice/framework/include/utils/corrupt_reporter.h b/services/distributeddataservice/framework/include/utils/corrupt_reporter.h new file mode 100644 index 0000000000000000000000000000000000000000..0a1173ed4c7146882de7390f940b1307da5e1340 --- /dev/null +++ b/services/distributeddataservice/framework/include/utils/corrupt_reporter.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_UTILS_CORRUPT_REPORTER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_UTILS_CORRUPT_REPORTER_H + +#include "visibility.h" +#include +namespace OHOS::DistributedData { +class CorruptReporter { +public: + API_EXPORT static bool CreateCorruptedFlag(const std::string &dbPath, const std::string &dbName); + API_EXPORT static bool HasCorruptedFlag(const std::string &dbPath, const std::string &dbName); + API_EXPORT static bool DeleteCorruptedFlag(const std::string &dbPath, const std::string &dbName); +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_UTILS_CORRUPT_REPORTER_H diff --git a/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp b/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp index 3224368c419088697c3fa1b26573c653afc1306b..8ecf15edddbd50137803c917fbd2b5a8de6ec88c 100644 --- a/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp @@ -25,12 +25,14 @@ AutoLaunchMetaData::AutoLaunchMetaData() bool AutoLaunchMetaData::Marshal(json& node) const { SetValue(node[GET_NAME(datas)], datas); + SetValue(node[GET_NAME(launchForCleanData)], launchForCleanData); return true; } bool AutoLaunchMetaData::Unmarshal(const json& node) { GetValue(node, GET_NAME(datas), datas); + GetValue(node, GET_NAME(launchForCleanData), launchForCleanData); return true; } diff --git a/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index 777a8d9396902324bc32be67d130ac4c25e667d3..44656ce4191d6856498dcc7e60636c1801bd4570 100644 --- a/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -14,11 +14,14 @@ */ #include "metadata/meta_data_manager.h" +#include #define LOG_TAG "MetaDataManager" +#include "directory/directory_manager.h" #include "kv_store_nb_delegate.h" #include "log_print.h" #include "utils/anonymous.h" +#include "utils/corrupt_reporter.h" namespace OHOS::DistributedData { class MetaObserver : public DistributedDB::KvStoreObserver { @@ -85,6 +88,10 @@ MetaDataManager::Filter::Filter(const std::string &pattern) : pattern_(pattern) void MetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data) { + if (filter_ == nullptr) { + ZLOGE("filter_ is nullptr!"); + return; + } auto values = { &data.GetEntriesInserted(), &data.GetEntriesUpdated(), &data.GetEntriesDeleted() }; int32_t next = MetaDataManager::INSERT; for (auto value : values) { @@ -116,6 +123,10 @@ void MetaObserver::HandleChanges(int32_t flag, std::vector> &p if (priData.empty()) { return; } + if (filter_ == nullptr) { + ZLOGE("filter_ is nullptr!"); + return; + } for (const auto &priKey : priData) { if (priKey.empty()) { continue; @@ -144,7 +155,7 @@ MetaDataManager::~MetaDataManager() metaObservers_.Clear(); } -void MetaDataManager::Initialize(std::shared_ptr metaStore, const Backup &backup) +void MetaDataManager::Initialize(std::shared_ptr metaStore, const Backup &backup, const std::string &storeId) { if (metaStore == nullptr) { return; @@ -156,6 +167,7 @@ void MetaDataManager::Initialize(std::shared_ptr metaStore, const Bac } metaStore_ = std::move(metaStore); backup_ = backup; + storeId_ = storeId; inited_ = true; } @@ -184,6 +196,13 @@ bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value auto data = Serializable::Marshall(value); auto status = isLocal ? metaStore_->PutLocal({ key.begin(), key.end() }, { data.begin(), data.end() }) : metaStore_->Put({ key.begin(), key.end() }, { data.begin(), data.end() }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + CorruptReporter::CreateCorruptedFlag(DirectoryManager::GetInstance().GetMetaStorePath(), storeId_); + StopSA(); + return false; + } if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } @@ -206,6 +225,13 @@ bool MetaDataManager::LoadMeta(const std::string &key, Serializable &value, bool DistributedDB::Value data; auto status = isLocal ? metaStore_->GetLocal({ key.begin(), key.end() }, data) : metaStore_->Get({ key.begin(), key.end() }, data); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + CorruptReporter::CreateCorruptedFlag(DirectoryManager::GetInstance().GetMetaStorePath(), storeId_); + StopSA(); + return false; + } if (status != DistributedDB::DBStatus::OK) { return false; } @@ -221,6 +247,12 @@ bool MetaDataManager::GetEntries(const std::string &prefix, std::vector & std::vector dbEntries; auto status = isLocal ? metaStore_->GetLocalEntries({ prefix.begin(), prefix.end() }, dbEntries) : metaStore_->GetEntries({ prefix.begin(), prefix.end() }, dbEntries); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d", status, isLocal); + CorruptReporter::CreateCorruptedFlag(DirectoryManager::GetInstance().GetMetaStorePath(), storeId_); + StopSA(); + return false; + } if (status != DistributedDB::DBStatus::OK && status != DistributedDB::DBStatus::NOT_FOUND) { ZLOGE("failed! prefix:%{public}s status:%{public}d isLocal:%{public}d", Anonymous::Change(prefix).c_str(), status, isLocal); @@ -242,6 +274,13 @@ bool MetaDataManager::DelMeta(const std::string &key, bool isLocal) DistributedDB::Value data; auto status = isLocal ? metaStore_->DeleteLocal({ key.begin(), key.end() }) : metaStore_->Delete({ key.begin(), key.end() }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + CorruptReporter::CreateCorruptedFlag(DirectoryManager::GetInstance().GetMetaStorePath(), storeId_); + StopSA(); + return false; + } if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } @@ -263,6 +302,12 @@ bool MetaDataManager::Sync(const std::vector &devices, OnComplete c } complete(results); }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d", status); + CorruptReporter::CreateCorruptedFlag(DirectoryManager::GetInstance().GetMetaStorePath(), storeId_); + StopSA(); + return false; + } if (status != DistributedDB::OK) { ZLOGW("meta data sync error %{public}d.", status); } @@ -299,4 +344,13 @@ bool MetaDataManager::Unsubscribe(std::string filter) return metaObservers_.Erase(filter); } + +void MetaDataManager::StopSA() +{ + ZLOGI("stop distributeddata"); + int err = raise(SIGKILL); + if (err < 0) { + ZLOGE("stop distributeddata failed, errCode: %{public}d", err); + } +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/store_debug_info.cpp b/services/distributeddataservice/framework/metadata/store_debug_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..014063f0a91451bebc937101488f99859929efca --- /dev/null +++ b/services/distributeddataservice/framework/metadata/store_debug_info.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "metadata/store_debug_info.h" +#include "utils/constant.h" +namespace OHOS::DistributedData { +bool StoreDebugInfo::FileInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(inode)], inode); + SetValue(node[GET_NAME(size)], size); + SetValue(node[GET_NAME(dev)], dev); + SetValue(node[GET_NAME(mode)], mode); + SetValue(node[GET_NAME(uid)], uid); + SetValue(node[GET_NAME(gid)], gid); + return true; +} + +bool StoreDebugInfo::FileInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(inode), inode); + GetValue(node, GET_NAME(size), size); + GetValue(node, GET_NAME(dev), dev); + GetValue(node, GET_NAME(mode), mode); + GetValue(node, GET_NAME(uid), uid); + GetValue(node, GET_NAME(gid), gid); + return true; +} + +bool StoreDebugInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(fileInfos)], fileInfos); + return true; +} + +bool StoreDebugInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(fileInfos), fileInfos); + return true; +} + +std::string StoreDebugInfo::GetPrefix(const std::initializer_list &fields) +{ + return Constant::Join(KEY_PREFIX, Constant::KEY_SEPARATOR, fields); +} +} \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/services/distributeddataservice/framework/metadata/store_meta_data.cpp index f10d2ebad536067ba7f26d5b731d1dc4a2be9b72..dea972be3a1cd91ac2369cba9746e1f2134e7e87 100644 --- a/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -17,6 +17,7 @@ #include "metadata/auto_launch_meta_data.h" #include "metadata/secret_key_meta_data.h" +#include "metadata/store_debug_info.h" #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" #include "utils/anonymous.h" @@ -62,6 +63,7 @@ bool StoreMetaData::Marshal(json &node) const SetValue(node[GET_NAME(UID)], uid); SetValue(node[GET_NAME(customDir)], customDir); SetValue(node[GET_NAME(authType)], authType); + SetValue(node[GET_NAME(haMode)], haMode); return true; } @@ -103,6 +105,7 @@ bool StoreMetaData::Unmarshal(const json &node) } GetValue(node, GET_NAME(customDir), customDir); GetValue(node, GET_NAME(authType), authType); + GetValue(node, GET_NAME(haMode), haMode); return true; } @@ -132,7 +135,8 @@ bool StoreMetaData::operator==(const StoreMetaData &metaData) const Constant::NotEqual(isSearchable, metaData.isSearchable) || Constant::NotEqual(isNeedCompress, metaData.isNeedCompress) || Constant::NotEqual(enableCloud, metaData.enableCloud) || - Constant::NotEqual(cloudAutoSync, metaData.cloudAutoSync)) { + Constant::NotEqual(cloudAutoSync, metaData.cloudAutoSync) || + Constant::NotEqual(isManualClean, metaData.isManualClean)) { return false; } return (version == metaData.version && storeType == metaData.storeType && dataType == metaData.dataType && @@ -140,7 +144,7 @@ bool StoreMetaData::operator==(const StoreMetaData &metaData) const tokenId == metaData.tokenId && instanceId == metaData.instanceId && appId == metaData.appId && appType == metaData.appType && bundleName == metaData.bundleName && dataDir == metaData.dataDir && storeId == metaData.storeId && user == metaData.user && deviceId == metaData.deviceId && - account == metaData.account && authType == metaData.authType); + account == metaData.account && authType == metaData.authType && haMode == metaData.haMode); } bool StoreMetaData::operator!=(const StoreMetaData &metaData) const @@ -185,6 +189,11 @@ std::string StoreMetaData::GetAutoLaunchKey() const return AutoLaunchMetaData::GetPrefix({ deviceId, user, "default", bundleName, storeId }); } +std::string StoreMetaData::GetDebugInfoKey() const +{ + return StoreDebugInfo::GetPrefix({ deviceId, user, "default", bundleName, storeId, std::to_string(instanceId) }); +} + std::string StoreMetaData::GetStoreAlias() const { return Anonymous::Change(storeId); diff --git a/services/distributeddataservice/framework/screen/screen_manager.cpp b/services/distributeddataservice/framework/screen/screen_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f7698f5bb28cfd602cd7a453a58d1c907fc2c19 --- /dev/null +++ b/services/distributeddataservice/framework/screen/screen_manager.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ScreenManager" +#include "screen/screen_manager.h" +#include "log_print.h" + +namespace OHOS::DistributedData { +std::mutex ScreenManager::mutex_; +std::shared_ptr ScreenManager::instance_ = nullptr; +std::shared_ptr ScreenManager::GetInstance() +{ + std::lock_guard lock(mutex_); + if (instance_ != nullptr) { + return instance_; + } + instance_ = std::make_shared(); + ZLOGW("no register, new instance!"); + return instance_; +} + +bool ScreenManager::RegisterInstance(std::shared_ptr instance) +{ + std::lock_guard lock(mutex_); + instance_ = std::move(instance); + return true; +} + +bool ScreenManager::IsLocked() +{ + return false; +} + +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/store/auto_cache.cpp b/services/distributeddataservice/framework/store/auto_cache.cpp index ed920d3d27c0d8fd785fcc32c9c39f3a37fb6df0..a32d959c98112e502783f53d0f141ce54466a937 100644 --- a/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/services/distributeddataservice/framework/store/auto_cache.cpp @@ -20,6 +20,7 @@ #include "changeevent/remote_change_event.h" #include "eventcenter/event_center.h" #include "log_print.h" +#include "screenlock/screen_lock.h" #include "utils/anonymous.h" namespace OHOS::DistributedData { AutoCache &AutoCache::GetInstance() @@ -60,14 +61,22 @@ AutoCache::~AutoCache() AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers &watchers) { Store store; - if (meta.storeType >= MAX_CREATOR_NUM || meta.storeType < 0 || !creators_[meta.storeType] || - disables_.ContainIf(meta.tokenId, - [&meta](const std::set &stores) -> bool { return stores.count(meta.storeId) != 0; })) { + if ((meta.area >= GeneralStore::EL4 && ScreenManager::GetInstance()->IsLocked()) || + meta.storeType >= MAX_CREATOR_NUM || meta.storeType < 0 || !creators_[meta.storeType] || + disables_.ContainIf(meta.tokenId, [&meta](const std::set &stores) -> bool { + return stores.count(meta.storeId) != 0; + })) { return store; } stores_.Compute( meta.tokenId, [this, &meta, &watchers, &store](auto &, std::map &stores) -> bool { + if (disableStores_.count(meta.dataDir) != 0) { + ZLOGW("store is closing, tokenId:0x%{public}x user:%{public}s" + "bundleName:%{public}s storeName:%{public}s", + meta.tokenId, meta.user.c_str(), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + return !stores.empty(); + } auto it = stores.find(meta.storeId); if (it != stores.end()) { if (!watchers.empty()) { @@ -81,6 +90,7 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & ZLOGE("creator failed. storeName:%{public}s", meta.GetStoreAlias().c_str()); return !stores.empty(); } + dbStore->SetExecutor(executor_); auto result = stores.emplace(std::piecewise_construct, std::forward_as_tuple(meta.storeId), std::forward_as_tuple(dbStore, watchers, atoi(meta.user.c_str()), meta)); store = result.first->second; @@ -134,31 +144,50 @@ void AutoCache::StartTimer() void AutoCache::CloseStore(uint32_t tokenId, const std::string &storeId) { - stores_.ComputeIfPresent(tokenId, [&storeId](auto &key, std::map &delegates) { - auto it = delegates.find(storeId); - if (it != delegates.end()) { - it->second.Close(); - delegates.erase(it); + std::set storeIds; + std::list closeStores; + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.ComputeIfPresent(tokenId, + [this, &storeId, isScreenLocked, &storeIds, &closeStores](auto &key, auto &delegates) { + auto it = delegates.begin(); + while (it != delegates.end()) { + if ((storeId == it->first || storeId.empty()) && + (!isScreenLocked || it->second.GetArea() < GeneralStore::EL4) && + disableStores_.count(it->second.GetDataDir()) == 0) { + disableStores_.insert(it->second.GetDataDir()); + storeIds.insert(it->first); + closeStores.emplace(closeStores.end(), it->second); + } else { + ++it; + } + } + return !delegates.empty(); + }); + closeStores.clear(); + stores_.ComputeIfPresent(tokenId, [this, &storeIds](auto &key, auto &delegates) { + for (auto it = delegates.begin(); it != delegates.end();) { + if (storeIds.count(it->first) != 0) { + disableStores_.erase(it->second.GetDataDir()); + it = delegates.erase(it); + } else { + ++it; + } } return !delegates.empty(); }); } -void AutoCache::CloseStore(uint32_t tokenId) -{ - stores_.Erase(tokenId); -} - void AutoCache::CloseExcept(const std::set &users) { - stores_.EraseIf([&users](const auto &tokenId, std::map &delegates) { + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.EraseIf([&users, isScreenLocked](const auto &tokenId, std::map &delegates) { if (delegates.empty() || users.count(delegates.begin()->second.GetUser()) != 0) { return delegates.empty(); } for (auto it = delegates.begin(); it != delegates.end();) { // if the kv store is BUSY we wait more INTERVAL minutes again - if (!it->second.Close()) { + if ((isScreenLocked && it->second.GetArea() >= GeneralStore::EL4) || !it->second.Close()) { ++it; } else { it = delegates.erase(it); @@ -184,10 +213,12 @@ void AutoCache::SetObserver(uint32_t tokenId, const std::string &storeId, const void AutoCache::GarbageCollect(bool isForce) { auto current = std::chrono::steady_clock::now(); - stores_.EraseIf([¤t, isForce](auto &key, std::map &delegates) { + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.EraseIf([¤t, isForce, isScreenLocked](auto &key, std::map &delegates) { for (auto it = delegates.begin(); it != delegates.end();) { // if the store is BUSY we wait more INTERVAL minutes again - if ((isForce || it->second < current) && it->second.Close()) { + if ((!isScreenLocked || it->second.GetArea() < GeneralStore::EL4) && (isForce || it->second < current) && + it->second.Close()) { it = delegates.erase(it); } else { ++it; @@ -223,6 +254,14 @@ AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, } } +AutoCache::Delegate::Delegate(const Delegate& delegate) +{ + store_ = delegate.store_; + if (store_ != nullptr) { + store_->AddRef(); + } +} + AutoCache::Delegate::~Delegate() { if (store_ != nullptr) { @@ -250,7 +289,6 @@ bool AutoCache::Delegate::operator<(const AutoCache::Time &time) const bool AutoCache::Delegate::Close() { - std::unique_lock lock(mutex_); if (store_ != nullptr) { auto status = store_->Close(); if (status == Error::E_BUSY) { @@ -272,6 +310,16 @@ int32_t AutoCache::Delegate::GetUser() const return user_; } +int32_t AutoCache::Delegate::GetArea() const +{ + return meta_.area; +} + +const std::string& AutoCache::Delegate::GetDataDir() const +{ + return meta_.dataDir; +} + int32_t AutoCache::Delegate::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) { std::vector tables; @@ -329,4 +377,4 @@ void AutoCache::Delegate::PostDataChange(const StoreMetaData &meta, const std::v auto evt = std::make_unique(RemoteChangeEvent::DATA_CHANGE, std::move(info)); EventCenter::GetInstance().PostEvent(std::move(evt)); } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/test/BUILD.gn b/services/distributeddataservice/framework/test/BUILD.gn index 026e7a9009caa13a2f081273c579e2f63ed23e19..d609a304d75f00a6905fb20a9d97ee850ae1483c 100644 --- a/services/distributeddataservice/framework/test/BUILD.gn +++ b/services/distributeddataservice/framework/test/BUILD.gn @@ -127,6 +127,11 @@ ohos_unittest("ServiceUtilsTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libnativetoken", @@ -207,23 +212,23 @@ ohos_unittest("CloudInfoTest") { deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } -ohos_unittest("EventTest") { +ohos_unittest("ConstantTest") { module_out_path = module_output_path - sources = [ "event_test.cpp" ] + sources = [ "constant_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } -ohos_unittest("GeneralStoreTest") { +ohos_unittest("CryptoTest") { module_out_path = module_output_path - sources = [ "general_store_test.cpp" ] + sources = [ "crypto_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } -ohos_unittest("SubscriptionTest") { +ohos_unittest("EventTest") { module_out_path = module_output_path - sources = [ "subscription_test.cpp" ] + sources = [ "event_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } @@ -258,23 +263,23 @@ ohos_unittest("MetaDataManagerTest") { ] } -ohos_unittest("StoreMetaDataLocalTest") { +ohos_unittest("GeneralStoreTest") { module_out_path = module_output_path - sources = [ "store_meta_data_local_test.cpp" ] + sources = [ "general_store_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } -ohos_unittest("ConstantTest") { +ohos_unittest("SubscriptionTest") { module_out_path = module_output_path - sources = [ "constant_test.cpp" ] + sources = [ "subscription_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } -ohos_unittest("CryptoTest") { +ohos_unittest("StoreMetaDataLocalTest") { module_out_path = module_output_path - sources = [ "crypto_test.cpp" ] + sources = [ "store_meta_data_local_test.cpp" ] configs = [ ":module_private_config" ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] } diff --git a/services/distributeddataservice/framework/test/checker_manager_test.cpp b/services/distributeddataservice/framework/test/checker_manager_test.cpp index 8dfc80b407d1cd53e3bdfcb16d808e382b864e5b..d95a7df7dd7ea8fd5c7df2730508f36e2aedf80e 100644 --- a/services/distributeddataservice/framework/test/checker_manager_test.cpp +++ b/services/distributeddataservice/framework/test/checker_manager_test.cpp @@ -170,4 +170,36 @@ HWTEST_F(CheckerManagerTest, BundleChecker, TestSize.Level0) AccessTokenKit::GetHapTokenInfo(storeInfo.tokenId, tokenInfo); ASSERT_EQ(Crypto::Sha256(tokenInfo.appID), CheckerManager::GetInstance().GetAppId(storeInfo)); ASSERT_TRUE(CheckerManager::GetInstance().IsValid(storeInfo)); +} + +/** +* @tc.name: IsDynamic +* @tc.desc: checker data type. +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CheckerManagerTest, IsDynamic, TestSize.Level0) +{ + CheckerManager::StoreInfo storeInfo; + storeInfo.uid = 2000000; + storeInfo.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo", 0); + storeInfo.bundleName = "ohos.test.demo"; + ASSERT_FALSE(CheckerManager::GetInstance().IsDynamic(storeInfo)); +} + +/** +* @tc.name: IsStatic +* @tc.desc: checker data type. +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CheckerManagerTest, IsStatic, TestSize.Level0) +{ + CheckerManager::StoreInfo storeInfo; + storeInfo.uid = 2000000; + storeInfo.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo", 0); + storeInfo.bundleName = "ohos.test.demo"; + ASSERT_FALSE(CheckerManager::GetInstance().IsStatic(storeInfo)); } \ No newline at end of file diff --git a/services/distributeddataservice/framework/test/cloud_test.cpp b/services/distributeddataservice/framework/test/cloud_test.cpp index 15a83e104235b731a0521583754b6bfa4c21f29e..90232b1848192abf5a4b3256489172c0a59a247b 100644 --- a/services/distributeddataservice/framework/test/cloud_test.cpp +++ b/services/distributeddataservice/framework/test/cloud_test.cpp @@ -18,11 +18,13 @@ #include "serializable/serializable.h" #include "cloud/cloud_db.h" +#include "cloud/cloud_event.h" #include "cloud/cloud_info.h" #include "cloud/cloud_server.h" #include "cloud/schema_meta.h" #include "nlohmann/json.hpp" #include "utils/crypto.h" +#include "screen/screen_manager.h" #include "store/general_store.h" #include "store/general_value.h" #include "store/general_watcher.h" @@ -54,6 +56,22 @@ public: void TearDown(){}; }; +class CloudEventTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class ScreenManagerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + class MockGeneralWatcher : public DistributedData::GeneralWatcher { public: int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, @@ -207,13 +225,13 @@ HWTEST_F(CloudInfoTest, GetPrefix, TestSize.Level0) } /** -* @tc.name: CloudInfoTest +* @tc.name: CloudInfoTest001 * @tc.desc: Marshal and Unmarshal of CloudInfo. * @tc.type: FUNC * @tc.require: * @tc.author: Anvette */ -HWTEST_F(CloudInfoTest, CloudInfoTest, TestSize.Level0) +HWTEST_F(CloudInfoTest, CloudInfoTest001, TestSize.Level0) { CloudInfo cloudInfo1; cloudInfo1.user = 111; @@ -231,6 +249,33 @@ HWTEST_F(CloudInfoTest, CloudInfoTest, TestSize.Level0) EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); } +/** +* @tc.name: CloudInfoTest002 +* @tc.desc: Marshal and Unmarshal of CloudInfo. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CloudInfoTest, CloudInfoTest002, TestSize.Level0) +{ + CloudInfo cloudInfo1; + cloudInfo1.user = 111; + cloudInfo1.id = "test1_id"; + cloudInfo1.totalSpace = 0; + cloudInfo1.remainSpace = 0; + cloudInfo1.enableCloud = false; + cloudInfo1.maxNumber = CloudInfo::DEFAULT_BATCH_NUMBER; + cloudInfo1.maxSize = CloudInfo::DEFAULT_BATCH_SIZE; + + Serializable::json node1; + cloudInfo1.Marshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfo1), to_string(node1)); + + CloudInfo cloudInfo2; + cloudInfo2.Unmarshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); +} + /** * @tc.name: AppInfoTest * @tc.desc: Marshal and Unmarshal of AppInfo. @@ -506,4 +551,32 @@ HWTEST_F(CloudInfoTest, SchemaMeta, TestSize.Level0) auto result2 = schemaMeta.GetHighVersion(); EXPECT_EQ(result2, metaVersion); } + +/** +* @tc.name: GetEventId +* @tc.desc: test GetEventId function +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CloudEventTest, GetEventId, TestSize.Level0) +{ + int32_t evtId = 1; + StoreInfo info; + CloudEvent event(evtId, info); + auto ret = event.GetEventId(); + EXPECT_EQ(ret, evtId); +} + +/** +* @tc.name: IsLocked +* @tc.desc: test IsLocked function +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(ScreenManagerTest, IsLocked, TestSize.Level0) +{ + ASSERT_FALSE(ScreenManager::GetInstance()->IsLocked()); +} } // namespace OHOS::Test diff --git a/services/distributeddataservice/framework/test/feature_test.cpp b/services/distributeddataservice/framework/test/feature_test.cpp index ed541823e4c7f7a65acd1ec07a80f62ca563a231..36cf911ac51150018130e3a45b101f50b9b037bf 100644 --- a/services/distributeddataservice/framework/test/feature_test.cpp +++ b/services/distributeddataservice/framework/test/feature_test.cpp @@ -257,4 +257,20 @@ HWTEST_F(FeatureSystemTest, FeatureTest002, TestSize.Level1) ret = mockFeature.OnSessionReady(device); EXPECT_EQ(ret, E_OK); } + + +/** +* @tc.name: OnScreenUnlockedTest +* @tc.desc: test OnScreenUnlocked +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(FeatureSystemTest, OnScreenUnlockedTest, TestSize.Level1) +{ + MockFeature mockFeature; + int32_t user = 0; + int32_t ret = mockFeature.OnScreenUnlocked(user); + EXPECT_EQ(ret, E_OK); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/framework/test/meta_data_test.cpp b/services/distributeddataservice/framework/test/meta_data_test.cpp index f205344c1418de72b1af6395e3cfd59746d52bd7..4ae67cd9d9b57b8139ed85fcab00916fcf943a74 100644 --- a/services/distributeddataservice/framework/test/meta_data_test.cpp +++ b/services/distributeddataservice/framework/test/meta_data_test.cpp @@ -45,7 +45,6 @@ public: static void SetUpTestCase() { std::shared_ptr executors = std::make_shared(NUM_MAX, NUM_MIN); - Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); KvStoreMetaManager::GetInstance().BindExecutor(executors); @@ -462,6 +461,16 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData006, TestSize.Level1) EXPECT_FALSE(storemetaData1 == storemetaData2); storemetaData2.isNeedCompress = true; EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.enableCloud = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.enableCloud = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.cloudAutoSync = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.cloudAutoSync = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); } /** @@ -508,6 +517,16 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData007, TestSize.Level1) EXPECT_TRUE(storemetaData1 != storemetaData2); storemetaData2.isNeedCompress = true; EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.enableCloud = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.enableCloud = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.cloudAutoSync = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.cloudAutoSync = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); } /** diff --git a/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp b/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp index 5b4e5611fd0127c36d8bc80ce13391308f7404d4..d0c6b6379d1bd767bf07bfcdfb6d0b4a98351097 100644 --- a/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp +++ b/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp @@ -37,22 +37,45 @@ public: HWTEST_F(StoreMetaDataLocalTest, EqualityOperatorTest, TestSize.Level1) { StoreMetaDataLocal metaData1; - metaData1.isAutoSync = true; - metaData1.isBackup = true; StoreMetaDataLocal metaData2; - metaData2.isAutoSync = true; - metaData2.isBackup = false; StoreMetaDataLocal metaData3; + + ASSERT_TRUE(metaData1 == metaData2); metaData3.isAutoSync = true; + ASSERT_FALSE(metaData1 == metaData3); metaData3.isBackup = true; + ASSERT_FALSE(metaData1 == metaData3); + ASSERT_TRUE(metaData1 != metaData3); + ASSERT_FALSE(metaData1 != metaData2); + metaData3.isDirty = true; + ASSERT_FALSE(metaData1 == metaData3); + metaData3.isEncrypt = true; + ASSERT_FALSE(metaData1 == metaData3); + metaData3.isPublic = true; + ASSERT_FALSE(metaData1 == metaData3); - ASSERT_FALSE(metaData1 == metaData2); - ASSERT_TRUE(metaData1 == metaData3); + metaData2.isAutoSync = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isDirty = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isEncrypt = true; ASSERT_FALSE(metaData2 == metaData3); + metaData2.isPublic = true; + ASSERT_TRUE(metaData2 == metaData3); - ASSERT_TRUE(metaData1 != metaData2); - ASSERT_FALSE(metaData1 != metaData3); - ASSERT_TRUE(metaData2 != metaData3); + metaData2.isBackup = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isDirty = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isEncrypt = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isPublic = false; + ASSERT_FALSE(metaData2 == metaData3); } /** @@ -95,5 +118,8 @@ HWTEST_F(StoreMetaDataLocalTest, GetPolicy, TestSize.Level1) policy.index = 1; EXPECT_FALSE(metaData.HasPolicy(type)); EXPECT_TRUE(policy.IsValueEffect()); + type = UINT32_MAX; + policy = metaData.GetPolicy(type); + EXPECT_EQ(policy.type, type); } } // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/framework/test/utils_test.cpp b/services/distributeddataservice/framework/test/utils_test.cpp index e81c8602929c6005e33f62cc0f5c22d4bfff834c..31e8ecf17f0b8aee3c2f705933c39294ce1f2001 100644 --- a/services/distributeddataservice/framework/test/utils_test.cpp +++ b/services/distributeddataservice/framework/test/utils_test.cpp @@ -21,12 +21,16 @@ #include "ipc_skeleton.h" #include "log_print.h" #include "utils/block_integer.h" +#include "utils/constant.h" #include "utils/converter.h" +#include "utils/corrupt_reporter.h" #include "utils/ref_count.h" #include "utils/endian_converter.h" using namespace testing::ext; using namespace OHOS::DistributedData; namespace OHOS::Test { +static constexpr const char *TEST_CORRUPT_PATH = "/data/service/el1/public/database/utils_test/"; +static constexpr const char *TEST_CORRUPT_STOREID = "utils_test_store"; class ServiceUtilsTest : public testing::Test { public: static constexpr uint16_t HOST_VALUE16 = 0x1234; @@ -130,6 +134,10 @@ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) std::function action = []() { }; RefCount refCountWithAction(action); EXPECT_TRUE(refCountWithAction); + + std::function actions; + RefCount refCountWithActions(actions); + EXPECT_TRUE(refCountWithActions); int num = 0; { RefCount refCount([&num]() { @@ -158,6 +166,8 @@ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) RefCount refCount6 = std::move(refCount2); refCount6 = std::move(refCount4); ASSERT_TRUE(refCount6); + + EXPECT_TRUE(refCount5 = refCount5); } ASSERT_EQ(num, 10); } @@ -189,4 +199,70 @@ HWTEST_F(ServiceUtilsTest, HostToNet, TestSize.Level1) uint64_t hostValue64 = NetToHost(NET_VALUE64); EXPECT_EQ(hostValue64, le64toh(NET_VALUE64)); } -} // namespace OHOS::Test \ No newline at end of file + +/** +* @tc.name: DCopy +* @tc.desc: test Constant::DCopy function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceUtilsTest, DCopy, TestSize.Level1) +{ + Constant constant; + uint8_t *tag = nullptr; + size_t tagLen = 1; + uint8_t *src = nullptr; + size_t srcLen = 0; + + uint8_t tags[10]; + size_t tagsLen = 10; + uint8_t srcs[10]; + size_t srcsLen = 10; + + EXPECT_FALSE(constant.DCopy(tag, tagLen, src, srcLen)); + EXPECT_FALSE(constant.DCopy(tag, tagsLen, src, srcsLen)); + EXPECT_FALSE(constant.DCopy(tags, tagLen, src, srcLen)); + EXPECT_FALSE(constant.DCopy(tag, tagLen, srcs, srcLen)); + EXPECT_FALSE(constant.DCopy(tags, tagsLen, src, srcsLen)); + EXPECT_FALSE(constant.DCopy(tag, tagsLen, srcs, srcsLen)); + EXPECT_FALSE(constant.DCopy(tags, tagLen, srcs, srcLen)); + EXPECT_TRUE(constant.DCopy(tags, tagsLen, srcs, srcsLen)); +} + +/** +* @tc.name: CorruptTest001 +* @tc.desc: test CorruptReporter function with invalid parameter. +* @tc.type: FUNC +* @tc.require: +* @tc.author: yanhui +*/ +HWTEST_F(ServiceUtilsTest, CorruptTest001, TestSize.Level1) +{ + ASSERT_EQ(false, CorruptReporter::CreateCorruptedFlag(TEST_CORRUPT_PATH, "")); + ASSERT_EQ(false, CorruptReporter::CreateCorruptedFlag("", TEST_CORRUPT_STOREID)); + ASSERT_EQ(false, CorruptReporter::CreateCorruptedFlag(TEST_CORRUPT_PATH, TEST_CORRUPT_STOREID)); + ASSERT_EQ(false, CorruptReporter::HasCorruptedFlag(TEST_CORRUPT_PATH, "")); + ASSERT_EQ(false, CorruptReporter::HasCorruptedFlag("", TEST_CORRUPT_STOREID)); + ASSERT_EQ(false, CorruptReporter::DeleteCorruptedFlag(TEST_CORRUPT_PATH, "")); + ASSERT_EQ(false, CorruptReporter::DeleteCorruptedFlag("", TEST_CORRUPT_STOREID)); + ASSERT_EQ(false, CorruptReporter::DeleteCorruptedFlag(TEST_CORRUPT_PATH, TEST_CORRUPT_STOREID)); +} + +/** +* @tc.name: CorruptTest002 +* @tc.desc: test CorruptReporter function with normal parameter. +* @tc.type: FUNC +* @tc.require: +* @tc.author: yanhui +*/ +HWTEST_F(ServiceUtilsTest, CorruptTest002, TestSize.Level1) +{ + mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771 + mkdir(TEST_CORRUPT_PATH, mode); + ASSERT_EQ(true, CorruptReporter::CreateCorruptedFlag(TEST_CORRUPT_PATH, TEST_CORRUPT_STOREID)); + ASSERT_EQ(true, CorruptReporter::HasCorruptedFlag(TEST_CORRUPT_PATH, TEST_CORRUPT_STOREID)); + ASSERT_EQ(true, CorruptReporter::DeleteCorruptedFlag(TEST_CORRUPT_PATH, TEST_CORRUPT_STOREID)); + rmdir(TEST_CORRUPT_PATH); +} +} // namespace OHOS::Test diff --git a/services/distributeddataservice/framework/utils/corrupt_reporter.cpp b/services/distributeddataservice/framework/utils/corrupt_reporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90c25a3b9b4b8c81d6648c11eb9c04b18af295af --- /dev/null +++ b/services/distributeddataservice/framework/utils/corrupt_reporter.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "CorruptReporter" +#include "utils/corrupt_reporter.h" + +#include "log_print.h" +#include "utils/anonymous.h" +#include +#include +#include + +namespace OHOS::DistributedData { +constexpr const char *DB_CORRUPTED_POSTFIX = ".corruptedflg"; + +bool CorruptReporter::CreateCorruptedFlag(const std::string &path, const std::string &dbName) +{ + if (path.empty() || dbName.empty()) { + ZLOGW("The path or dbName is empty, path:%{public}s, dbName:%{public}s", path.c_str(), + Anonymous::Change(dbName).c_str()); + return false; + } + std::string flagFileName = path + "/" + dbName + DB_CORRUPTED_POSTFIX; + int fd = creat(flagFileName.c_str(), S_IRWXU | S_IRWXG); + if (fd == -1) { + ZLOGW("Create corrupted flag fail, flagFileName:%{public}s, errno:%{public}d", + Anonymous::Change(flagFileName).c_str(), errno); + return false; + } + close(fd); + return true; +} + +bool CorruptReporter::HasCorruptedFlag(const std::string &path, const std::string &dbName) +{ + if (path.empty() || dbName.empty()) { + ZLOGW("The path or dbName is empty, path:%{public}s, dbName:%{public}s", path.c_str(), + Anonymous::Change(dbName).c_str()); + return false; + } + std::string flagFileName = path + "/" + dbName + DB_CORRUPTED_POSTFIX; + return access(flagFileName.c_str(), F_OK) == 0; +} + +bool CorruptReporter::DeleteCorruptedFlag(const std::string &path, const std::string &dbName) +{ + if (path.empty() || dbName.empty()) { + ZLOGW("The path or dbName is empty, path:%{public}s, dbName:%{public}s", path.c_str(), + Anonymous::Change(dbName).c_str()); + return false; + } + std::string flagFileName = path + "/" + dbName + DB_CORRUPTED_POSTFIX; + int result = remove(flagFileName.c_str()); + if (result != 0) { + ZLOGW("Remove corrupted flag fail, flagFileName:%{public}s, errno:%{public}d", + Anonymous::Change(flagFileName).c_str(), errno); + return false; + } + return true; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/rust/connect_adapter/BUILD.gn b/services/distributeddataservice/rust/connect_adapter/BUILD.gn index a5759ed585ba5a847f84558f59c830c8400eb731..377395b06ef5799c17347f70afbd05a328f03194 100644 --- a/services/distributeddataservice/rust/connect_adapter/BUILD.gn +++ b/services/distributeddataservice/rust/connect_adapter/BUILD.gn @@ -38,7 +38,6 @@ ohos_shared_library("conn_adapter") { external_deps = [ "ability_base:want", - "ability_runtime:ability_connect_callback_stub", "ability_runtime:extension_manager", "c_utils:utils", "hilog:libhilog", diff --git a/services/distributeddataservice/rust/extension/BUILD.gn b/services/distributeddataservice/rust/extension/BUILD.gn index cffbfca971c9d6f8ab4a3021e261c34cb8c9294b..302f89d6ae8a134e72da04fbb5b4b8f51cb83e98 100644 --- a/services/distributeddataservice/rust/extension/BUILD.gn +++ b/services/distributeddataservice/rust/extension/BUILD.gn @@ -56,7 +56,6 @@ ohos_shared_library("opencloudextension") { external_deps = [ "access_token:libaccesstoken_sdk", "hilog:libhilog", - "json:nlohmann_json_static", "kv_store:distributeddata_inner", ] subsystem_name = "distributeddatamgr" diff --git a/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp b/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp index fc42049721363bd52ea456965e617dc3683deeef..9d62cc7e10d5df567ca411db806f432f6b00760d 100644 --- a/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp +++ b/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp @@ -271,6 +271,7 @@ int32_t CloudCursorImpl::Get(const std::string &col, DBValue &value) auto it = std::find(names_.begin(), names_.end(), col); if (it == names_.end()) { value = GetExtend(vBucket, EXTEND_TO_KEYS[col]); + OhCloudExtValueBucketFree(vBucket); return DBErr::E_OK; } auto pair = GetData(vBucket); diff --git a/services/distributeddataservice/rust/extension/cloud_db_impl.cpp b/services/distributeddataservice/rust/extension/cloud_db_impl.cpp index 5b21555e858e690bf718b6c86bc0f5d1d24e9d78..da137619bfc423220f73d0095506c8fc6b57fc59 100644 --- a/services/distributeddataservice/rust/extension/cloud_db_impl.cpp +++ b/services/distributeddataservice/rust/extension/cloud_db_impl.cpp @@ -57,6 +57,8 @@ int32_t CloudDbImpl::BatchInsert(const std::string &table, DBVBuckets &&values, auto valIn = ExtensionUtil::Convert(std::move(inValues)); auto exdIn = ExtensionUtil::Convert(std::move(extends)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchInsert(database_, reinterpret_cast(table.c_str()), @@ -74,6 +76,8 @@ int32_t CloudDbImpl::BatchUpdate(const std::string &table, DBVBuckets &&values, auto exdIn = ExtensionUtil::Convert(std::move(extends)); auto valIn = ExtensionUtil::Convert(std::move(values)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchUpdate(database_, reinterpret_cast(table.c_str()), @@ -91,6 +95,8 @@ int32_t CloudDbImpl::BatchUpdate(const std::string &table, DBVBuckets &&values, auto exdIn = ExtensionUtil::Convert(std::move(const_cast(extends))); auto valIn = ExtensionUtil::Convert(std::move(values)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchUpdate(database_, reinterpret_cast(table.c_str()), diff --git a/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn b/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn index 71f5d359eb954cd071ba17a64c0ee209ab33da0e..4ac4309e2d1eaddbf0913f5d67b31a297be5cb77 100644 --- a/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn +++ b/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn @@ -22,7 +22,6 @@ ohos_rust_shared_ffi("ylong_cloud_extension") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" - branch_protector_ret = "pac_ret" sanitize = { cfi = true cfi_cross_dso = true diff --git a/services/distributeddataservice/service/BUILD.gn b/services/distributeddataservice/service/BUILD.gn index ea1225221899a806ac189377b4595f7e421b0874..4c04cb7e45a9510673290bdf528594c46c6a705b 100644 --- a/services/distributeddataservice/service/BUILD.gn +++ b/services/distributeddataservice/service/BUILD.gn @@ -68,6 +68,7 @@ ohos_shared_library("distributeddatasvc") { "${kv_store_distributeddb_path}", ] sources = [ + "${dataobject_path}/frameworks/innerkitsimpl/src/object_radar_reporter.cpp", "backup/src/backup_manager.cpp", "bootstrap/src/bootstrap.cpp", "cloud/cloud_service_impl.cpp", @@ -80,6 +81,7 @@ ohos_shared_library("distributeddatasvc") { "common/value_proxy.cpp", "common/xcollie.cpp", "config/src/config_factory.cpp", + "config/src/model/app_id_mapping_config.cpp", "config/src/model/backup_config.cpp", "config/src/model/checker_config.cpp", "config/src/model/cloud_config.cpp", @@ -107,6 +109,7 @@ ohos_shared_library("distributeddatasvc") { "object/object_asset_machine.cpp", "object/object_callback_proxy.cpp", "object/object_data_listener.cpp", + "object/object_dms_handler.cpp", "object/object_manager.cpp", "object/object_service_impl.cpp", "object/object_service_stub.cpp", @@ -131,6 +134,7 @@ ohos_shared_library("distributeddatasvc") { cflags = [ "-Wno-multichar", "-Wno-c99-designator", + "-D_LIBCPP_HAS_COND_CLOCKWAIT", ] cflags_cc = [ "-fvisibility=hidden" ] @@ -151,6 +155,7 @@ ohos_shared_library("distributeddatasvc") { "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", diff --git a/services/distributeddataservice/service/bootstrap/include/bootstrap.h b/services/distributeddataservice/service/bootstrap/include/bootstrap.h index 967ad0976e3fe9da45b7ace4171c6b30ba0a084d..50b86fd88dfa0ae9221c5c6fbf0c0f56b9e25c22 100644 --- a/services/distributeddataservice/service/bootstrap/include/bootstrap.h +++ b/services/distributeddataservice/service/bootstrap/include/bootstrap.h @@ -31,6 +31,7 @@ public: API_EXPORT void LoadDirectory(); API_EXPORT void LoadCloud(); API_EXPORT void LoadBackup(std::shared_ptr executors); + API_EXPORT void LoadAppIdMappings(); private: static constexpr const char *DEFAULT_LABEL = "distributeddata"; static constexpr const char *DEFAULT_META = "service_meta"; diff --git a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 8ef60d480e2152bf81dc0bcaafbf7e7fee2a1616..78974b4000b0756d0a2a6d6cb5f6acd057fb44b1 100644 --- a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -24,6 +24,7 @@ #include "config_factory.h" #include "directory/directory_manager.h" #include "log_print.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS { namespace DistributedData { Bootstrap &Bootstrap::GetInstance() @@ -60,6 +61,7 @@ void Bootstrap::LoadComponents() if (comp.lib.empty()) { continue; } + // no need to close the component, so we don't keep the handles auto handle = dlopen(comp.lib.c_str(), RTLD_LAZY); if (handle == nullptr) { @@ -167,5 +169,18 @@ void Bootstrap::LoadCloud() } CloudConfigManager::GetInstance().Initialize(infos); } + +void Bootstrap::LoadAppIdMappings() +{ + auto *appIdMapping = ConfigFactory::GetInstance().GetAppIdMappingConfig(); + if (appIdMapping == nullptr) { + return; + } + std::vector infos; + for (auto &info : *appIdMapping) { + infos.push_back({ info.srcAppId, info.dstAppId }); + } + AppIdMappingConfigManager::GetInstance().Initialize(infos); +} } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index 050509d39ae2ccbd9f783102aa0fb9686b78ad47..b2bf72f5bd480172c233ef920614b71cac1019d7 100644 --- a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -126,6 +126,7 @@ int32_t CloudServiceImpl::DisableCloud(const std::string &id) { auto tokenId = IPCSkeleton::GetCallingTokenID(); auto user = Account::GetInstance()->GetUserByToken(tokenId); + ReleaseUserInfo(user); std::lock_guard lock(rwMetaMutex_); auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { @@ -140,7 +141,7 @@ int32_t CloudServiceImpl::DisableCloud(const std::string &id) if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { return ERROR; } - Execute(GenTask(0, cloudInfo.user, { WORK_STOP_CLOUD_SYNC, WORK_RELEASE, WORK_SUB })); + Execute(GenTask(0, cloudInfo.user, { WORK_STOP_CLOUD_SYNC, WORK_SUB })); return SUCCESS; } @@ -150,17 +151,26 @@ int32_t CloudServiceImpl::ChangeAppSwitch(const std::string &id, const std::stri auto user = Account::GetInstance()->GetUserByToken(tokenId); std::lock_guard lock(rwMetaMutex_); auto [status, cloudInfo] = GetCloudInfo(user); - if (status != SUCCESS) { + if (status != SUCCESS || !cloudInfo.enableCloud) { return status; } - if (!cloudInfo.enableCloud) { - return SUCCESS; - } - if (cloudInfo.id != id || !cloudInfo.Exist(bundleName)) { - ZLOGE("invalid args, [input] id:%{public}s, [exist] id:%{public}s, bundleName:%{public}s", + if (cloudInfo.id != id) { + ZLOGW("invalid args, [input] id:%{public}s, [exist] id:%{public}s, bundleName:%{public}s", Anonymous::Change(id).c_str(), Anonymous::Change(cloudInfo.id).c_str(), bundleName.c_str()); + Execute(GenTask(0, cloudInfo.user, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB, + WORK_DO_CLOUD_SYNC })); return INVALID_ARGUMENT; } + if (!cloudInfo.Exist(bundleName)) { + std::tie(status, cloudInfo) = GetCloudInfoFromServer(user); + if (status != SUCCESS || !cloudInfo.enableCloud || cloudInfo.id != id || !cloudInfo.Exist(bundleName)) { + ZLOGE("invalid args, status:%{public}d, enableCloud:%{public}d, [input] id:%{public}s," + "[exist] id:%{public}s, bundleName:%{public}s", status, cloudInfo.enableCloud, + Anonymous::Change(id).c_str(), Anonymous::Change(cloudInfo.id).c_str(), bundleName.c_str()); + return INVALID_ARGUMENT; + } + ZLOGI("add app switch, bundleName:%{public}s", bundleName.c_str()); + } cloudInfo.apps[bundleName].cloudSwitch = (appSwitch == SWITCH_ON); if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { return ERROR; @@ -208,6 +218,11 @@ void CloudServiceImpl::DoClean(int32_t user, const SchemaMeta &schemaMeta, int32 ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); continue; } + DistributedData::StoreInfo storeInfo; + storeInfo.bundleName = meta.bundleName; + storeInfo.user = atoi(meta.user.c_str()); + storeInfo.storeName = meta.storeId; + EventCenter::GetInstance().PostEvent(std::make_unique(CloudEvent::CLEAN_DATA, storeInfo)); auto status = store->Clean({}, action, ""); if (status != E_OK) { ZLOGW("remove device data status:%{public}d, user:%{public}d, bundleName:%{public}s, " @@ -325,9 +340,6 @@ std::map> CloudServiceImpl::GetDbInfoFromE bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleName, int32_t triggerMode) { - if (triggerMode == MODE_UNLOCK && DeviceMatrix::GetInstance().IsConsistent()) { - return false; - } auto stores = CheckerManager::GetInstance().GetDynamicStores(); auto staticStores = CheckerManager::GetInstance().GetStaticStores(); stores.insert(stores.end(), staticStores.begin(), staticStores.end()); @@ -345,7 +357,9 @@ bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleNa } for (auto user : users) { for (const auto &store : stores) { - syncManager_.DoCloudSync(SyncManager::SyncInfo(user, store.bundleName, store.storeId, {}, triggerMode)); + int32_t mode = (store.bundleName != bundleName && triggerMode == MODE_PUSH) ? MODE_CONSISTENCY + : triggerMode; + syncManager_.DoCloudSync(SyncManager::SyncInfo(user, store.bundleName, store.storeId, {}, mode)); } } return found; @@ -381,28 +395,30 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &eventId, const std if (user == DEFAULT_USER) { continue; } + auto &bundleName = exData.info.bundleName; + auto &prepareTraceId = exData.info.context.prepareTraceId; auto [status, cloudInfo] = GetCloudInfoFromMeta(user); - if (CheckNotifyConditions(exData.info.accountId, exData.info.bundleName, cloudInfo) != E_OK) { - ZLOGD("invalid user:%{public}d", user); + if (CheckNotifyConditions(exData.info.accountId, bundleName, cloudInfo) != E_OK) { + ZLOGD("invalid user:%{public}d, traceId:%{public}s", user, prepareTraceId.c_str()); + syncManager_.Report({ user, bundleName, prepareTraceId, SyncStage::END, INVALID_ARGUMENT }); return INVALID_ARGUMENT; } - if (DoKvCloudSync(cloudInfo.user, exData.info.bundleName, MODE_PUSH)) { - continue; - } - auto schemaKey = CloudInfo::GetSchemaKey(user, exData.info.bundleName); + auto schemaKey = CloudInfo::GetSchemaKey(user, bundleName); SchemaMeta schemaMeta; if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { - ZLOGE("no exist meta, user:%{public}d", user); + ZLOGE("no exist meta, user:%{public}d, traceId:%{public}s", user, prepareTraceId.c_str()); + syncManager_.Report({ user, bundleName, prepareTraceId, SyncStage::END, INVALID_ARGUMENT }); return INVALID_ARGUMENT; } auto dbInfos = GetDbInfoFromExtraData(exData, schemaMeta); if (dbInfos.empty()) { - ZLOGE("GetDbInfoFromExtraData failed, empty database info."); + ZLOGE("GetDbInfoFromExtraData failed, empty database info. traceId:%{public}s.", prepareTraceId.c_str()); + syncManager_.Report({ user, bundleName, prepareTraceId, SyncStage::END, INVALID_ARGUMENT }); return INVALID_ARGUMENT; } for (const auto &dbInfo : dbInfos) { - syncManager_.DoCloudSync( - SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, dbInfo.first, dbInfo.second, MODE_PUSH)); + syncManager_.DoCloudSync(SyncManager::SyncInfo( + { cloudInfo.user, bundleName, dbInfo.first, dbInfo.second, MODE_PUSH, prepareTraceId })); } } return SUCCESS; @@ -524,7 +540,7 @@ std::pair> CloudServiceImpl::Quer int32_t CloudServiceImpl::SetGlobalCloudStrategy(Strategy strategy, const std::vector &values) { - if (strategy < Strategy::STRATEGY_HEAD || strategy >= Strategy::STRATEGY_BUTT) { + if (strategy >= Strategy::STRATEGY_BUTT) { ZLOGE("invalid strategy:%{public}d, size:%{public}zu", strategy, values.size()); return INVALID_ARGUMENT; } @@ -649,12 +665,6 @@ int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, c return E_OK; } -int32_t CloudServiceImpl::OnScreenUnlocked(int32_t user) -{ - DoKvCloudSync(user, "", MODE_UNLOCK); - return E_OK; -} - int32_t CloudServiceImpl::OnReady(const std::string& device) { if (device != DeviceManagerAdapter::CLOUD_DEVICE_UUID) { @@ -713,7 +723,7 @@ std::pair CloudServiceImpl::GetCloudInfoFromServer(int32_t u } cloudInfo = instance->GetServerInfo(cloudInfo.user); if (!cloudInfo.IsValid()) { - ZLOGE("cloud is empty, user%{public}d", cloudInfo.user); + ZLOGE("cloud is empty, user:%{public}d", cloudInfo.user); return { CLOUD_INFO_INVALID, cloudInfo }; } return { SUCCESS, cloudInfo }; @@ -736,7 +746,7 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user) ZLOGE("user:%{public}d, status:%{public}d", user, status); return false; } - ZLOGI("[server] id:%{public}s, enableCloud:%{pubic}d, user:%{public}d, app size:%{public}zu", + ZLOGI("[server] id:%{public}s, enableCloud:%{public}d, user:%{public}d, app size:%{public}zu", Anonymous::Change(cloudInfo.id).c_str(), cloudInfo.enableCloud, cloudInfo.user, cloudInfo.apps.size()); CloudInfo oldInfo; if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), oldInfo, true)) { @@ -763,7 +773,6 @@ bool CloudServiceImpl::UpdateSchema(int32_t user) { auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { - ZLOGE("user:%{public}d, status:%{public}d", user, status); return false; } auto keys = cloudInfo.GetSchemaKey(); @@ -772,7 +781,7 @@ bool CloudServiceImpl::UpdateSchema(int32_t user) std::tie(status, schemaMeta) = GetAppSchemaFromServer(user, bundle); if (status == NOT_SUPPORT) { ZLOGW("app not support, del cloudInfo! user:%{public}d, bundleName:%{public}s", user, bundle.c_str()); - MetaDataManager::GetInstance().DelMeta(cloudInfo.GetKey()); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetKey(), true); return false; } if (status != SUCCESS) { @@ -997,6 +1006,7 @@ bool CloudServiceImpl::ReleaseUserInfo(int32_t user) return true; } instance->ReleaseUserInfo(user); + ZLOGI("notify release user info, user:%{public}d", user); return true; } @@ -1414,7 +1424,7 @@ void CloudServiceImpl::InitSubTask(const Subscription &sub, uint64_t minInterval int32_t CloudServiceImpl::SetCloudStrategy(Strategy strategy, const std::vector &values) { - if (strategy < 0 || strategy >= Strategy::STRATEGY_BUTT) { + if (strategy >= Strategy::STRATEGY_BUTT) { ZLOGE("invalid strategy:%{public}d, size:%{public}zu", strategy, values.size()); return INVALID_ARGUMENT; } diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.h b/services/distributeddataservice/service/cloud/cloud_service_impl.h index 2f3315bed41cdfdd0ed52705e27d995392364e13..212b7780d55104c42e564bde3d37af56f54ed0f5 100644 --- a/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -68,7 +68,6 @@ public: int32_t OnInitialize() override; int32_t OnBind(const BindInfo &info) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; - int32_t OnScreenUnlocked(int32_t user) override; int32_t OnReady(const std::string &device) override; int32_t Offline(const std::string &device) override; diff --git a/services/distributeddataservice/service/cloud/sync_manager.cpp b/services/distributeddataservice/service/cloud/sync_manager.cpp index 4e32833fa7989862b95695873053bb80ebb17c65..54792b9e7285276a8d79400e0337b73b4e91e483 100644 --- a/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -24,6 +24,8 @@ #include "cloud/schema_meta.h" #include "cloud/sync_event.h" #include "cloud_value_util.h" +#include "cloud/cloud_lock_event.h" +#include "cloud/cloud_report.h" #include "device_manager_adapter.h" #include "dfx/radar_reporter.h" #include "eventcenter/event_center.h" @@ -68,6 +70,16 @@ SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, con syncId_ = SyncManager::GenerateId(user); } +SyncManager::SyncInfo::SyncInfo(const Param ¶m) + : user_(param.user), bundleName_(param.bundleName), triggerMode_(param.triggerMode) +{ + if (!param.store.empty()) { + tables_[param.store] = param.tables; + } + syncId_ = SyncManager::GenerateId(param.user); + prepareTraceId_ = param.prepareTraceId; +} + void SyncManager::SyncInfo::SetMode(int32_t mode) { mode_ = mode; @@ -140,8 +152,44 @@ bool SyncManager::SyncInfo::Contains(const std::string &storeName) return tables_.empty() || tables_.find(storeName) != tables_.end(); } +std::function SyncManager::GetLockChangeHandler() +{ + return [](const Event &event) { + auto &evt = static_cast(event); + auto storeInfo = evt.GetStoreInfo(); + auto callback = evt.GetCallback(); + if (callback == nullptr) { + ZLOGE("callback is nullptr. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + StoreMetaData meta(storeInfo); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + ZLOGE("not found meta. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + auto store = GetStore(meta, storeInfo.user); + if (store == nullptr) { + ZLOGE("failed to get store. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + if (evt.GetEventId() == CloudEvent::LOCK_CLOUD_CONTAINER) { + auto [result, expiredTime] = store->LockCloudDB(); + callback(result, expiredTime); + } else { + auto result = store->UnLockCloudDB(); + callback(result, 0); + } + }; +} + SyncManager::SyncManager() { + EventCenter::GetInstance().Subscribe(CloudEvent::LOCK_CLOUD_CONTAINER, GetLockChangeHandler()); + EventCenter::GetInstance().Subscribe(CloudEvent::UNLOCK_CLOUD_CONTAINER, GetLockChangeHandler()); EventCenter::GetInstance().Subscribe(CloudEvent::LOCAL_CHANGE, GetClientChangeHandler()); syncStrategy_ = std::make_shared(); auto metaName = Bootstrap::GetInstance().GetProcessLabel(); @@ -228,32 +276,41 @@ GeneralError SyncManager::IsValid(SyncInfo &info, CloudInfo &cloud) return E_OK; } -std::function SyncManager::GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, - SyncInfo &info, bool retry) +std::function SyncManager::GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, + SyncInfo &info, bool retry, const TraceIds &traceIds) { - return [this, &cloud, &info, &schemas, retry]() { + return [this, &cloud, &info, &schemas, retry, &traceIds]() { bool isPostEvent = false; for (auto &schema : schemas) { + auto it = traceIds.find(schema.bundleName); if (!cloud.IsOn(schema.bundleName)) { + UpdateFinishSyncInfo({ cloud.id, schema.bundleName, "" }, info.syncId_, E_ERROR); + Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END, + E_ERROR }); continue; } for (const auto &database : schema.databases) { if (!info.Contains(database.name)) { + UpdateFinishSyncInfo({ cloud.id, schema.bundleName, "" }, info.syncId_, E_ERROR); + Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END, + E_ERROR }); continue; } StoreInfo storeInfo = { 0, schema.bundleName, database.name, cloud.apps[schema.bundleName].instanceId, - info.user_, "", info.syncId_ }; + info.user_, "", info.syncId_ }; auto status = syncStrategy_->CheckSyncAction(storeInfo); if (status != SUCCESS) { ZLOGW("Verification strategy failed, status:%{public}d. %{public}d:%{public}s:%{public}s", status, storeInfo.user, storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str()); - QueryKey queryKey{ cloud.id, schema.bundleName, "" }; - UpdateFinishSyncInfo(queryKey, info.syncId_, E_BLOCKED_BY_NETWORK_STRATEGY); + UpdateFinishSyncInfo({ cloud.id, schema.bundleName, "" }, info.syncId_, status); + Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END, + status }); info.SetError(status); continue; } auto query = info.GenerateQuery(database.name, database.GetTableNames()); - SyncParam syncParam = { info.mode_, info.wait_, info.isCompensation_, info.triggerMode_ }; + SyncParam syncParam = { info.mode_, info.wait_, info.isCompensation_, info.triggerMode_, + it == traceIds.end() ? "" : it->second, cloud.user }; auto evt = std::make_unique(std::move(storeInfo), SyncEvent::EventInfo{ syncParam, retry, std::move(query), info.async_ }); EventCenter::GetInstance().PostEvent(std::move(evt)); @@ -264,7 +321,6 @@ std::function SyncManager::GetPostEventTask(const std::vectorsecond); BatchUpdateFinishState(cloudSyncInfos, E_CLOUD_DISABLED); + BatchReport(info.user_, traceIds, SyncStage::END, E_CLOUD_DISABLED); return; } } @@ -305,11 +367,8 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount if (createdByDefaultUser) { info.user_ = 0; } - auto task = GetPostEventTask(schemas, cloud, info, retry); - if (task != nullptr && task()) { - return; - } - BatchUpdateFinishState(cloudSyncInfos, E_ERROR); + auto task = GetPostEventTask(schemas, cloud, info, retry, traceIds); + task(); }; } @@ -319,35 +378,31 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) auto &evt = static_cast(event); auto &storeInfo = evt.GetStoreInfo(); GenAsync async = evt.GetAsyncDetail(); + auto prepareTraceId = evt.GetPrepareTraceId(); + auto user = evt.GetUser(); GenDetails details; auto &detail = details[SyncInfo::DEFAULT_ID]; detail.progress = GenProgress::SYNC_FINISH; - StoreMetaData meta(storeInfo); - meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { - meta.user = "0"; // check if it is a public store. - StoreMetaDataLocal localMetaData; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMetaData, true) || - !localMetaData.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { - ZLOGE("failed, no store meta. bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), - meta.GetStoreAlias().c_str()); - return DoExceptionalCallback(async, details, storeInfo); - } + auto [result, meta] = GetMetaData(storeInfo); + if (!result) { + return DoExceptionalCallback(async, details, storeInfo, prepareTraceId); } auto store = GetStore(meta, storeInfo.user); if (store == nullptr) { - ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); - return DoExceptionalCallback(async, details, storeInfo); + ZLOGE("store null, storeId:%{public}s, prepareTraceId:%{public}s", meta.GetStoreAlias().c_str(), + prepareTraceId.c_str()); + return DoExceptionalCallback(async, details, storeInfo, prepareTraceId); } - ZLOGD("database:<%{public}d:%{public}s:%{public}s> sync start", storeInfo.user, storeInfo.bundleName.c_str(), - meta.GetStoreAlias().c_str()); + ZLOGI("database:<%{public}d:%{public}s:%{public}s:%{public}s> sync start", storeInfo.user, + storeInfo.bundleName.c_str(), meta.GetStoreAlias().c_str(), prepareTraceId.c_str()); RadarReporter::Report( { storeInfo.bundleName.c_str(), CLOUD_SYNC, TRIGGER_SYNC, storeInfo.syncId, evt.GetTriggerMode() }, - "GetSyncHandler", BEGIN); - SyncParam syncParam = { evt.GetMode(), evt.GetWait(), evt.IsCompensation() }; - auto status = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()), - evt.AutoRetry() ? RetryCallback(storeInfo, retryer, evt.GetTriggerMode()) - : GetCallback(evt.GetAsyncDetail(), storeInfo, evt.GetTriggerMode()), + "GetSyncHandler", BizState::BEGIN); + Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::START, E_OK }); + SyncParam syncParam = { evt.GetMode(), evt.GetWait(), evt.IsCompensation(), MODE_DEFAULT, prepareTraceId }; + auto [status, dbCode] = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()), + evt.AutoRetry() ? RetryCallback(storeInfo, retryer, evt.GetTriggerMode(), prepareTraceId, user) + : GetCallback(evt.GetAsyncDetail(), storeInfo, evt.GetTriggerMode(), prepareTraceId, user), syncParam); if (status != E_OK) { if (async) { @@ -358,9 +413,10 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) if (status == GeneralError::E_NOT_SUPPORT) { return; } - int32_t errCode = status + GenStore::DB_ERR_OFFSET; + auto code = dbCode == 0 ? GenStore::CLOUD_ERR_OFFSET + status : dbCode; RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, - evt.GetTriggerMode(), false, errCode }, "GetSyncHandler", END); + evt.GetTriggerMode(), false, code }, "GetSyncHandler", BizState::END); + Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::END, code }); } }; } @@ -382,29 +438,35 @@ std::function SyncManager::GetClientChangeHandler() }; } -SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &syncInfo) +SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &syncInfo, int32_t user) { if (times >= RETRY_TIMES) { - return [info = SyncInfo(syncInfo)](Duration, int32_t code, int32_t dbCode) mutable { + return [this, user, info = SyncInfo(syncInfo)](Duration, int32_t code, int32_t dbCode, + const std::string &prepareTraceId) mutable { if (code == E_OK || code == E_SYNC_TASK_MERGED) { return true; } info.SetError(code); - RadarReporter::Report( - { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, false, dbCode }, - "GetRetryer", END); + RadarReporter::Report({ info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, + false, dbCode }, + "GetRetryer", BizState::END); + Report({ user, info.bundleName_, prepareTraceId, SyncStage::END, + dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode }); return true; }; } - return [this, times, info = SyncInfo(syncInfo)](Duration interval, int32_t code, int32_t dbCode) mutable { + return [this, times, user, info = SyncInfo(syncInfo)](Duration interval, int32_t code, int32_t dbCode, + const std::string &prepareTraceId) mutable { if (code == E_OK || code == E_SYNC_TASK_MERGED) { return true; } if (code == E_NO_SPACE_FOR_ASSET || code == E_RECODE_LIMIT_EXCEEDED) { info.SetError(code); - RadarReporter::Report( - { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, false, dbCode }, - "GetRetryer", END); + RadarReporter::Report({ info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, + false, dbCode }, + "GetRetryer", BizState::END); + Report({ user, info.bundleName_, prepareTraceId, SyncStage::END, + dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode }); return true; } @@ -532,6 +594,36 @@ AutoCache::Store SyncManager::GetStore(const StoreMetaData &meta, int32_t user, return store; } +void SyncManager::Report(const ReportParam &reportParam) +{ + auto cloudReport = CloudReport::GetInstance(); + if (cloudReport == nullptr) { + return; + } + cloudReport->Report(reportParam); +} + +SyncManager::TraceIds SyncManager::GetPrepareTraceId(const SyncInfo &info, const CloudInfo &cloud) +{ + TraceIds traceIds; + if (!info.prepareTraceId_.empty()) { + traceIds.emplace(info.bundleName_, info.prepareTraceId_); + return traceIds; + } + auto cloudReport = CloudReport::GetInstance(); + if (cloudReport == nullptr) { + return traceIds; + } + if (info.bundleName_.empty()) { + for (const auto &it : cloud.apps) { + traceIds.emplace(it.first, cloudReport->GetPrepareTraceId(info.user_)); + } + } else { + traceIds.emplace(info.bundleName_, cloudReport->GetPrepareTraceId(info.user_)); + } + return traceIds; +} + bool SyncManager::NeedGetCloudInfo(CloudInfo &cloud) { return (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true) || !cloud.enableCloud) && @@ -583,10 +675,7 @@ bool SyncManager::NeedSaveSyncInfo(const QueryKey &queryKey) if (queryKey.accountId.empty()) { return false; } - if (std::find(kvApps_.begin(), kvApps_.end(), queryKey.bundleName) != kvApps_.end()) { - return false; - } - return true; + return kvApps_.find(queryKey.bundleName) == kvApps_.end(); } int32_t SyncManager::QueryLastSyncInfo(const std::vector &queryKeys, QueryLastResults &results) @@ -641,9 +730,9 @@ void SyncManager::UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId } std::function SyncManager::GetCallback(const GenAsync &async, - const StoreInfo &storeInfo, int32_t triggerMode) + const StoreInfo &storeInfo, int32_t triggerMode, const std::string &prepareTraceId, int32_t user) { - return [this, async, storeInfo, triggerMode](const GenDetails &result) { + return [this, async, storeInfo, triggerMode, prepareTraceId, user](const GenDetails &result) { if (async != nullptr) { async(result); } @@ -657,8 +746,15 @@ std::function SyncManager::GetCallback(const Gen return; } + int32_t dbCode = (result.begin()->second.dbCode == GenStore::DB_ERR_OFFSET) ? 0 : result.begin()->second.dbCode; + RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, triggerMode, + result.begin()->second.changeCount, dbCode }, + "GetCallback", BizState::END); + Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::END, dbCode }); + auto id = GetAccountId(storeInfo.user); if (id.empty()) { + ZLOGD("account id is empty"); return; } QueryKey queryKey{ @@ -668,11 +764,7 @@ std::function SyncManager::GetCallback(const Gen }; int32_t code = result.begin()->second.code; - int32_t dbCode = (result.begin()->second.dbCode == GenStore::DB_ERR_OFFSET) ? 0 : result.begin()->second.dbCode; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); - RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, triggerMode, - result.begin()->second.dataChange, dbCode }, - "GetCallback", END); }; } @@ -707,7 +799,8 @@ std::vector SyncManager::GetSchemaMeta(const CloudInfo &cloud, const return schemas; } -void SyncManager::DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo) +void SyncManager::DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo, + const std::string &prepareTraceId) { if (async) { details[SyncInfo::DEFAULT_ID].code = E_ERROR; @@ -715,6 +808,7 @@ void SyncManager::DoExceptionalCallback(const GenAsync &async, GenDetails &detai } QueryKey queryKey{ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, E_ERROR); + Report({ storeInfo.user, storeInfo.bundleName, prepareTraceId, SyncStage::END, E_ERROR }); } bool SyncManager::InitDefaultUser(int32_t &user) @@ -730,10 +824,10 @@ bool SyncManager::InitDefaultUser(int32_t &user) return true; } -std::function SyncManager::RetryCallback( - const StoreInfo &storeInfo, Retryer retryer, int32_t triggerMode) +std::function SyncManager::RetryCallback(const StoreInfo &storeInfo, + Retryer retryer, int32_t triggerMode, const std::string &prepareTraceId, int32_t user) { - return [this, retryer, storeInfo, triggerMode](const GenDetails &details) { + return [this, retryer, storeInfo, triggerMode, prepareTraceId, user](const GenDetails &details) { if (details.empty()) { ZLOGE("retry, details empty"); return; @@ -745,11 +839,13 @@ std::function SyncManager::Retr UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); if (code == E_OK) { RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, - triggerMode, details.begin()->second.dataChange }, - "RetryCallback", END); + triggerMode, details.begin()->second.changeCount }, + "RetryCallback", BizState::END); + Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::END, + dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode }); } } - retryer(GetInterval(code), code, dbCode); + retryer(GetInterval(code), code, dbCode, prepareTraceId); }; } @@ -761,4 +857,27 @@ void SyncManager::BatchUpdateFinishState(const std::vector SyncManager::GetMetaData(const StoreInfo &storeInfo) +{ + StoreMetaData meta(storeInfo); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + meta.user = "0"; // check if it is a public store. + StoreMetaDataLocal localMetaData; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMetaData, true) || + !localMetaData.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + ZLOGE("failed, no store meta. bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + return { false, meta }; + } + } + return { true, meta }; +} } // namespace OHOS::CloudData \ No newline at end of file diff --git a/services/distributeddataservice/service/cloud/sync_manager.h b/services/distributeddataservice/service/cloud/sync_manager.h index ccbee00824bb4d7a74579412e94ae02a7ab4358b..29488624b73d3521d9fc7ec6a05bf613aca1ef6a 100644 --- a/services/distributeddataservice/service/cloud/sync_manager.h +++ b/services/distributeddataservice/service/cloud/sync_manager.h @@ -39,17 +39,29 @@ public: using AutoCache = DistributedData::AutoCache; using StoreMetaData = DistributedData::StoreMetaData; using SchemaMeta = DistributedData::SchemaMeta; + using TraceIds = std::map; + using SyncStage = DistributedData::SyncStage; + using ReportParam = DistributedData::ReportParam; static AutoCache::Store GetStore(const StoreMetaData &meta, int32_t user, bool mustBind = true); class SyncInfo final { public: using Store = std::string; using Stores = std::vector; using Tables = std::vector; + struct Param { + int32_t user; + std::string bundleName; + Store store; + Tables tables; + int32_t triggerMode = 0; + std::string prepareTraceId; + }; using MutliStoreTables = std::map; explicit SyncInfo(int32_t user, const std::string &bundleName = "", const Store &store = "", const Tables &tables = {}, int32_t triggerMode = 0); SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores); SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables); + explicit SyncInfo(const Param ¶m); void SetMode(int32_t mode); void SetWait(int32_t wait); void SetAsyncDetail(GenAsync asyncDetail); @@ -57,6 +69,7 @@ public: void SetError(int32_t code) const; void SetCompensation(bool isCompensation); void SetTriggerMode(int32_t triggerMode); + void SetPrepareTraceId(const std::string &prepareTraceId); std::shared_ptr GenerateQuery(const std::string &store, const Tables &tables); bool Contains(const std::string &storeName); inline static constexpr const char *DEFAULT_ID = "default"; @@ -74,6 +87,7 @@ public: std::shared_ptr query_; bool isCompensation_ = false; int32_t triggerMode_ = 0; + std::string prepareTraceId_; }; SyncManager(); ~SyncManager(); @@ -81,13 +95,15 @@ public: int32_t DoCloudSync(SyncInfo syncInfo); int32_t StopCloudSync(int32_t user = 0); int32_t QueryLastSyncInfo(const std::vector &queryKeys, QueryLastResults &results); + void Report(const ReportParam &reportParam); private: using Event = DistributedData::Event; using Task = ExecutorPool::Task; using TaskId = ExecutorPool::TaskId; using Duration = ExecutorPool::Duration; - using Retryer = std::function; + using Retryer = + std::function; using CloudInfo = DistributedData::CloudInfo; using StoreInfo = DistributedData::StoreInfo; using SyncStrategy = DistributedData::SyncStrategy; @@ -117,24 +133,29 @@ private: void UpdateSchema(const SyncInfo &syncInfo); std::function GetSyncHandler(Retryer retryer); std::function GetClientChangeHandler(); - Retryer GetRetryer(int32_t times, const SyncInfo &syncInfo); + Retryer GetRetryer(int32_t times, const SyncInfo &syncInfo, int32_t user); RefCount GenSyncRef(uint64_t syncId); int32_t Compare(uint64_t syncId, int32_t user); GeneralError IsValid(SyncInfo &info, CloudInfo &cloud); void UpdateStartSyncInfo(const std::vector> &cloudSyncInfos); void UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code); std::function GetCallback(const GenAsync &async, - const StoreInfo &storeInfo, int32_t triggerMode); - std::function GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, - bool retry); - void DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo); + const StoreInfo &storeInfo, int32_t triggerMode, const std::string &prepareTraceId, int32_t user); + std::function GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, + bool retry, const TraceIds &traceIds); + void DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo, + const std::string &prepareTraceId); bool InitDefaultUser(int32_t &user); - std::function RetryCallback( - const StoreInfo &storeInfo, Retryer retryer, int32_t triggerMode); + std::function RetryCallback(const StoreInfo &storeInfo, + Retryer retryer, int32_t triggerMode, const std::string &prepareTraceId, int32_t user); static void GetLastResults( const std::string &storeId, std::map &infos, QueryLastResults &results); void BatchUpdateFinishState(const std::vector> &cloudSyncInfos, int32_t code); bool NeedSaveSyncInfo(const QueryKey &queryKey); + std::function GetLockChangeHandler(); + void BatchReport(int32_t userId, const TraceIds &traceIds, SyncStage syncStage, int32_t errCode); + TraceIds GetPrepareTraceId(const SyncInfo &info, const CloudInfo &cloud); + std::pair GetMetaData(const StoreInfo &storeInfo); static std::atomic genId_; std::shared_ptr executor_; diff --git a/services/distributeddataservice/service/config/include/config_factory.h b/services/distributeddataservice/service/config/include/config_factory.h index e6e4025c67e930ead2e48498875bb0aeb4d677ac..6ebb1e0db025495eb261667e8bbb23d845dc8466 100644 --- a/services/distributeddataservice/service/config/include/config_factory.h +++ b/services/distributeddataservice/service/config/include/config_factory.h @@ -31,6 +31,7 @@ public: API_EXPORT DirectoryConfig *GetDirectoryConfig(); API_EXPORT BackupConfig *GetBackupConfig(); API_EXPORT CloudConfig *GetCloudConfig(); + API_EXPORT std::vector *GetAppIdMappingConfig(); private: static constexpr const char *CONF_PATH = "/system/etc/distributeddata/conf"; ConfigFactory(); diff --git a/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h b/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h new file mode 100644 index 0000000000000000000000000000000000000000..a0ff96a34640a66077dc4b268ec1359c860ca7bb --- /dev/null +++ b/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H + +#include "serializable/serializable.h" +namespace OHOS { +namespace DistributedData { +class AppIdMappingConfig final : public Serializable { +public: + std::string srcAppId = ""; + std::string dstAppId = ""; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; +} // namespace DistributedData +} // namespace OHOS +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H diff --git a/services/distributeddataservice/service/config/include/model/global_config.h b/services/distributeddataservice/service/config/include/model/global_config.h index c96926e4f5e7d458e058ccf6ef5e73f794743bda..0d974d5bec9b6930904aaa3bbd1a2f962593fa5c 100644 --- a/services/distributeddataservice/service/config/include/model/global_config.h +++ b/services/distributeddataservice/service/config/include/model/global_config.h @@ -22,6 +22,7 @@ #include "model/network_config.h" #include "model/directory_config.h" #include "model/backup_config.h" +#include "model/app_id_mapping_config.h" namespace OHOS { namespace DistributedData { class GlobalConfig final : public Serializable { @@ -36,6 +37,7 @@ public: DirectoryConfig *directory = nullptr; BackupConfig *backup = nullptr; CloudConfig *cloud = nullptr; + std::vector *appIdMapping = nullptr; ~GlobalConfig(); bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; diff --git a/services/distributeddataservice/service/config/src/config_factory.cpp b/services/distributeddataservice/service/config/src/config_factory.cpp index 733ab0ea95a4eb88e4933481456035b40595c4fa..996f6e585bde9141a1a0e956860a1cb16ad0d99a 100644 --- a/services/distributeddataservice/service/config/src/config_factory.cpp +++ b/services/distributeddataservice/service/config/src/config_factory.cpp @@ -82,5 +82,10 @@ CloudConfig *ConfigFactory::GetCloudConfig() { return config_.cloud; } + +std::vector *ConfigFactory::GetAppIdMappingConfig() +{ + return config_.appIdMapping; +} } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp b/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..001336e61e656c721499af1ce77c3bd6839882d9 --- /dev/null +++ b/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "model/app_id_mapping_config.h" +namespace OHOS { +namespace DistributedData { +bool AppIdMappingConfig::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(srcAppId)], srcAppId); + SetValue(node[GET_NAME(dstAppId)], dstAppId); + return true; +} +bool AppIdMappingConfig::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(srcAppId), srcAppId); + GetValue(node, GET_NAME(dstAppId), dstAppId); + return true; +} +} // namespace DistributedData +} // namespace OHOS diff --git a/services/distributeddataservice/service/config/src/model/global_config.cpp b/services/distributeddataservice/service/config/src/model/global_config.cpp index b3078891e9d5fb031ac1ba036e560ad8ec2722b8..d4ee79710b9cedcc9f8581b168b2d3301693c135 100644 --- a/services/distributeddataservice/service/config/src/model/global_config.cpp +++ b/services/distributeddataservice/service/config/src/model/global_config.cpp @@ -28,6 +28,7 @@ bool GlobalConfig::Marshal(json &node) const SetValue(node[GET_NAME(directory)], directory); SetValue(node[GET_NAME(backup)], backup); SetValue(node[GET_NAME(cloud)], cloud); + SetValue(node[GET_NAME(appIdMapping)], appIdMapping); return true; } @@ -43,6 +44,7 @@ bool GlobalConfig::Unmarshal(const json &node) GetValue(node, GET_NAME(directory), directory); GetValue(node, GET_NAME(backup), backup); GetValue(node, GET_NAME(cloud), cloud); + GetValue(node, GET_NAME(appIdMapping), appIdMapping); return true; } @@ -54,6 +56,7 @@ GlobalConfig::~GlobalConfig() delete directory; delete backup; delete cloud; + delete appIdMapping; } } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/service/data_share/BUILD.gn b/services/distributeddataservice/service/data_share/BUILD.gn index ff8b1a46d30ffea7d77ab2c638ee722a73520382..17b71aabac6101e8eac7ec452bb348bd7757865b 100644 --- a/services/distributeddataservice/service/data_share/BUILD.gn +++ b/services/distributeddataservice/service/data_share/BUILD.gn @@ -20,6 +20,7 @@ config("module_public_config") { "strategies", "common", "data", + "dfx", "../../adapter/include", "../../app/src", "../../framework/include", @@ -69,6 +70,8 @@ ohos_shared_library("data_share_service") { "data_share_service_stub.cpp", "data_share_silent_config.cpp", "data_share_types_util.cpp", + "dfx/hiview_adapter.cpp", + "dfx/hiview_fault_adapter.cpp", "strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", "strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", "strategies/general/check_is_data_proxy_strategy.cpp", @@ -87,7 +90,10 @@ ohos_shared_library("data_share_service") { "subscriber_managers/rdb_subscriber_manager.cpp", "sys_event_subscriber.cpp", ] - cflags = [ "-Wno-multichar" ] + cflags = [ + "-Wno-multichar", + "-D_LIBCPP_HAS_COND_CLOCKWAIT", + ] cflags_cc = [ "-fvisibility=hidden" ] @@ -101,9 +107,9 @@ ohos_shared_library("data_share_service") { ] external_deps = [ + "ability_base:base", "ability_base:want", "ability_base:zuri", - "ability_runtime:ability_connect_callback_stub", "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "ability_runtime:wantagent_innerkits", diff --git a/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp index dec8551caa0b349d709dd9a97ff697e9fdc60dc4..03e91f19bacd6af3b5bd88a9c06b37fcb9f743c0 100644 --- a/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp +++ b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp @@ -62,9 +62,12 @@ sptr BundleMgrProxy::CheckBMS() } int BundleMgrProxy::GetBundleInfoFromBMS( - const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig) + const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig, int32_t appIndex) { - auto bundleKey = bundleName + std::to_string(userId); + std::string bundleKey = bundleName + std::to_string(userId); + if (appIndex != 0) { + bundleKey += "appIndex" + std::to_string(appIndex); + } auto it = bundleCache_.Find(bundleKey); if (it.first) { bundleConfig = it.second; @@ -78,8 +81,24 @@ int BundleMgrProxy::GetBundleInfoFromBMS( return E_BMS_NOT_READY; } AppExecFwk::BundleInfo bundleInfo; - bool ret = bmsClient->GetBundleInfo( - bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); + bool ret; + if (appIndex == 0) { + ret = bmsClient->GetBundleInfo( + bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); + } else { + ret = bmsClient->GetCloneBundleInfo( + bundleName, static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) | + static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE), + appIndex, bundleInfo, userId); + // when there is no error, the former function returns 1 while the new function returns 0 + ret = !ret; + for (auto &item : bundleInfo.hapModuleInfos) { + for (auto &item2 : item.extensionInfos) { + bundleInfo.extensionInfos.push_back(item2); + } + } + } + if (!ret) { RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BUNDLE_INFP_FAILED); @@ -115,9 +134,13 @@ BundleMgrProxy::~BundleMgrProxy() } } -void BundleMgrProxy::Delete(const std::string &bundleName, int32_t userId) +void BundleMgrProxy::Delete(const std::string &bundleName, int32_t userId, int32_t appIndex) { - bundleCache_.Erase(bundleName + std::to_string(userId)); + if (appIndex != 0) { + bundleCache_.Erase(bundleName + std::to_string(userId) + "appIndex" + std::to_string(appIndex)); + } else { + bundleCache_.Erase(bundleName + std::to_string(userId)); + } return; } diff --git a/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h index 9b4b325cac565a22567387de6bb53d57d6a3b898..75edf5bbfd6ca0d05563f6104a56dc6d7a829162 100644 --- a/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h +++ b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h @@ -65,8 +65,9 @@ class BundleMgrProxy final : public std::enable_shared_from_this public: ~BundleMgrProxy(); static std::shared_ptr GetInstance(); - int GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig); - void Delete(const std::string &bundleName, int32_t userId); + int GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, + BundleConfig &bundleConfig, int32_t appIndex = 0); + void Delete(const std::string &bundleName, int32_t userId, int32_t appIndex); sptr CheckBMS(); private: diff --git a/services/distributeddataservice/service/data_share/common/context.h b/services/distributeddataservice/service/data_share/common/context.h index 25995eaa064c8741f80251cfc2e80874f6fa15d8..71988eb20eedd5323afde3da7a7307b7a15a3d1f 100644 --- a/services/distributeddataservice/service/data_share/common/context.h +++ b/services/distributeddataservice/service/data_share/common/context.h @@ -37,6 +37,7 @@ public: virtual ~Context() = default; std::string uri; int32_t currentUserId = -1; + int32_t appIndex = 0; std::string permission; uint32_t callerTokenId = 0; std::string callerBundleName; diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 34632fa7b9be3fa611475dc4794681f69b231b36..f9ba94f047fb3fd9eef242af3d1c578f67f7d681 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -23,21 +23,22 @@ namespace OHOS::DataShare { ExecutorPool::TaskId DBDelegate::taskId_ = ExecutorPool::INVALID_TASK_ID; ConcurrentMap>> DBDelegate::stores_ = {}; std::shared_ptr DBDelegate::executor_ = nullptr; -std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &metaData) +std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &metaData, + const std::string &extUri, const std::string &backup) { if (metaData.tokenId == 0) { - return std::make_shared(metaData, NO_CHANGE_VERSION, true); + return std::make_shared(metaData, NO_CHANGE_VERSION, true, extUri, backup); } std::shared_ptr store; stores_.Compute(metaData.tokenId, - [&metaData, &store](auto &, std::map> &stores) -> bool { + [&metaData, &store, extUri, &backup](auto &, std::map> &stores) -> bool { auto it = stores.find(metaData.storeId); if (it != stores.end()) { store = it->second->store_; - it->second->time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + it->second->time_ = std::chrono::steady_clock::now() + std::chrono::seconds(INTERVAL); return !stores.empty(); } - store = std::make_shared(metaData, NO_CHANGE_VERSION, true); + store = std::make_shared(metaData, NO_CHANGE_VERSION, true, extUri, backup); if (store->IsInvalid()) { store = nullptr; ZLOGE("creator failed, storeName: %{public}s", metaData.GetStoreAlias().c_str()); @@ -89,14 +90,14 @@ void DBDelegate::StartTimer() taskId_ = Executor::INVALID_TASK_ID; }); }, - std::chrono::minutes(INTERVAL), std::chrono::minutes(INTERVAL)); + std::chrono::seconds(INTERVAL), std::chrono::seconds(INTERVAL)); ZLOGD("start timer, taskId: %{public}" PRIu64, taskId_); } DBDelegate::Entity::Entity(std::shared_ptr store) { store_ = std::move(store); - time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + time_ = std::chrono::steady_clock::now() + std::chrono::seconds(INTERVAL); } void DBDelegate::EraseStoreCache(const int32_t tokenId) diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.h b/services/distributeddataservice/service/data_share/common/db_delegate.h index 4627dde4b9d965579199c08ab030db5fc6570453..d2e79fd67ec055d64699c1da92aff0126f737bd8 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -24,6 +24,7 @@ #include "datashare_result_set.h" #include "datashare_values_bucket.h" #include "executor_pool.h" +#include "hiview_fault_adapter.h" #include "metadata/store_meta_data.h" #include "result_set.h" #include "serializable/serializable.h" @@ -32,20 +33,27 @@ namespace OHOS::DataShare { class DBDelegate { public: using Time = std::chrono::steady_clock::time_point; - static std::shared_ptr Create(DistributedData::StoreMetaData &metaData); + static std::shared_ptr Create(DistributedData::StoreMetaData &metaData, + const std::string &extUri = "", const std::string &backup = ""); virtual int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) = 0; virtual std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, - const int32_t callingPid) = 0; + int32_t callingPid, uint32_t callingTokenId) = 0; virtual std::string Query( const std::string &sql, const std::vector &selectionArgs = std::vector()) = 0; virtual std::shared_ptr QuerySql(const std::string &sql) = 0; virtual bool IsInvalid() = 0; static void SetExecutorPool(std::shared_ptr executor); static void EraseStoreCache(const int32_t tokenId); + virtual std::pair InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair UpdateEx(const std::string &tableName, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair DeleteEx(const std::string &tableName, + const DataSharePredicates &predicate) = 0; private: static void GarbageCollect(); static void StartTimer(); @@ -55,7 +63,7 @@ private: Time time_; }; static constexpr int NO_CHANGE_VERSION = -1; - static constexpr int64_t INTERVAL = 1; //min + static constexpr int64_t INTERVAL = 20; //seconds static ConcurrentMap>> stores_; static std::shared_ptr executor_; static ExecutorPool::TaskId taskId_; @@ -122,6 +130,7 @@ public: std::string &result) = 0; virtual int32_t GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, std::vector &result) = 0; + virtual void NotifyBackup() = 0; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_DB_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp b/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp index ff74c826133142ad28e98d4c43d4046a9dc5a805..2328285df370c1f67f2b2bcc51788ba1d3e28416 100644 --- a/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp +++ b/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp @@ -34,7 +34,7 @@ void ExtensionAbilityManager::SetExecutorPool(std::shared_ptr exec } int32_t ExtensionAbilityManager::ConnectExtension(const std::string &uri, const std::string &bundleName, - const sptr &callback) + const sptr &callback, AAFwk::WantParams &wantParams) { auto absent = connectCallbackCache_.ComputeIfAbsent(bundleName, [callback](const std::string &) { return std::move(callback); @@ -44,7 +44,7 @@ int32_t ExtensionAbilityManager::ConnectExtension(const std::string &uri, const bundleName.c_str(), URIUtils::Anonymous(uri).c_str()); return E_ERROR; } - ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(uri, callback, nullptr); + ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(uri, callback, nullptr, wantParams); if (ret != E_OK) { ZLOGE("Connect ability failed, ret:%{public}d, uri:%{public}s, bundleName:%{public}s", ret, URIUtils::Anonymous(uri).c_str(), bundleName.c_str()); diff --git a/services/distributeddataservice/service/data_share/common/extension_ability_manager.h b/services/distributeddataservice/service/data_share/common/extension_ability_manager.h index 9f8031c25da335685c3a1de55f404cf7311b09b9..a78e4e20cac0d275089080e5fe3f088161cede3d 100644 --- a/services/distributeddataservice/service/data_share/common/extension_ability_manager.h +++ b/services/distributeddataservice/service/data_share/common/extension_ability_manager.h @@ -19,6 +19,7 @@ #include "concurrent_map.h" #include "executor_pool.h" #include "iremote_object.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionAbilityManager { @@ -26,7 +27,7 @@ public: static ExtensionAbilityManager &GetInstance(); void SetExecutorPool(std::shared_ptr executor); int32_t ConnectExtension(const std::string &uri, const std::string &bundleName, - const sptr &callback); + const sptr &callback, AAFwk::WantParams &wantParams); void DelayDisconnect(const std::string &bundleName); private: diff --git a/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp index f6a7bc87c86658a1f922543bb171af6d9e7a4cf3..5578adbc1f97de0d12971a6ed0a85acbc7249e0a 100644 --- a/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp +++ b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp @@ -32,13 +32,15 @@ ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(std::make_sharedClear(); if (callback_ == nullptr) { return false; } - ErrCode ret = ExtensionAbilityManager::GetInstance().ConnectExtension(uri, bundleName, callback_->AsObject()); + ErrCode ret = ExtensionAbilityManager::GetInstance().ConnectExtension(uri, bundleName, + callback_->AsObject(), wantParams); if (ret != ERR_OK) { ZLOGE("connect ability failed, ret = %{public}d, uri: %{public}s", ret, URIUtils::Anonymous(uri).c_str()); @@ -51,13 +53,13 @@ bool ExtensionConnectAdaptor::DoConnect(const std::string &uri, const std::strin } bool ExtensionConnectAdaptor::TryAndWait(const std::string &uri, const std::string &bundleName, - int maxWaitTime) + AAFwk::WantParams &wantParams, int maxWaitTime) { ExtensionConnectAdaptor strategy; return AppConnectManager::Wait( bundleName, maxWaitTime, - [&uri, &bundleName, &strategy]() { - return strategy.DoConnect(uri, bundleName); + [&uri, &bundleName, &strategy, &wantParams]() { + return strategy.DoConnect(uri, bundleName, wantParams); }, [&strategy]() { strategy.Disconnect(); diff --git a/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h index 0226e72053e64c28879f7ce56cfd1d0cef4b76e5..dc81093b4c9ea434d75363a7b1bc3b6d000b9bf6 100644 --- a/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h +++ b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h @@ -19,15 +19,16 @@ #include "ability_connect_callback_interface.h" #include "block_data.h" #include "context.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionConnectAdaptor { public: - static bool TryAndWait(const std::string &uri, const std::string &bundleName, + static bool TryAndWait(const std::string &uri, const std::string &bundleName, AAFwk::WantParams &wantParams, int maxWaitTime = 2); ExtensionConnectAdaptor(); private: void Disconnect(); - bool DoConnect(const std::string &uri, const std::string &bundleName); + bool DoConnect(const std::string &uri, const std::string &bundleName, AAFwk::WantParams &wantParams); std::shared_ptr> data_; sptr callback_ = nullptr; }; diff --git a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp index 3303346e9a23b2e79349a56551d811950e7938d9..dacd6ce8826dc757ba5b0839b4d41bc2d3ecd8c0 100644 --- a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp +++ b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp @@ -23,6 +23,9 @@ #include "log_print.h" #include "system_ability_definition.h" #include "want.h" +#include "uri_utils.h" +#include "datashare_errno.h" + namespace OHOS::DataShare { void ExtensionMgrProxy::OnProxyDied() { @@ -49,13 +52,20 @@ std::shared_ptr ExtensionMgrProxy::GetInstance() } int ExtensionMgrProxy::Connect( - const std::string &uri, const sptr &connect, const sptr &callerToken) + const std::string &uri, const sptr &connect, const sptr &callerToken, + AAFwk::WantParams &wantParams) { AAFwk::Want want; - want.SetUri(uri); + auto [success, userId] = URIUtils::GetUserFromProxyURI(uri); + if (!success) { + return E_INVALID_USER_ID; + } + want.SetUri(URIUtils::FormatConstUri(uri)); + want.SetParams(wantParams); std::lock_guard lock(mutex_); if (ConnectSA()) { - int ret = proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); + int ret = proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE, + userId); if (ret != ERR_OK) { ZLOGE("ConnectAbilityCommon failed, %{public}d", ret); } diff --git a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h index a93a4c903b98086b7cc028f0770c495708d40217..21bda2ddb44049777f2843c05e6edc56e25f2309 100644 --- a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h +++ b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h @@ -20,6 +20,7 @@ #include #include "extension_manager_proxy.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionMgrProxy final : public std::enable_shared_from_this { public: @@ -27,7 +28,8 @@ public: ExtensionMgrProxy() = default; ~ExtensionMgrProxy(); static std::shared_ptr GetInstance(); - int Connect(const std::string &uri, const sptr &connect, const sptr &callerToken); + int Connect(const std::string &uri, const sptr &connect, + const sptr &callerToken, AAFwk::WantParams &wantParams); int DisConnect(sptr connect); private: using Proxy = AAFwk::ExtensionManagerProxy; diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.cpp b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp index 5fcd2b11219869116dee5ad38e5422b1457ab9eb..23aa6a6119c406daf5700de16df913598af56b33 100644 --- a/services/distributeddataservice/service/data_share/common/kv_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,6 +13,12 @@ * limitations under the License. */ #define LOG_TAG "KvAdaptor" + +#include +#include +#include +#include + #include "kv_delegate.h" #include "datashare_errno.h" @@ -24,6 +30,103 @@ namespace OHOS::DataShare { constexpr int WAIT_TIME = 30; + +// If using multi-process access, back up dataShare.db.map as well. Check config file to see whether +// using multi-process maccess +const char* g_backupFiles[] = { + "dataShare.db", + "dataShare.db.redo", + "dataShare.db.safe", + "dataShare.db.undo", +}; +const char* BACKUP_SUFFIX = ".backup"; + +// If isBackUp is true, remove db backup files. Otherwise remove source db files. +void KvDelegate::RemoveDbFile(bool isBackUp) +{ + for (auto &fileName: g_backupFiles) { + std::string dbPath = path_ + "/" + fileName; + if (isBackUp) { + dbPath += BACKUP_SUFFIX; + } + if (std::filesystem::exists(dbPath)) { + std::error_code ec; + bool success = std::filesystem::remove(dbPath, ec); + if (!success) { + ZLOGE("failed to remove file %{public}s, err: %{public}s", fileName, ec.message().c_str()); + } + } + } +} + +bool KvDelegate::CopyFile(bool isBackup) +{ + std::filesystem::copy_options options = std::filesystem::copy_options::overwrite_existing; + std::error_code code; + bool ret = true; + for (auto &fileName : g_backupFiles) { + std::string src = path_ + "/" + fileName; + std::string dst = src; + isBackup ? dst.append(BACKUP_SUFFIX) : src.append(BACKUP_SUFFIX); + // If src doesn't exist, error will be returned through `std::error_code` + bool copyRet = std::filesystem::copy_file(src, dst, options, code); + if (!copyRet) { + ZLOGE("failed to copy file %{public}s, isBackup %{public}d, err: %{public}s", + fileName, isBackup, code.message().c_str()); + ret = false; + RemoveDbFile(isBackup); + break; + } + } + return ret; +} + +// Restore database data when it is broken somehow. Some failure of insertion / deletion / updates will be considered +// as database files damage, and therefore trigger the process of restoration. +void KvDelegate::Restore() +{ + // No need to lock because this inner method will only be called when upper methods lock up + CopyFile(false); + ZLOGD("finish restoring kv"); +} + +// Backup database data by copying its key files. This mechanism might be costly, but acceptable when updating +// contents of KV database happens not so frequently now. +void KvDelegate::Backup() +{ + // No need to lock because this inner method will only be called when upper methods lock up + ZLOGD("backup kv"); + if (hasChange_) { + CopyFile(true); + hasChange_ = false; + } + ZLOGD("finish backing up kv"); +} + +// Set hasChange_ to true. Caller can use this to control when to back up db. +void OHOS::DataShare::KvDelegate::NotifyBackup() +{ + std::lock_guard lock(mutex_); + hasChange_ = true; +} + +// The return val indicates whether the database has been restored +bool KvDelegate::RestoreIfNeed(int32_t dbStatus) +{ + // No need to lock because this inner method will only be called when upper methods lock up + if (dbStatus == GRD_INVALID_FILE_FORMAT || dbStatus == GRD_REBUILD_DATABASE) { + if (db_ != NULL) { + GRD_DBClose(db_, GRD_DB_CLOSE); + db_ = nullptr; + isInitDone_ = false; + } + // If db is NULL, it has been closed. + Restore(); + return true; + } + return false; +} + int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string &filter, const std::string &value) { std::lock_guard lock(mutex_); @@ -34,6 +137,7 @@ int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string int count = GRD_UpsertDoc(db_, collectionName.c_str(), filter.c_str(), value.c_str(), 0); if (count <= 0) { ZLOGE("GRD_UpSertDoc failed,status %{public}d", count); + RestoreIfNeed(count); return count; } Flush(); @@ -52,12 +156,16 @@ int32_t KvDelegate::Delete(const std::string &collectionName, const std::string int32_t status = GetBatch(collectionName, filter, "{\"id_\": true}", queryResults); if (status != E_OK) { ZLOGE("db GetBatch failed, %{public}s %{public}d", filter.c_str(), status); + // `GetBatch` should decide whether to restore before errors are returned, so skip restoration here. return status; } for (auto &result : queryResults) { auto count = GRD_DeleteDoc(db_, collectionName.c_str(), result.c_str(), 0); if (count < 0) { - ZLOGE("GRD_UpSertDoc failed,status %{public}d %{public}s", count, result.c_str()); + ZLOGE("GRD_DeleteDoc failed,status %{public}d %{public}s", count, result.c_str()); + if (RestoreIfNeed(count)) { + return count; + } continue; } } @@ -80,6 +188,7 @@ bool KvDelegate::Init() (path_ + "/dataShare.db").c_str(), nullptr, GRD_DB_OPEN_CREATE | GRD_DB_OPEN_CHECK_FOR_ABNORMAL, &db_); if (status != GRD_OK || db_ == nullptr) { ZLOGE("GRD_DBOpen failed,status %{public}d", status); + RestoreIfNeed(status); return false; } if (executors_ != nullptr) { @@ -89,17 +198,22 @@ bool KvDelegate::Init() db_ = nullptr; isInitDone_ = false; taskId_ = ExecutorPool::INVALID_TASK_ID; + Backup(); }); } status = GRD_CreateCollection(db_, TEMPLATE_TABLE, nullptr, 0); if (status != GRD_OK) { + // If opeaning db succeeds, it is rare to fail to create tables ZLOGE("GRD_CreateCollection template table failed,status %{public}d", status); + RestoreIfNeed(status); return false; } status = GRD_CreateCollection(db_, DATA_TABLE, nullptr, 0); if (status != GRD_OK) { + // If opeaning db succeeds, it is rare to fail to create tables ZLOGE("GRD_CreateCollection data table failed,status %{public}d", status); + RestoreIfNeed(status); return false; } isInitDone_ = true; @@ -174,12 +288,14 @@ int32_t KvDelegate::Get( int status = GRD_FindDoc(db_, collectionName.c_str(), query, 0, &resultSet); if (status != GRD_OK || resultSet == nullptr) { ZLOGE("GRD_FindDoc failed,status %{public}d", status); + RestoreIfNeed(status); return status; } status = GRD_Next(resultSet); if (status != GRD_OK) { GRD_FreeResultSet(resultSet); ZLOGE("GRD_Next failed,status %{public}d", status); + RestoreIfNeed(status); return status; } char *value = nullptr; @@ -187,6 +303,7 @@ int32_t KvDelegate::Get( if (status != GRD_OK || value == nullptr) { GRD_FreeResultSet(resultSet); ZLOGE("GRD_GetValue failed,status %{public}d", status); + RestoreIfNeed(status); return status; } result = value; @@ -200,6 +317,7 @@ void KvDelegate::Flush() int status = GRD_Flush(db_, GRD_DB_FLUSH_ASYNC); if (status != GRD_OK) { ZLOGE("GRD_Flush failed,status %{public}d", status); + RestoreIfNeed(status); } } @@ -217,7 +335,8 @@ int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::strin GRD_ResultSet *resultSet; int status = GRD_FindDoc(db_, collectionName.c_str(), query, GRD_DOC_ID_DISPLAY, &resultSet); if (status != GRD_OK || resultSet == nullptr) { - ZLOGE("GRD_UpSertDoc failed,status %{public}d", status); + ZLOGE("GRD_FindDoc failed,status %{public}d", status); + RestoreIfNeed(status); return status; } char *value = nullptr; @@ -226,6 +345,7 @@ int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::strin if (status != GRD_OK || value == nullptr) { GRD_FreeResultSet(resultSet); ZLOGE("GRD_GetValue failed,status %{public}d", status); + RestoreIfNeed(status); return status; } result.emplace_back(value); diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.h b/services/distributeddataservice/service/data_share/common/kv_delegate.h index e3d19e08c05494f4b95f8f69798145115a15cc95..13499f70d9e24d15e50c2016a9a86361a3a98f0c 100644 --- a/services/distributeddataservice/service/data_share/common/kv_delegate.h +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -36,18 +36,25 @@ public: std::string &result) override; int32_t GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, std::vector &result) override; + void NotifyBackup() override; private: bool Init(); bool GetVersion(const std::string &collectionName, const std::string &filter, int &version); int64_t Upsert(const std::string &collectionName, const std::string &filter, const std::string &value); void Flush(); + bool RestoreIfNeed(int32_t dbStatus); + void Backup(); + void Restore(); + void RemoveDbFile(bool isBackUp); + bool CopyFile(bool isBackup); std::recursive_mutex mutex_; std::string path_; GRD_DB *db_ = nullptr; bool isInitDone_ = false; std::shared_ptr executors_ = nullptr; ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; + bool hasChange_ = false; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_KV_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index f647f2aeaceadd2da0ea1fd0a10e2c1dc7f08c59..1bf1992199f4ad390ab15e46ab90f3366e71a039 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -16,19 +16,25 @@ #include "rdb_delegate.h" #include "crypto_manager.h" +#include "datashare_errno.h" #include "datashare_radar_reporter.h" #include "device_manager_adapter.h" +#include "extension_connect_adaptor.h" +#include "int_wrapper.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "metadata/secret_key_meta_data.h" #include "resultset_json_formatter.h" #include "log_print.h" +#include "rdb_errno.h" #include "rdb_utils.h" #include "scheduler_manager.h" +#include "string_wrapper.h" #include "utils/anonymous.h" +#include "want_params.h" namespace OHOS::DataShare { -constexpr static int32_t MAX_RESULTSET_COUNT = 16; +constexpr static int32_t MAX_RESULTSET_COUNT = 32; constexpr static int64_t TIMEOUT_TIME = 500; std::atomic RdbDelegate::resultSetCount = 0; ConcurrentMap RdbDelegate::resultSetCallingPids; @@ -58,36 +64,70 @@ std::string RemindTimerFunc(const std::vector &args) return args[ARG_TIME]; } -RdbStoreConfig RdbDelegate::GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction) +std::pair RdbDelegate::GetConfig(const DistributedData::StoreMetaData &meta, + bool registerFunction) { RdbStoreConfig config(meta.dataDir); config.SetCreateNecessary(false); + config.SetHaMode(meta.haMode); config.SetBundleName(meta.bundleName); if (meta.isEncrypt) { DistributedData::SecretKeyMetaData secretKeyMeta; - DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKeyMeta, true); + if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKeyMeta, true)) { + return std::make_pair(E_DB_NOT_EXIST, config); + } std::vector decryptKey; - DistributedData::CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); + if (!DistributedData::CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey)) { + return std::make_pair(E_ERROR, config); + }; config.SetEncryptKey(decryptKey); std::fill(decryptKey.begin(), decryptKey.end(), 0); } if (registerFunction) { config.SetScalarFunction("remindTimer", ARGS_SIZE, RemindTimerFunc); } - return config; + return std::make_pair(E_OK, config); } -RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction) +RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUriData, const std::string &backup) { - RdbStoreConfig config = GetConfig(meta, registerFunction); + tokenId_ = meta.tokenId; + bundleName_ = meta.bundleName; + storeName_ = meta.storeId; + extUri_ = extUriData; + haMode_ = meta.haMode; + backup_ = backup; + + auto [err, config] = GetConfig(meta, registerFunction); + if (err != E_OK) { + ZLOGW("Get rdbConfig failed, errCode is %{public}d, dir is %{public}s", err, + DistributedData::Anonymous::Change(meta.dataDir).c_str()); + return; + } DefaultOpenCallback callback; store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_); if (errCode_ != E_OK) { ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_, DistributedData::Anonymous::Change(meta.dataDir).c_str()); + RdbDelegate::TryAndSend(errCode_); } } +void RdbDelegate::TryAndSend(int errCode) +{ + if (errCode != E_SQLITE_CORRUPT || (haMode_ == HAMode::SINGLE && (backup_ != DUAL_WRITE && backup_ != PERIODIC))) { + return; + } + ZLOGE("Database corruption. BundleName: %{public}s. StoreName: %{public}s. ExtUri: %{public}s", + bundleName_.c_str(), storeName_.c_str(), DistributedData::Anonymous::Change(extUri_).c_str()); + AAFwk::WantParams params; + params.SetParam("BundleName", AAFwk::String::Box(bundleName_)); + params.SetParam("StoreName", AAFwk::String::Box(storeName_)); + params.SetParam("StoreStatus", AAFwk::Integer::Box(1)); + ExtensionConnectAdaptor::TryAndWait(extUri_, bundleName_, params); +} + int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) { if (store_ == nullptr) { @@ -101,6 +141,9 @@ int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesB ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::INSERT_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } } return rowId; } @@ -119,6 +162,9 @@ int64_t RdbDelegate::Update( ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::UPDATE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } } return changeCount; } @@ -135,12 +181,85 @@ int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredica ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::DELETE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } } return changeCount; } + +std::pair RdbDelegate::InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return std::make_pair(E_DB_ERROR, 0); + } + int64_t rowId = 0; + ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); + int ret = store_->Insert(rowId, tableName, bucket); + if (ret != E_OK) { + ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::INSERT_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, rowId); + } + return std::make_pair(E_OK, rowId); +} + +std::pair RdbDelegate::UpdateEx( + const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return std::make_pair(E_DB_ERROR, 0); + } + int changeCount = 0; + ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); + RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); + int ret = store_->Update(changeCount, bucket, predicates); + if (ret != E_OK) { + ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::UPDATE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, changeCount); + } + return std::make_pair(E_OK, changeCount); +} + +std::pair RdbDelegate::DeleteEx(const std::string &tableName, const DataSharePredicates &predicate) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return std::make_pair(E_DB_ERROR, 0); + } + int changeCount = 0; + RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); + int ret = store_->Delete(changeCount, predicates); + if (ret != E_OK) { + ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::DELETE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, changeCount); + } + return std::make_pair(E_OK, changeCount); +} + std::pair> RdbDelegate::Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, - const int32_t callingPid) + int32_t callingPid, uint32_t callingTokenId) { if (store_ == nullptr) { ZLOGE("store is null"); @@ -148,9 +267,9 @@ std::pair> RdbDelegate::Query(const std } int count = resultSetCount.fetch_add(1); ZLOGD("start query %{public}d", count); - if (count > MAX_RESULTSET_COUNT && IsLimit(count)) { + if (count > MAX_RESULTSET_COUNT && IsLimit(count, callingPid, callingTokenId)) { resultSetCount--; - return std::make_pair(E_ERROR, nullptr); + return std::make_pair(E_RESULTSET_BUSY, nullptr); } RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); std::shared_ptr resultSet = store_->QueryByStep(rdbPredicates, columns); @@ -161,6 +280,12 @@ std::pair> RdbDelegate::Query(const std resultSetCount--; return std::make_pair(E_ERROR, nullptr); } + int err = resultSet->GetRowCount(count); + RdbDelegate::TryAndSend(err); + if (err == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d, pid:%{public}d", E_SQLITE_ERROR, callingPid); + EraseStoreCache(tokenId_); + } resultSetCallingPids.Compute(callingPid, [](const uint32_t &, int32_t &value) { ++value; return true; @@ -197,6 +322,11 @@ std::string RdbDelegate::Query(const std::string &sql, const std::vectorGetRowCount(rowCount) == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d", E_SQLITE_ERROR); + EraseStoreCache(tokenId_); + } ResultSetJsonFormatter formatter(std::move(resultSet)); return DistributedData::Serializable::Marshall(formatter); } @@ -207,7 +337,17 @@ std::shared_ptr RdbDelegate::QuerySql(const std::string &s ZLOGE("store is null"); return nullptr; } - return store_->QuerySql(sql); + auto resultSet = store_->QuerySql(sql); + if (resultSet == nullptr) { + ZLOGE("Query failed %{private}s", sql.c_str()); + return resultSet; + } + int rowCount; + if (resultSet->GetRowCount(rowCount) == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d", E_SQLITE_ERROR); + EraseStoreCache(tokenId_); + } + return resultSet; } bool RdbDelegate::IsInvalid() @@ -215,7 +355,7 @@ bool RdbDelegate::IsInvalid() return store_ == nullptr; } -bool RdbDelegate::IsLimit(int count) +bool RdbDelegate::IsLimit(int count, int32_t callingPid, uint32_t callingTokenId) { bool isFull = true; for (int32_t retryCount = 0; retryCount < RETRY; retryCount++) { @@ -229,11 +369,15 @@ bool RdbDelegate::IsLimit(int count) return false; } std::string logStr; - resultSetCallingPids.ForEach([&logStr](const uint32_t &key, int32_t &value) { + resultSetCallingPids.ForEach([&logStr](const uint32_t &key, const int32_t &value) { logStr += std::to_string(key) + ":" + std::to_string(value) + ";"; return false; }); - ZLOGE("resultSetCount is full, owner is %{public}s", logStr.c_str()); + ZLOGE("resultSetCount is full, pid: %{public}d, owner is %{public}s", callingPid, logStr.c_str()); + std::string appendix = "callingName:" + HiViewFaultAdapter::GetCallingName(callingTokenId).first; + DataShareFaultInfo faultInfo{RESULTSET_FULL, "callingTokenId:" + std::to_string(callingTokenId), + "Pid:" + std::to_string(callingPid), "owner:" + logStr, __FUNCTION__, E_RESULTSET_BUSY, appendix}; + HiViewFaultAdapter::ReportDataFault(faultInfo); return true; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/services/distributeddataservice/service/data_share/common/rdb_delegate.h index 4e5bbc6f75b29cb6ffe219faac878f1a76710f46..75b869b90af1f007aefe728acf62134e46db35c0 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,27 +31,43 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction); + explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUri, const std::string &backup); int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) override; std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, - const int32_t callingPid) override; + int32_t callingPid, uint32_t callingTokenId) override; std::string Query(const std::string &sql, const std::vector &selectionArgs) override; std::shared_ptr QuerySql(const std::string &sql) override; bool IsInvalid() override; + std::pair InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) override; + std::pair UpdateEx(const std::string &tableName, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; + std::pair DeleteEx(const std::string &tableName, + const DataSharePredicates &predicate) override; private: - RdbStoreConfig GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction); - bool IsLimit(int count); + void TryAndSend(int errCode); + std::pair GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction); + bool IsLimit(int count, int32_t callingPid, uint32_t callingTokenId); static std::atomic resultSetCount; static ConcurrentMap resultSetCallingPids; - static constexpr std::chrono::milliseconds WAIT_TIME = std::chrono::milliseconds(100); + static constexpr std::chrono::milliseconds WAIT_TIME = std::chrono::milliseconds(50); std::shared_ptr store_; int errCode_ = E_OK; static constexpr int RETRY = 3; + static constexpr const char *DUAL_WRITE = "dualWrite"; + static constexpr const char *PERIODIC = "periodic"; + uint32_t tokenId_; + std::string bundleName_; + std::string storeName_; + int32_t haMode_; + std::string extUri_; + std::string backup_; }; class DefaultOpenCallback : public RdbOpenCallback { public: diff --git a/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp b/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp index cce99c945ba0145d5e84a2061ef0194e51684148..8ed1869761a28d98d49f19dfe26fee597ff35ce6 100644 --- a/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp +++ b/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp @@ -91,7 +91,7 @@ void SchedulerManager::DestoryTimerTask(int64_t timerId) void SchedulerManager::ResetTimerTask(int64_t timerId, int64_t reminderTime) { - TimeServiceClient::GetInstance()->StopTimer(timerId); + // This start also means reset, new one will replace old one TimeServiceClient::GetInstance()->StartTimer(timerId, static_cast(reminderTime)); } @@ -178,11 +178,6 @@ void SchedulerManager::ExecuteSchedulerSQL(const std::string &rdbDir, const int3 count); return; } - errCode = resultSet->GoToFirstRow(); - if (errCode != E_OK) { - ZLOGE("GoToFirstRow error, %{public}s, %{public}" PRId64 ", %{public}s, errCode is %{public}d", - DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str(), errCode); - } } void SchedulerManager::GenRemindTimerFuncParams( diff --git a/services/distributeddataservice/service/data_share/common/uri_utils.cpp b/services/distributeddataservice/service/data_share/common/uri_utils.cpp index 7d925cf722cb4f88dc62b6f52a3ec29bc8a6f967..48d4dfce0b37a17109a989bf4a5a475138296b02 100644 --- a/services/distributeddataservice/service/data_share/common/uri_utils.cpp +++ b/services/distributeddataservice/service/data_share/common/uri_utils.cpp @@ -62,6 +62,38 @@ bool URIUtils::GetBundleNameFromProxyURI(const std::string &uri, std::string &bu return true; } +bool URIUtils::GetAppIndexFromProxyURI(const std::string &uri, int32_t &appIndex) +{ + auto queryParams = URIUtils::GetQueryParams(uri); + if (!queryParams[APP_INDEX].empty()) { + auto [success, data] = URIUtils::Strtoul(queryParams[APP_INDEX]); + if (!success) { + appIndex = -1; + ZLOGE("appIndex is invalid! appIndex: %{public}s", queryParams[APP_INDEX].c_str()); + return false; + } + appIndex = static_cast(data); + } + return true; +} + +std::pair URIUtils::GetUserFromProxyURI(const std::string &uri) +{ + auto queryParams = URIUtils::GetQueryParams(uri); + if (queryParams[USER_PARAM].empty()) { + // -1 is placeholder for visit provider's user + return std::make_pair(true, -1); + } + auto [success, data] = URIUtils::Strtoul(queryParams[USER_PARAM]); + if (!success) { + return std::make_pair(false, -1); + } + if (data < 0 || data > INT32_MAX) { + return std::make_pair(false, -1); + } + return std::make_pair(true, data); +} + void URIUtils::FormatUri(std::string &uri) { auto pos = uri.find_last_of('?'); @@ -72,7 +104,17 @@ void URIUtils::FormatUri(std::string &uri) uri.resize(pos); } -UriConfig URIUtils::GetUriConfig(const std::string &uri) +std::string URIUtils::FormatConstUri(const std::string &uri) +{ + auto pos = uri.find_last_of('?'); + if (pos == std::string::npos) { + return uri; + } + + return uri.substr(0, pos); +} + +__attribute__((no_sanitize("cfi"))) UriConfig URIUtils::GetUriConfig(const std::string &uri) { UriConfig uriConfig; Uri uriTemp(uri); diff --git a/services/distributeddataservice/service/data_share/common/uri_utils.h b/services/distributeddataservice/service/data_share/common/uri_utils.h index ffd4286c3ea7732968b9459b1ba8e0f0b591a679..8f2298506f8c454cfad95dd44f162a7aa23c181c 100644 --- a/services/distributeddataservice/service/data_share/common/uri_utils.h +++ b/services/distributeddataservice/service/data_share/common/uri_utils.h @@ -39,8 +39,11 @@ class URIUtils { public: static bool GetInfoFromURI(const std::string &uri, UriInfo &uriInfo); static bool GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName); + static bool GetAppIndexFromProxyURI(const std::string &uri, int32_t &appIndex); + static std::pair GetUserFromProxyURI(const std::string &uri); static bool IsDataProxyURI(const std::string &uri); static void FormatUri(std::string &uri); + static std::string FormatConstUri(const std::string &uri); static UriConfig GetUriConfig(const std::string &uri); static std::string Anonymous(const std::string &uri); static std::map GetQueryParams(const std::string& uri); @@ -50,6 +53,8 @@ public: static constexpr const char *PARAM_URI_SEPARATOR = ":///"; static constexpr const char *SCHEME_SEPARATOR = "://"; static constexpr const char *URI_SEPARATOR = "/"; + static constexpr const char *APP_INDEX = "appIndex"; // for Application Clone + static constexpr const char USER_PARAM[] = "user"; static constexpr int DATA_PROXY_SCHEMA_LEN = sizeof(DATA_PROXY_SCHEMA) - 1; static constexpr uint32_t PARAM_URI_SEPARATOR_LEN = 4; diff --git a/services/distributeddataservice/service/data_share/data/template_data.cpp b/services/distributeddataservice/service/data_share/data/template_data.cpp index 4236f4d7b370f28199c9e7f443bd267756cced00..f99bec09c24f851811f1371be7302f2260bb8426 100644 --- a/services/distributeddataservice/service/data_share/data/template_data.cpp +++ b/services/distributeddataservice/service/data_share/data/template_data.cpp @@ -59,7 +59,14 @@ bool TemplateRootNode::Unmarshal(const DistributedData::Serializable::json &node { bool ret = GetValue(node, GET_NAME(uri), uri); ret = ret && GetValue(node, GET_NAME(bundleName), bundleName); - ret = ret && GetValue(node, GET_NAME(subscriberId), subscriberId); + if (!GetValue(node, GET_NAME(subscriberId), subscriberId)) { + int64_t subId; + if (GetValue(node, GET_NAME(subscriberId), subId)) { + subscriberId = std::to_string(subId); + } else { + ret = false; + } + } ret = ret && GetValue(node, GET_NAME(userId), userId); ret = ret && GetValue(node, GET_NAME(templat), tpl); return ret; @@ -67,7 +74,7 @@ bool TemplateRootNode::Unmarshal(const DistributedData::Serializable::json &node TemplateRootNode::TemplateRootNode(const std::string &uri, const std::string &bundleName, const int64_t subscriberId, const int32_t userId, const Template &tpl) - : uri(uri), bundleName(bundleName), subscriberId(subscriberId), userId(userId), tpl(tpl) + : uri(uri), bundleName(bundleName), subscriberId(std::to_string(subscriberId)), userId(userId), tpl(tpl) { } @@ -132,6 +139,7 @@ bool TemplateData::Delete(const std::string &bundleName, const int32_t userId) ZLOGE("db DeleteById failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } @@ -149,6 +157,7 @@ bool TemplateData::Add(const std::string &uri, const int32_t userId, const std:: ZLOGE("db Upsert failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } @@ -166,6 +175,7 @@ bool TemplateData::Delete( ZLOGE("db DeleteById failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } diff --git a/services/distributeddataservice/service/data_share/data/template_data.h b/services/distributeddataservice/service/data_share/data/template_data.h index 06b482b51bc1f573126f8d8e191716fe7e5fe8d3..859f0d2d3fe02515bc87390246e7ed48249788dd 100644 --- a/services/distributeddataservice/service/data_share/data/template_data.h +++ b/services/distributeddataservice/service/data_share/data/template_data.h @@ -50,7 +50,7 @@ struct TemplateRootNode final: public DistributedData::Serializable { private: std::string uri; std::string bundleName; - int64_t subscriberId; + std::string subscriberId; int32_t userId; TemplateNode tpl; }; diff --git a/services/distributeddataservice/service/data_share/data_provider_config.cpp b/services/distributeddataservice/service/data_share/data_provider_config.cpp index 01f67f0050d685b7cd8095e0d9d2f5e78be151ef..accce64e09ab916aa92bf4f2a9a4846decc94555 100644 --- a/services/distributeddataservice/service/data_share/data_provider_config.cpp +++ b/services/distributeddataservice/service/data_share/data_provider_config.cpp @@ -33,10 +33,20 @@ DataProviderConfig::DataProviderConfig(const std::string &uri, uint32_t callerTo { providerInfo_.uri = uri; providerInfo_.currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(callerTokenId); + providerInfo_.visitedUserId = providerInfo_.currentUserId; + URIUtils::GetAppIndexFromProxyURI(providerInfo_.uri, providerInfo_.appIndex); if (providerInfo_.currentUserId == 0) { - LoadConfigCommonStrategy::GetInfoFromProxyURI(providerInfo_.uri, providerInfo_.currentUserId, + LoadConfigCommonStrategy::GetInfoFromProxyURI(providerInfo_.uri, providerInfo_.visitedUserId, callerTokenId, providerInfo_.bundleName); URIUtils::FormatUri(providerInfo_.uri); + } else { + auto [success, data] = URIUtils::GetUserFromProxyURI(providerInfo_.uri); + if (success) { + // if data is -1, it means visiting provider's user + providerInfo_.visitedUserId = (data == -1 ? providerInfo_.currentUserId : data); + } else { + providerInfo_.visitedUserId = -1; + } } uriConfig_ = URIUtils::GetUriConfig(providerInfo_.uri); } @@ -52,7 +62,7 @@ std::pair DataProviderConfig::GetBundleInfo() providerInfo_.bundleName = uriConfig_.pathSegments[0]; } auto ret = BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo); + providerInfo_.bundleName, providerInfo_.visitedUserId, bundleInfo, providerInfo_.appIndex); return std::make_pair(ret, bundleInfo); } @@ -60,8 +70,8 @@ int DataProviderConfig::GetFromProxyData() { auto [errCode, bundleInfo] = GetBundleInfo(); if (errCode != E_OK) { - ZLOGE("Get bundleInfo failed! bundleName:%{public}s, userId:%{public}d, uri:%{public}s", - providerInfo_.bundleName.c_str(), providerInfo_.currentUserId, + ZLOGE("Get bundleInfo failed! bundleName:%{public}s, userId:%{public}d, visitedId:%{public}d, uri:%{public}s", + providerInfo_.bundleName.c_str(), providerInfo_.currentUserId, providerInfo_.visitedUserId, URIUtils::Anonymous(providerInfo_.uri).c_str()); return errCode; } @@ -110,6 +120,8 @@ int DataProviderConfig::GetFromDataProperties(const ProfileInfo &profileInfo, providerInfo_.tableName = profileInfo.tableName; providerInfo_.type = profileInfo.type; providerInfo_.storeMetaDataFromUri = profileInfo.storeMetaDataFromUri; + providerInfo_.backup = profileInfo.backup; + providerInfo_.extensionUri = profileInfo.extUri; if (profileInfo.tableConfig.empty()) { return E_OK; } @@ -129,7 +141,7 @@ int DataProviderConfig::GetFromExtensionProperties(const ProfileInfo &profileInf return E_ERROR; } if (providerInfo_.singleton && providerInfo_.accessCrossMode == AccessCrossMode::USER_SINGLE) { - providerInfo_.tableName.append("_").append(std::to_string(providerInfo_.currentUserId)); + providerInfo_.tableName.append("_").append(std::to_string(providerInfo_.visitedUserId)); } return E_OK; } @@ -142,7 +154,7 @@ int DataProviderConfig::GetFromExtension() } BundleConfig bundleInfo; auto ret = BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo); + providerInfo_.bundleName, providerInfo_.visitedUserId, bundleInfo, providerInfo_.appIndex); if (ret != E_OK) { ZLOGE("BundleInfo failed! bundleName: %{public}s", providerInfo_.bundleName.c_str()); return ret; @@ -200,6 +212,12 @@ void DataProviderConfig::GetMetaDataFromUri() std::pair DataProviderConfig::GetProviderInfo() { + if (providerInfo_.appIndex == -1) { + return std::make_pair(E_APPINDEX_INVALID, providerInfo_); + } + if (providerInfo_.visitedUserId == -1) { + return std::make_pair(E_INVALID_USER_ID, providerInfo_); + } auto ret = GetFromProxyData(); if (ret == E_OK) { GetMetaDataFromUri(); diff --git a/services/distributeddataservice/service/data_share/data_provider_config.h b/services/distributeddataservice/service/data_share/data_provider_config.h index aa98e4c2f614c4b75e426e3097c854bf6a5651db..694b04a892579fb19c84d04e28e68de6eca5a957 100644 --- a/services/distributeddataservice/service/data_share/data_provider_config.h +++ b/services/distributeddataservice/service/data_share/data_provider_config.h @@ -33,13 +33,18 @@ public: struct ProviderInfo { std::string uri; int32_t currentUserId = -1; + int32_t visitedUserId = -1; + int32_t appIndex = 0; // appIndex is in [1, 1000], and original app's index is 0 std::string bundleName; std::string moduleName; std::string storeName; std::string tableName; std::string readPermission; std::string writePermission; + std::string acrossAccountsPermission = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS"; std::string type = "rdb"; + std::string backup; + std::string extensionUri; bool singleton = false; bool hasExtension = false; bool allowEmptyPermission = false; diff --git a/services/distributeddataservice/service/data_share/data_share_db_config.cpp b/services/distributeddataservice/service/data_share/data_share_db_config.cpp index d604a832557e6f05b4d1e6fc7c53326c8aa2b076..79a2f4629ba388611e675ae0ec7b0edc33fbd366 100644 --- a/services/distributeddataservice/service/data_share/data_share_db_config.cpp +++ b/services/distributeddataservice/service/data_share/data_share_db_config.cpp @@ -30,28 +30,30 @@ namespace OHOS::DataShare { std::pair DataShareDbConfig::QueryMetaData( - const std::string &bundleName, const std::string &storeName, int32_t userId) + const std::string &bundleName, const std::string &storeName, int32_t userId, int32_t appIndex) { DistributedData::StoreMetaData meta; meta.deviceId = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; meta.user = std::to_string(userId); meta.bundleName = bundleName; meta.storeId = storeName; + meta.instanceId = appIndex; DistributedData::StoreMetaData metaData; bool isCreated = DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), metaData, true); return std::make_pair(isCreated, metaData); } -std::pair DataShareDbConfig::GetMetaData(const std::string &uri, - const std::string &bundleName, const std::string &storeName, int32_t userId, bool hasExtension) +std::pair DataShareDbConfig::GetMetaData(const DbConfig &dbConfig) { - auto [success, metaData] = QueryMetaData(bundleName, storeName, userId); + auto [success, metaData] = QueryMetaData( + dbConfig.bundleName, dbConfig.storeName, dbConfig.userId, dbConfig.appIndex); if (!success) { - if (!hasExtension) { + if (!dbConfig.hasExtension) { return std::pair(NativeRdb::E_DB_NOT_EXIST, metaData); } - ExtensionConnectAdaptor::TryAndWait(uri, bundleName); - auto [succ, meta] = QueryMetaData(bundleName, storeName, userId); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(dbConfig.uri, dbConfig.bundleName, wantParams); + auto [succ, meta] = QueryMetaData(dbConfig.bundleName, dbConfig.storeName, dbConfig.userId, dbConfig.appIndex); if (!succ) { return std::pair(NativeRdb::E_DB_NOT_EXIST, meta); } @@ -61,21 +63,21 @@ std::pair DataShareDbConfig::GetMetaData(co } std::tuple> DataShareDbConfig::GetDbConfig( - const std::string &uri, bool hasExtension, const std::string &bundleName, const std::string &storeName, - int32_t userId) + DbConfig &dbConfig) { - auto [errCode, metaData] = GetMetaData(uri, bundleName, storeName, userId, hasExtension); + auto [errCode, metaData] = GetMetaData(dbConfig); if (errCode != E_OK) { ZLOGE("DB not exist,bundleName:%{public}s,storeName:%{public}s,user:%{public}d,err:%{public}d,uri:%{public}s", - bundleName.c_str(), storeName.c_str(), userId, errCode, URIUtils::Anonymous(uri).c_str()); + dbConfig.bundleName.c_str(), dbConfig.storeName.c_str(), dbConfig.userId, errCode, + URIUtils::Anonymous(dbConfig.uri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_MATEDATA_EXISTS, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::META_DATA_NOT_EXISTS); return std::make_tuple(errCode, metaData, nullptr); } - auto dbDelegate = DBDelegate::Create(metaData); + auto dbDelegate = DBDelegate::Create(metaData, dbConfig.extUri, dbConfig.backup); if (dbDelegate == nullptr) { ZLOGE("Create delegate fail, bundleName:%{public}s, userId:%{public}d, uri:%{public}s", - bundleName.c_str(), userId, URIUtils::Anonymous(uri).c_str()); + dbConfig.bundleName.c_str(), dbConfig.userId, URIUtils::Anonymous(dbConfig.uri).c_str()); return std::make_tuple(E_ERROR, metaData, nullptr); } return std::make_tuple(E_OK, metaData, dbDelegate); diff --git a/services/distributeddataservice/service/data_share/data_share_db_config.h b/services/distributeddataservice/service/data_share/data_share_db_config.h index 441e9cfe20c447d4451318ca0344869a959b779b..88efe930efe5fd4e58b9db46d822ad5f0f97d081 100644 --- a/services/distributeddataservice/service/data_share/data_share_db_config.h +++ b/services/distributeddataservice/service/data_share/data_share_db_config.h @@ -28,14 +28,21 @@ namespace OHOS::DataShare { class DataShareDbConfig { public: - std::tuple> GetDbConfig( - const std::string &uri, bool hasExtension, const std::string &bundleName, - const std::string &storeName, int32_t userId); - std::pair GetMetaData(const std::string &uri, - const std::string &bundleName, const std::string &storeName, int32_t userId, bool hasExtension); + struct DbConfig { + std::string uri; + std::string extUri; + std::string bundleName; + std::string storeName; + std::string backup; + int32_t userId; + int32_t appIndex; + bool hasExtension; + }; + std::tuple> GetDbConfig(DbConfig &dbConfig); + std::pair GetMetaData(const DbConfig &dbConfig); private: static std::pair QueryMetaData(const std::string &bundleName, - const std::string &storeName, int32_t userId); + const std::string &storeName, int32_t userId, int32_t appIndex); }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/data_share_profile_config.cpp b/services/distributeddataservice/service/data_share/data_share_profile_config.cpp index 332fa9db71e5770858055247dbaa30dd024033d1..562357ffb91eb51e3cbd21996e2c761e1a698601 100644 --- a/services/distributeddataservice/service/data_share/data_share_profile_config.cpp +++ b/services/distributeddataservice/service/data_share/data_share_profile_config.cpp @@ -59,7 +59,7 @@ bool LaunchInfo::Marshal(json &node) const SetValue(node[GET_NAME(tableNames)], tableNames); return true; } - + bool LaunchInfo::Unmarshal(const json &node) { GetValue(node, GET_NAME(storeId), storeId); @@ -76,6 +76,9 @@ bool ProfileInfo::Marshal(json &node) const SetValue(node[GET_NAME(type)], type); SetValue(node[GET_NAME(launchInfos)], launchInfos); SetValue(node[GET_NAME(storeMetaDataFromUri)], storeMetaDataFromUri); + SetValue(node[GET_NAME(launchForCleanData)], launchForCleanData); + SetValue(node[GET_NAME(backup)], backup); + SetValue(node[GET_NAME(extUri)], extUri); return true; } @@ -87,6 +90,9 @@ bool ProfileInfo::Unmarshal(const json &node) GetValue(node, GET_NAME(type), type); GetValue(node, GET_NAME(launchInfos), launchInfos); GetValue(node, GET_NAME(storeMetaDataFromUri), storeMetaDataFromUri); + GetValue(node, GET_NAME(launchForCleanData), launchForCleanData); + GetValue(node, GET_NAME(backup), backup); + GetValue(node, GET_NAME(extUri), extUri); std::string path; auto ret = GetValue(node, GET_NAME(path), path); if (ret) { @@ -245,6 +251,7 @@ bool DataShareProfileConfig::GetProfileInfo(const std::string &calledBundleName, std::map &profileInfos) { BundleConfig bundleInfo; + // profile is the same when app clone if (BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS(calledBundleName, currentUserId, bundleInfo) != E_OK) { ZLOGE("data share GetBundleInfoFromBMS failed! bundleName: %{public}s, currentUserId = %{public}d", diff --git a/services/distributeddataservice/service/data_share/data_share_profile_config.h b/services/distributeddataservice/service/data_share/data_share_profile_config.h index 562df8a92495c5fe2009bbff8d2f9498548b720d..9fc6df898af97bb4db84fbae61b63d2e535fb641 100644 --- a/services/distributeddataservice/service/data_share/data_share_profile_config.h +++ b/services/distributeddataservice/service/data_share/data_share_profile_config.h @@ -50,8 +50,11 @@ struct ProfileInfo : public DistributedData::Serializable { std::string tableName; std::string scope = "module"; std::string type = "rdb"; + std::string backup; + std::string extUri; std::vector launchInfos; bool storeMetaDataFromUri = false; + bool launchForCleanData = false; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index dcabe9bd271e88a00ee0757d0f339a22bd9d6982..54c7504ac2c392b47f0e1b10595878c8239c73a0 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -38,8 +38,12 @@ #include "dump/dump_manager.h" #include "extension_ability_manager.h" #include "hap_token_info.h" +#include "hiview_adapter.h" +#include "if_system_ability_manager.h" #include "ipc_skeleton.h" +#include "iservice_registry.h" #include "log_print.h" +#include "common/uri_utils.h" #include "metadata/auto_launch_meta_data.h" #include "metadata/meta_data_manager.h" #include "matching_skills.h" @@ -48,6 +52,8 @@ #include "scheduler_manager.h" #include "subscriber_managers/published_data_subscriber_manager.h" #include "sys_event_subscriber.h" +#include "system_ability_definition.h" +#include "system_ability_status_change_stub.h" #include "template_data.h" #include "utils/anonymous.h" #include "xcollie.h" @@ -58,6 +64,29 @@ using DumpManager = OHOS::DistributedData::DumpManager; using ProviderInfo = DataProviderConfig::ProviderInfo; using namespace OHOS::DistributedData; __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_; +class DataShareServiceImpl::SystemAbilityStatusChangeListener + : public SystemAbilityStatusChangeStub { +public: + SystemAbilityStatusChangeListener() + { + } + ~SystemAbilityStatusChangeListener() = default; + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override + { + } +}; + +void DataShareServiceImpl::SystemAbilityStatusChangeListener::OnAddSystemAbility( + int32_t systemAbilityId, const std::string &deviceId) +{ + if (systemAbilityId != COMMON_EVENT_SERVICE_ID) { + return; + } + ZLOGI("Common event service start. saId:%{public}d", systemAbilityId); + InitSubEvent(); +} + DataShareServiceImpl::Factory::Factory() { FeatureSystem::GetInstance().RegisterCreator("data_share", []() { @@ -87,7 +116,35 @@ int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValu } return ret; }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return Execute(uri, "", IPCSkeleton::GetCallingTokenID(), false, callBack); +} + +std::pair DataShareServiceImpl::InsertEx(const std::string &uri, const std::string &extUri, + const DataShareValuesBucket &valuesBucket) +{ + ZLOGD("InsertEx enter."); + std::string func = __FUNCTION__; + XCollie xcollie(func, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { + ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); + return std::make_pair(ERROR, 0); + } + auto callingTokenId = IPCSkeleton::GetCallingTokenID(); + auto callBack = [&uri, &valuesBucket, this, &callingTokenId, &func](ProviderInfo &providerInfo, + DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + RdbTimeCostInfo rdbTimeCostInfo(providerInfo.bundleName, providerInfo.moduleName, providerInfo.storeName, + func, callingTokenId); + auto [errCode, ret] = dbDelegate->InsertEx(providerInfo.tableName, valuesBucket); + if (errCode == E_OK && ret > 0) { + NotifyChange(uri); + RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.visitedUserId, metaData); + } else { + ReportExcuteFault(callingTokenId, providerInfo, errCode, func); + } + return std::make_pair(errCode, ret); + }; + return ExecuteEx(uri, extUri, IPCSkeleton::GetCallingTokenID(), false, callBack); } bool DataShareServiceImpl::NotifyChange(const std::string &uri) @@ -110,8 +167,8 @@ bool DataShareServiceImpl::NotifyChange(const std::string &uri) return true; } -int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) +int32_t DataShareServiceImpl::Update(const std::string &uri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) { ZLOGD("Update enter."); XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), @@ -129,7 +186,35 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred } return ret; }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return Execute(uri, "", IPCSkeleton::GetCallingTokenID(), false, callBack); +} + +std::pair DataShareServiceImpl::UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) +{ + ZLOGD("UpdateEx enter."); + std::string func = __FUNCTION__; + XCollie xcollie(func, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { + ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); + return std::make_pair(ERROR, 0); + } + auto callingTokenId = IPCSkeleton::GetCallingTokenID(); + auto callBack = [&uri, &predicate, &valuesBucket, this, &callingTokenId, &func](ProviderInfo &providerInfo, + DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + RdbTimeCostInfo rdbTimeCostInfo(providerInfo.bundleName, providerInfo.moduleName, providerInfo.storeName, + func, callingTokenId); + auto [errCode, ret] = dbDelegate->UpdateEx(providerInfo.tableName, predicate, valuesBucket); + if (errCode == E_OK && ret > 0) { + NotifyChange(uri); + RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.visitedUserId, metaData); + } else { + ReportExcuteFault(callingTokenId, providerInfo, errCode, func); + } + return std::make_pair(errCode, ret); + }; + return ExecuteEx(uri, extUri, callingTokenId, false, callBack); } int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePredicates &predicate) @@ -149,14 +234,42 @@ int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePred } return ret; }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return Execute(uri, "", IPCSkeleton::GetCallingTokenID(), false, callBack); } -std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, +std::pair DataShareServiceImpl::DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) +{ + std::string func = __FUNCTION__; + XCollie xcollie(func, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { + ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); + return std::make_pair(ERROR, 0); + } + auto callingTokenId = IPCSkeleton::GetCallingTokenID(); + auto callBack = [&uri, &predicate, this, &callingTokenId, &func](ProviderInfo &providerInfo, + DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + RdbTimeCostInfo rdbTimeCostInfo(providerInfo.bundleName, providerInfo.moduleName, providerInfo.storeName, + func, callingTokenId); + auto [errCode, ret] = dbDelegate->DeleteEx(providerInfo.tableName, predicate); + if (errCode == E_OK && ret > 0) { + NotifyChange(uri); + RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.visitedUserId, metaData); + } else { + ReportExcuteFault(callingTokenId, providerInfo, errCode, func); + } + return std::make_pair(errCode, ret); + }; + return ExecuteEx(uri, extUri, callingTokenId, false, callBack); +} + +std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, const std::string &extUri, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) { ZLOGD("Query enter."); - XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), + std::string func = __FUNCTION__; + XCollie xcollie(std::string(LOG_TAG) + "::" + func, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); @@ -164,14 +277,21 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin } std::shared_ptr resultSet; auto callingPid = IPCSkeleton::GetCallingPid(); - auto callBack = [&uri, &predicates, &columns, &resultSet, &callingPid](ProviderInfo &providerInfo, - DistributedData::StoreMetaData &, std::shared_ptr dbDelegate) -> int32_t { + auto callingTokenId = IPCSkeleton::GetCallingTokenID(); + auto callBack = [&uri, &predicates, &columns, &resultSet, &callingPid, &callingTokenId, &func, this] + (ProviderInfo &providerInfo, DistributedData::StoreMetaData &, + std::shared_ptr dbDelegate) -> int32_t { + RdbTimeCostInfo rdbTimeCostInfo(providerInfo.bundleName, providerInfo.moduleName, providerInfo.storeName, + func, callingTokenId); auto [err, result] = dbDelegate->Query(providerInfo.tableName, - predicates, columns, callingPid); + predicates, columns, callingPid, callingTokenId); + if (err != E_OK) { + ReportExcuteFault(callingTokenId, providerInfo, err, func); + } resultSet = std::move(result); return err; }; - errCode = Execute(uri, IPCSkeleton::GetCallingTokenID(), true, callBack); + errCode = Execute(uri, extUri, callingTokenId, true, callBack); return resultSet; } @@ -190,7 +310,7 @@ int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t return templateStrategy_.Execute(context, [&uri, &tpltId, &tplt, &context]() -> int32_t { auto result = TemplateManager::GetInstance().Add( Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId, tplt); - RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, context); + RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, tpltId.bundleName_, context); return result; }); } @@ -503,13 +623,25 @@ int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo) SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors); ExtensionAbilityManager::GetInstance().SetExecutorPool(binderInfo.executors); DBDelegate::SetExecutorPool(binderInfo.executors); - InitSubEvent(); + HiViewAdapter::GetInstance().SetThreadPool(binderInfo.executors); + SubscribeCommonEvent(); SubscribeTimeChanged(); SubscribeChange(); ZLOGI("end"); return E_OK; } +void DataShareServiceImpl::SubscribeCommonEvent() +{ + sptr systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemManager == nullptr) { + ZLOGE("System mgr is nullptr"); + return; + } + sptr callback(new SystemAbilityStatusChangeListener()); + systemManager->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, callback); +} + void DataShareServiceImpl::SubscribeChange() { EventCenter::GetInstance().Subscribe(RemoteChangeEvent::RDB_META_SAVE, [this](const Event &event) { @@ -521,7 +653,7 @@ void DataShareServiceImpl::SubscribeChange() AutoLaunch(event); }); } - + void DataShareServiceImpl::SaveLaunchInfo(const std::string &bundleName, const std::string &userId, const std::string &deviceId) { @@ -533,23 +665,42 @@ void DataShareServiceImpl::SaveLaunchInfo(const std::string &bundleName, const s if (profileInfos.empty()) { return; } - std::map maps; + StoreMetaData meta = MakeMetaData(bundleName, userId, deviceId); for (auto &[uri, value] : profileInfos) { if (uri.find(EXT_URI_SCHEMA) == std::string::npos) { continue; } std::string extUri = uri; extUri.insert(strlen(EXT_URI_SCHEMA), "/"); + if (value.launchInfos.empty()) { + meta.storeId = ""; + AutoLaunchMetaData autoLaunchMetaData = {}; + std::vector tempDatas = {}; + autoLaunchMetaData.datas.emplace(extUri, tempDatas); + autoLaunchMetaData.launchForCleanData = value.launchForCleanData; + MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), autoLaunchMetaData, true); + ZLOGI("without launchInfos, save meta end, bundleName = %{public}s.", bundleName.c_str()); + continue; + } for (const auto &launchInfo : value.launchInfos) { - AutoLaunchMetaData &autoLaunchMetaData = maps[launchInfo.storeId]; + AutoLaunchMetaData autoLaunchMetaData = {}; autoLaunchMetaData.datas.emplace(extUri, launchInfo.tableNames); + autoLaunchMetaData.launchForCleanData = value.launchForCleanData; + meta.storeId = launchInfo.storeId; + MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), autoLaunchMetaData, true); } } - StoreMetaData meta = MakeMetaData(bundleName, userId, deviceId); - for (const auto &[storeId, value] : maps) { - meta.storeId = storeId; - MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), value, true); +} + +bool DataShareServiceImpl::AllowCleanDataLaunchApp(const Event &event, bool launchForCleanData) +{ + auto &evt = static_cast(event); + auto dataInfo = evt.GetDataInfo(); + // 1 means CLOUD_DATA_CLEAN + if (dataInfo.changeType == 1) { + return launchForCleanData; // Applications can be started by default } + return true; } void DataShareServiceImpl::AutoLaunch(const Event &event) @@ -559,24 +710,33 @@ void DataShareServiceImpl::AutoLaunch(const Event &event) StoreMetaData meta = MakeMetaData(dataInfo.bundleName, dataInfo.userId, dataInfo.deviceId, dataInfo.storeId); AutoLaunchMetaData autoLaunchMetaData; if (!MetaDataManager::GetInstance().LoadMeta(std::move(meta.GetAutoLaunchKey()), autoLaunchMetaData, true)) { - return; + meta.storeId = ""; + if (!MetaDataManager::GetInstance().LoadMeta(std::move(meta.GetAutoLaunchKey()), autoLaunchMetaData, true)) { + ZLOGE("NO autoLaunch meta without storeId, bundleName = %{public}s", dataInfo.bundleName.c_str()); + return; + } } - if (autoLaunchMetaData.datas.empty()) { + if (autoLaunchMetaData.datas.empty() || !AllowCleanDataLaunchApp(event, autoLaunchMetaData.launchForCleanData)) { return; } - std::vector uris; for (const auto &[uri, metaTables] : autoLaunchMetaData.datas) { - for (const auto &table : dataInfo.tables) - if (std::find(metaTables.begin(), metaTables.end(), table) != metaTables.end()) { - uris.emplace_back(uri); - break; + if (dataInfo.tables.empty() && dataInfo.changeType == 1) { + ZLOGI("Start to connect extension, bundleName = %{public}s", dataInfo.bundleName.c_str()); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName, wantParams); + return; + } + for (const auto &table : dataInfo.tables) { + if (std::find(metaTables.begin(), metaTables.end(), table) != metaTables.end()) { + ZLOGI("Find table, start to connect extension, bundleName = %{public}s", dataInfo.bundleName.c_str()); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName, wantParams); + break; + } } - } - for (const auto &uri : uris) { - ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName); } } - + StoreMetaData DataShareServiceImpl::MakeMetaData(const std::string &bundleName, const std::string &userId, const std::string &deviceId, const std::string storeId) { @@ -606,7 +766,7 @@ int32_t DataShareServiceImpl::DataShareStatic::OnAppUninstall(const std::string PublishedData::ClearAging(); TemplateData::Delete(bundleName, user); NativeRdb::RdbHelper::ClearCache(); - BundleMgrProxy::GetInstance()->Delete(bundleName, user); + BundleMgrProxy::GetInstance()->Delete(bundleName, user, index); uint32_t tokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(user, bundleName, index); DBDelegate::EraseStoreCache(tokenId); return E_OK; @@ -616,8 +776,8 @@ int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, { ZLOGI("AppExit uid=%{public}d, pid=%{public}d, tokenId=0x%{public}x, bundleName=%{public}s", uid, pid, tokenId, bundleName.c_str()); - RdbSubscriberManager::GetInstance().Delete(tokenId); - PublishedDataSubscriberManager::GetInstance().Delete(tokenId); + RdbSubscriberManager::GetInstance().Delete(tokenId, pid); + PublishedDataSubscriberManager::GetInstance().Delete(tokenId, pid); return E_OK; } @@ -625,7 +785,7 @@ int32_t DataShareServiceImpl::DataShareStatic::OnAppUpdate(const std::string &bu int32_t index) { ZLOGI("%{public}s updated", bundleName.c_str()); - BundleMgrProxy::GetInstance()->Delete(bundleName, user); + BundleMgrProxy::GetInstance()->Delete(bundleName, user, index); std::string prefix = StoreMetaData::GetPrefix( { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(user), "default", bundleName }); std::vector storeMetaData; @@ -650,7 +810,7 @@ int32_t DataShareServiceImpl::OnAppUninstall(const std::string &bundleName, int3 { ZLOGI("AppUninstall user=%{public}d, index=%{public}d, bundleName=%{public}s", user, index, bundleName.c_str()); - BundleMgrProxy::GetInstance()->Delete(bundleName, user); + BundleMgrProxy::GetInstance()->Delete(bundleName, user, index); return E_OK; } @@ -658,7 +818,7 @@ int32_t DataShareServiceImpl::OnAppUpdate(const std::string &bundleName, int32_t { ZLOGI("AppUpdate user=%{public}d, index=%{public}d, bundleName=%{public}s", user, index, bundleName.c_str()); - BundleMgrProxy::GetInstance()->Delete(bundleName, user); + BundleMgrProxy::GetInstance()->Delete(bundleName, user, index); return E_OK; } @@ -778,7 +938,12 @@ int32_t DataShareServiceImpl::GetSilentProxyStatus(const std::string &uri, bool return E_OK; } std::string calledBundleName = uriInfo.bundleName; - uint32_t calledTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(currentUserId, calledBundleName, 0); + int32_t appIndex = 0; + if (!URIUtils::GetAppIndexFromProxyURI(uri, appIndex)) { + return E_APPINDEX_INVALID; + } + uint32_t calledTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID( + currentUserId, calledBundleName, appIndex); if (calledTokenId == 0) { calledTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(0, calledBundleName, 0); } @@ -858,37 +1023,110 @@ int32_t DataShareServiceImpl::UnregisterObserver(const std::string &uri, return obsMgrClient->UnregisterObserver(Uri(uri), obServer); } -int32_t DataShareServiceImpl::Execute(const std::string &uri, const int32_t tokenId, +int32_t DataShareServiceImpl::Execute(const std::string &uri, const std::string &extUri, const int32_t tokenId, bool isRead, ExecuteCallback callback) { DataProviderConfig providerConfig(uri, tokenId); - auto [errCode, provider] = providerConfig.GetProviderInfo(); + auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); if (errCode != E_OK) { - ZLOGE("Provider failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s", tokenId, - errCode, URIUtils::Anonymous(provider.uri).c_str()); + ZLOGE("Provider failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s,visitedUserId:%{public}d", tokenId, + errCode, URIUtils::Anonymous(providerInfo.uri).c_str(), providerInfo.visitedUserId); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_GET_SUPPLIER, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::SUPPLIER_ERROR); return errCode; } - std::string permission = isRead ? provider.readPermission : provider.writePermission; + // when HAP interacts across users, it needs to check across users permission + if (!VerifyAcrossAccountsPermission(providerInfo.currentUserId, providerInfo.visitedUserId, + providerInfo.acrossAccountsPermission, tokenId)) { + ZLOGE("Across accounts permission denied! token:0x%{public}x, uri:%{public}s, current user:%{public}d," + "visited user:%{public}d", tokenId, URIUtils::Anonymous(providerInfo.uri).c_str(), + providerInfo.currentUserId, providerInfo.visitedUserId); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); + return ERROR_PERMISSION_DENIED; + } + std::string permission = isRead ? providerInfo.readPermission : providerInfo.writePermission; if (!permission.empty() && !PermitDelegate::VerifyPermission(permission, tokenId)) { ZLOGE("Permission denied! token:0x%{public}x, permission:%{public}s, uri:%{public}s", - tokenId, permission.c_str(), URIUtils::Anonymous(provider.uri).c_str()); + tokenId, permission.c_str(), URIUtils::Anonymous(providerInfo.uri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); return ERROR_PERMISSION_DENIED; } DataShareDbConfig dbConfig; - auto [code, metaData, dbDelegate] = dbConfig.GetDbConfig(provider.uri, - provider.hasExtension, provider.bundleName, provider.storeName, - provider.singleton ? 0 : provider.currentUserId); + std::string extensionUri = extUri; + if (extensionUri.empty()) { + extensionUri = providerInfo.extensionUri; + } + DataShareDbConfig::DbConfig config {providerInfo.uri, extensionUri, providerInfo.bundleName, + providerInfo.storeName, providerInfo.backup, providerInfo.singleton ? 0 : providerInfo.visitedUserId, + providerInfo.appIndex, providerInfo.hasExtension}; + auto [code, metaData, dbDelegate] = dbConfig.GetDbConfig(config); if (code != E_OK) { ZLOGE("Get dbConfig fail,bundleName:%{public}s,tableName:%{public}s,tokenId:0x%{public}x, uri:%{public}s", - provider.bundleName.c_str(), provider.tableName.c_str(), tokenId, - URIUtils::Anonymous(provider.uri).c_str()); + providerInfo.bundleName.c_str(), providerInfo.tableName.c_str(), tokenId, + URIUtils::Anonymous(providerInfo.uri).c_str()); return code; } - return callback(provider, metaData, dbDelegate); + return callback(providerInfo, metaData, dbDelegate); +} + +bool DataShareServiceImpl::VerifyAcrossAccountsPermission(int32_t currentUserId, int32_t visitedUserId, + const std::string &acrossAccountsPermission, uint32_t callerTokenId) +{ + // if it's SA, or visit itself, no need to verify permission + if (currentUserId == 0 || currentUserId == visitedUserId) { + return true; + } + return PermitDelegate::VerifyPermission(acrossAccountsPermission, callerTokenId); +} + +std::pair DataShareServiceImpl::ExecuteEx(const std::string &uri, const std::string &extUri, + const int32_t tokenId, bool isRead, ExecuteCallbackEx callback) +{ + DataProviderConfig providerConfig(uri, tokenId); + auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); + if (errCode != E_OK) { + ZLOGE("Provider failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s,visitedUserId:%{public}d", tokenId, + errCode, URIUtils::Anonymous(providerInfo.uri).c_str(), providerInfo.visitedUserId); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_GET_SUPPLIER, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::SUPPLIER_ERROR); + return std::make_pair(E_DATA_SUPPLIER_ERROR, 0); + } + // when HAP interacts across users, it needs to check across users permission + if (!VerifyAcrossAccountsPermission(providerInfo.currentUserId, providerInfo.visitedUserId, + providerInfo.acrossAccountsPermission, tokenId)) { + ZLOGE("Across accounts permission denied! token:0x%{public}x, uri:%{public}s, current user:%{public}d," + "visited user:%{public}d", tokenId, URIUtils::Anonymous(providerInfo.uri).c_str(), + providerInfo.currentUserId, providerInfo.visitedUserId); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); + return std::make_pair(ERROR_PERMISSION_DENIED, 0); + } + std::string permission = isRead ? providerInfo.readPermission : providerInfo.writePermission; + if (!permission.empty() && !PermitDelegate::VerifyPermission(permission, tokenId)) { + ZLOGE("Permission denied! token:0x%{public}x, permission:%{public}s, uri:%{public}s", + tokenId, permission.c_str(), URIUtils::Anonymous(providerInfo.uri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); + return std::make_pair(ERROR_PERMISSION_DENIED, 0); + } + DataShareDbConfig dbConfig; + std::string extensionUri = extUri; + if (extensionUri.empty()) { + extensionUri = providerInfo.extensionUri; + } + DataShareDbConfig::DbConfig config {providerInfo.uri, extensionUri, providerInfo.bundleName, + providerInfo.storeName, providerInfo.backup, providerInfo.singleton ? 0 : providerInfo.visitedUserId, + providerInfo.appIndex, providerInfo.hasExtension}; + auto [code, metaData, dbDelegate] = dbConfig.GetDbConfig(config); + if (code != E_OK) { + ZLOGE("Get dbConfig fail,bundleName:%{public}s,tableName:%{public}s,tokenId:0x%{public}x, uri:%{public}s", + providerInfo.bundleName.c_str(), providerInfo.tableName.c_str(), tokenId, + URIUtils::Anonymous(providerInfo.uri).c_str()); + return std::make_pair(code, 0); + } + return callback(providerInfo, metaData, dbDelegate); } int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId) @@ -897,7 +1135,7 @@ int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, co auto [errCode, calledInfo] = calledConfig.GetProviderInfo(); if (errCode == E_URI_NOT_EXIST) { ZLOGE("Create helper invalid uri, token:0x%{public}x, uri:%{public}s", tokenId, - URIUtils::Anonymous(calledInfo.uri).c_str()); + URIUtils::Anonymous(calledInfo.uri).c_str()); return E_OK; } if (errCode != E_OK) { @@ -906,8 +1144,14 @@ int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, co return errCode; } DataShareDbConfig dbConfig; - auto [code, metaData] = dbConfig.GetMetaData(calledInfo.uri, calledInfo.bundleName, - calledInfo.storeName, calledInfo.singleton ? 0 : calledInfo.currentUserId, calledInfo.hasExtension); + DataShareDbConfig::DbConfig dbArg; + dbArg.uri = calledInfo.uri; + dbArg.bundleName = calledInfo.bundleName; + dbArg.storeName = calledInfo.storeName; + dbArg.userId = calledInfo.singleton ? 0 : calledInfo.visitedUserId; + dbArg.hasExtension = calledInfo.hasExtension; + dbArg.appIndex = calledInfo.appIndex; + auto [code, metaData] = dbConfig.GetMetaData(dbArg); if (code != E_OK) { ZLOGE("Get metaData fail,bundleName:%{public}s,tableName:%{public}s,tokenId:0x%{public}x, uri:%{public}s", calledInfo.bundleName.c_str(), calledInfo.tableName.c_str(), tokenId, @@ -931,4 +1175,13 @@ void DataShareServiceImpl::InitSubEvent() sysEventSubscriber->OnBMSReady(); } } + +void DataShareServiceImpl::ReportExcuteFault(uint32_t callingTokenId, DataProviderConfig::ProviderInfo &providerInfo, + int32_t errCode, std::string &func) +{ + std::string appendix = "callingName:" + HiViewFaultAdapter::GetCallingName(callingTokenId).first; + DataShareFaultInfo faultInfo = {CURD_FAILED, providerInfo.bundleName, providerInfo.moduleName, + providerInfo.storeName, func, errCode, appendix}; + HiViewFaultAdapter::ReportDataFault(faultInfo); +} } // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.h b/services/distributeddataservice/service/data_share/data_share_service_impl.h index 5b347469c318d4011ec0d14b37a1776d0ef5a745..0282591b3e56b8a1c669bf733ed9661be41926c0 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -47,14 +47,22 @@ public: using Handler = std::function> &)>; using ExecuteCallback = std::function)>; + using ExecuteCallbackEx = std::function(DataProviderConfig::ProviderInfo &, + DistributedData::StoreMetaData &, std::shared_ptr)>; DataShareServiceImpl() = default; virtual ~DataShareServiceImpl(); int32_t Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) override; int32_t Update(const std::string &uri, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) override; + const DataShareValuesBucket &valuesBucket) override; int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) override; - std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, - const std::vector &columns, int &errCode) override; + std::pair InsertEx(const std::string &uri, const std::string &extUri, + const DataShareValuesBucket &valuesBucket) override; + std::pair UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; + std::pair DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) override; + std::shared_ptr Query(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) override; int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) override; int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) override; std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) override; @@ -87,8 +95,8 @@ public: int32_t GetSilentProxyStatus(const std::string &uri, bool isCreateHelper) override; int32_t RegisterObserver(const std::string &uri, const sptr &remoteObj) override; int32_t UnregisterObserver(const std::string &uri, const sptr &remoteObj) override; - private: + class SystemAbilityStatusChangeListener; using StaticActs = DistributedData::StaticActs; class DataShareStatic : public StaticActs { public: @@ -116,15 +124,24 @@ private: bool SubscribeTimeChanged(); bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); - int32_t Execute(const std::string &uri, const int32_t tokenId, bool isRead, ExecuteCallback callback); + int32_t Execute(const std::string &uri, const std::string &extUri, const int32_t tokenId, + bool isRead, ExecuteCallback callback); + std::pair ExecuteEx(const std::string &uri, const std::string &extUri, const int32_t tokenId, + bool isRead, ExecuteCallbackEx callback); int32_t GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId); - void InitSubEvent(); + void SubscribeCommonEvent(); + static void InitSubEvent(); void AutoLaunch(const DistributedData::Event &event); void SubscribeChange(); + bool AllowCleanDataLaunchApp(const DistributedData::Event &event, bool launchForCleanData); static void SaveLaunchInfo(const std::string &bundleName, const std::string &userId, const std::string &deviceId); static DistributedData::StoreMetaData MakeMetaData(const std::string &bundleName, const std::string &userId, const std::string &deviceId, const std::string storeId = ""); + void ReportExcuteFault(uint32_t callingTokenId, DataProviderConfig::ProviderInfo &providerInfo, + int32_t errCode, std::string &func); + bool VerifyAcrossAccountsPermission(int32_t currentUserId, int32_t visitedUserId, + const std::string &acrossAccountsPermission, uint32_t callerTokenId); static Factory factory_; static constexpr int32_t ERROR = -1; static constexpr int32_t ERROR_PERMISSION_DENIED = -2; diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index c0d0959289a836b8fa151024a0db876cf0d76a61..cf353dcdee0d2daf668408cc79ba66d1404d1f81 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -19,6 +19,8 @@ #include #include "data_share_obs_proxy.h" +#include "hiview_adapter.h" +#include "hiview_fault_adapter.h" #include "ipc_skeleton.h" #include "ishared_result_set.h" #include "itypes_util.h" @@ -89,18 +91,73 @@ int32_t DataShareServiceStub::OnDelete(MessageParcel &data, MessageParcel &reply return 0; } +int32_t DataShareServiceStub::OnInsertEx(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + std::string extUri; + DataShareValuesBucket bucket; + if (!ITypesUtil::Unmarshal(data, uri, extUri, bucket.valuesMap)) { + ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), + bucket.valuesMap.size()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto [errCode, status] = InsertEx(uri, extUri, bucket); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + +int32_t DataShareServiceStub::OnUpdateEx(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + std::string extUri; + DataSharePredicates predicate; + DataShareValuesBucket bucket; + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate, bucket.valuesMap)) { + ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), + bucket.valuesMap.size()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto [errCode, status] = UpdateEx(uri, extUri, predicate, bucket); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + +int32_t DataShareServiceStub::OnDeleteEx(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + std::string extUri; + DataSharePredicates predicate; + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate)) { + ZLOGE("Unmarshal uri:%{public}s", DistributedData::Anonymous::Change(uri).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto [errCode, status] = DeleteEx(uri, extUri, predicate); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + int32_t DataShareServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply) { std::string uri; + std::string extUri; DataSharePredicates predicate; std::vector columns; - if (!ITypesUtil::Unmarshal(data, uri, predicate, columns)) { + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate, columns)) { ZLOGE("Unmarshal uri:%{public}s columns size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), columns.size()); return IPC_STUB_INVALID_DATA_ERR; } int status = 0; - auto result = ISharedResultSet::WriteToParcel(Query(uri, predicate, columns, status), reply); + auto result = ISharedResultSet::WriteToParcel(Query(uri, extUri, predicate, columns, status), reply); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -335,15 +392,19 @@ int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Me } int res = -1; if (code < DATA_SHARE_SERVICE_CMD_MAX) { + auto callingTokenid = IPCSkeleton::GetCallingTokenID(); auto start = std::chrono::steady_clock::now(); res = (this->*HANDLERS[code])(data, reply); auto finish = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(finish - start); + CallerInfo callerInfo(callingTokenid, IPCSkeleton::GetCallingUid(), callingPid, duration.count(), code); if (duration >= TIME_THRESHOLD) { int64_t milliseconds = duration.count(); ZLOGW("over time, code:%{public}u callingPid:%{public}d, cost:%{public}" PRIi64 "ms", code, callingPid, milliseconds); + callerInfo.isSlowRequest = true; } + HiViewAdapter::GetInstance().ReportDataStatistic(callerInfo); } return res; } diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.h b/services/distributeddataservice/service/data_share/data_share_service_stub.h index 9daede9747bfc18d822379b19c8b7a9a84c7fd2c..3a92d14b1033a93625a440dd935b504fbc61c16c 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -51,6 +51,9 @@ private: int32_t OnGetSilentProxyStatus(MessageParcel& data, MessageParcel& reply); int32_t OnRegisterObserver(MessageParcel& data, MessageParcel& reply); int32_t OnUnregisterObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnInsertEx(MessageParcel& data, MessageParcel& reply); + int32_t OnUpdateEx(MessageParcel& data, MessageParcel& reply); + int32_t OnDeleteEx(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (DataShareServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[DATA_SHARE_SERVICE_CMD_MAX] = { &DataShareServiceStub::OnInsert, @@ -74,7 +77,10 @@ private: &DataShareServiceStub::OnSetSilentSwitch, &DataShareServiceStub::OnGetSilentProxyStatus, &DataShareServiceStub::OnRegisterObserver, - &DataShareServiceStub::OnUnregisterObserver}; + &DataShareServiceStub::OnUnregisterObserver, + &DataShareServiceStub::OnInsertEx, + &DataShareServiceStub::OnDeleteEx, + &DataShareServiceStub::OnUpdateEx}; static constexpr int SLEEP_TIME = 300; static constexpr int TRY_TIMES = 5; std::atomic isReady_ = false; diff --git a/services/distributeddataservice/service/data_share/dfx/hiview_adapter.cpp b/services/distributeddataservice/service/data_share/dfx/hiview_adapter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21e4eba9df2bbebf4269b8ef53ccd78b9ff02861 --- /dev/null +++ b/services/distributeddataservice/service/data_share/dfx/hiview_adapter.cpp @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define LOG_TAG "HiViewAdapter" + +#include "hiview_adapter.h" + +#include +#include "hiview_fault_adapter.h" +#include "log_print.h" + +namespace OHOS { +namespace DataShare { +namespace { +constexpr char DOMAIN[] = "DISTDATAMGR"; +constexpr const char *EVENT_NAME = "DATA_SHARE_STATISTIC"; +constexpr const uint32_t MAX_COLLECT_COUNT = 20; +constexpr const uint32_t MIN_CALL_COUNT = 1000; +constexpr const size_t PARAMS_SIZE = 7; +} + +using namespace std::chrono; + +HiViewAdapter& HiViewAdapter::GetInstance() +{ + static HiViewAdapter instance; + return instance; +} + +void HiViewAdapter::ReportDataStatistic(const CallerInfo &callerInfo) +{ + if (executors_ == nullptr) { + ZLOGE("executors is nullptr, collect failed"); + return; + } + + callers_.Compute(callerInfo.callerTokenId, [&callerInfo, this](const uint64_t &key, CallerTotalInfo &value) { + if (value.totalCount == 0) { + value.callerUid = callerInfo.callerUid; + std::string callingName = HiViewFaultAdapter::GetCallingName(key).first; + value.callerName = callingName.empty() ? std::to_string(callerInfo.callerPid) : callingName; + } + value.totalCount += 1; + value.maxCostTime = std::max(callerInfo.costTime, value.maxCostTime); + value.totalCostTime += callerInfo.costTime; + value.slowRequestCount = value.slowRequestCount + (callerInfo.isSlowRequest ? 1 : 0); + auto it = funcIdMap_.find(callerInfo.funcId); + if (it != funcIdMap_.end()) { + auto funcName = it->second; + value.funcCounts[funcName] = value.funcCounts[funcName] + 1; + } + return true; + }); +} + +void HiViewAdapter::InvokeData() +{ + uint32_t mapSize = callers_.Size(); + if (mapSize == 0) { return; } + std::vector callerTotalInfos; + GetCallerTotalInfoVec(callerTotalInfos); + uint32_t count = std::min(static_cast(callerTotalInfos.size()), MAX_COLLECT_COUNT); + if (count == 0) { return; } + int64_t callerUids[count]; + char* callerNames[count]; + int64_t totalCounts[count]; + int64_t slowRequestCounts[count]; + int64_t maxCostTimes[count]; + int64_t totalCostTimes[count]; + char* funcCounts[count]; + std::vector funcCountsHolder(count); + for (uint32_t i = 0; i < count; i++) { + CallerTotalInfo &callerTotalInfo = callerTotalInfos[i]; + callerUids[i] = callerTotalInfo.callerUid; + callerNames[i] = const_cast(callerTotalInfo.callerName.c_str()); + totalCounts[i] = callerTotalInfo.totalCount; + slowRequestCounts[i] = callerTotalInfo.slowRequestCount; + maxCostTimes[i] = callerTotalInfo.maxCostTime; + totalCostTimes[i] = callerTotalInfo.totalCostTime; + std::string funcCount = "{"; + for (const auto &it : callerTotalInfo.funcCounts) { + funcCount += it.first + ":" + std::to_string(it.second) + ","; + } + funcCount = funcCount.substr(0, funcCount.size() - 1) + "}"; + funcCountsHolder[i] = std::move(funcCount); + funcCounts[i] = const_cast(funcCountsHolder[i].c_str()); + } + + HiSysEventParam callerUid = { .name = "COLLIE_UID", .t = HISYSEVENT_INT64_ARRAY, + .v = { .array = callerUids }, .arraySize = count }; + HiSysEventParam callerName = { .name = "CALLER_NAME", .t = HISYSEVENT_STRING_ARRAY, + .v = { .array = callerNames }, .arraySize = count }; + HiSysEventParam totalCount = { .name = "TOTAL_COUNT", .t = HISYSEVENT_INT64_ARRAY, + .v = { .array = totalCounts }, .arraySize = count }; + HiSysEventParam slowRequestCount = { .name = "SLOW_RQUEST_COUNT", .t = HISYSEVENT_INT64_ARRAY, + .v = { .array = slowRequestCounts }, .arraySize = count }; + HiSysEventParam maxCostTime = { .name = "MAX_COST_TIME", .t = HISYSEVENT_INT64_ARRAY, + .v = { .array = maxCostTimes }, .arraySize = count }; + HiSysEventParam totalCostTime = { .name = "TOTAL_COST_TIME", .t = HISYSEVENT_INT64_ARRAY, + .v = { .array = totalCostTimes }, .arraySize = count }; + HiSysEventParam funcCount = { .name = "FUNC_COUNTS", .t = HISYSEVENT_STRING_ARRAY, + .v = { .array = funcCounts }, .arraySize = count }; + HiSysEventParam params[] = {callerUid, callerName, totalCount, slowRequestCount, + maxCostTime, totalCostTime, funcCount}; + int res = OH_HiSysEvent_Write(DOMAIN, EVENT_NAME, HISYSEVENT_STATISTIC, params, PARAMS_SIZE); + ZLOGI("OH_HiSysEvent_Write, res = %{public}d", res); +} + +void HiViewAdapter::GetCallerTotalInfoVec(std::vector &callerTotalInfos) +{ + callers_.EraseIf([&callerTotalInfos](const uint64_t key, CallerTotalInfo &callerTotalInfo) { + if (callerTotalInfo.totalCount >= MIN_CALL_COUNT) + callerTotalInfos.push_back(callerTotalInfo); + return true; + }); + std::sort(callerTotalInfos.begin(), callerTotalInfos.end(), + [](const CallerTotalInfo &first, const CallerTotalInfo &second) { + return first.totalCount > second.totalCount; + }); +} +} // namespace DataShare +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/dfx/hiview_adapter.h b/services/distributeddataservice/service/data_share/dfx/hiview_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..0b13a3bb017df3a761d049ee88c75c49d0c45ef3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/dfx/hiview_adapter.h @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DATASHARESERVICE_HIVIEW_ADAPTER_H +#define DATASHARESERVICE_HIVIEW_ADAPTER_H + + +#include "hiview_base_adapter.h" +#include "concurrent_map.h" +#include "data_share_service_stub.h" +namespace OHOS { +namespace DataShare { +struct CallerInfo { + uint64_t callerTokenId = 0; + uint64_t callerUid = 0; + uint64_t callerPid = 0; + uint64_t costTime = 0; + bool isSlowRequest = false; + uint32_t funcId = 0; + + CallerInfo(uint64_t tokenId, uint64_t uid, uint64_t pid, uint64_t time, uint32_t id) + : callerTokenId(tokenId), callerUid(uid), callerPid(pid), costTime(time), funcId(id) + {} +}; + +struct CallerTotalInfo { + uint64_t callerUid = 0; + uint64_t totalCount = 0; + uint64_t slowRequestCount = 0; + uint64_t maxCostTime = 0; + uint64_t totalCostTime = 0; + std::string callerName; + std::map funcCounts; +}; + +class HiViewAdapter : public HiViewBaseAdapter { +public: + static HiViewAdapter &GetInstance(); + void InvokeData() override; + void ReportDataStatistic(const CallerInfo &callerInfo); + +private: + ConcurrentMap callers_; + std::map funcIdMap_ = { + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_QUERY), "OnQuery"}, + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_INSERTEX), "OnInsertEx"}, + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_DELETEEX), "OnDeleteEx"}, + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_UPDATEEX), "OnUpdateEx"}, + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_NOTIFY_OBSERVERS), "OnNotifyObserver"}, + {static_cast(IDataShareService::DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS), + "OnGetSilentProxyStatus"} + }; + void GetCallerTotalInfoVec(std::vector &callerTotalInfos); +}; +} // namespace DataShare +} // namespace OHOS +#endif // DATASHARESERVICE_HIVIEW_ADAPTER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/dfx/hiview_base_adapter.h b/services/distributeddataservice/service/data_share/dfx/hiview_base_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..50a6eaa7b4996562b14d9714db1b701c723f51f6 --- /dev/null +++ b/services/distributeddataservice/service/data_share/dfx/hiview_base_adapter.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DATASHARESERVICE_HIVIEW_BASE_ADAPTER_H +#define DATASHARESERVICE_HIVIEW_BASE_ADAPTER_H + +#include + +#include "executor_pool.h" +#include "hisysevent_c.h" + +namespace OHOS { +namespace DataShare { + +class HiViewBaseAdapter { +public: + const int waitTime = 180 * 60; + std::shared_ptr executors_ = nullptr; + std::atomic running_ = false; + + void SetThreadPool(std::shared_ptr executors) + { + executors_ = executors; + StartTimerThread(); + } + + void StartTimerThread() + { + if (executors_ == nullptr) { + return; + } + if (running_.exchange(true)) { + return; + } + auto interval = std::chrono::seconds(waitTime); + auto fun = [this]() { InvokeData(); }; + executors_->Schedule(fun, interval); + } + + virtual void InvokeData() = 0; +}; +} +} +#endif // DATASHARESERVICE_HIVIEW_ADAPTER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.cpp b/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db04c7eb5ecad5012dce54aabe833ccfe50cf484 --- /dev/null +++ b/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.cpp @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define LOG_TAG "HiViewFaultAdapter" + +#include "hiview_fault_adapter.h" + +#include +#include +#include "log_print.h" + +namespace OHOS { +namespace DataShare { +namespace { + constexpr char DOMAIN[] = "DISTDATAMGR"; + constexpr const char *EVENT_NAME = "DISTRIBUTED_DATA_SHARE_FAULT"; + constexpr const size_t PARAMS_SIZE = 8; + // digits for milliseconds + constexpr uint8_t MILLSECOND_DIGIT = 3; +} + +void HiViewFaultAdapter::ReportDataFault(const DataShareFaultInfo &faultInfo) +{ + auto now = std::chrono::system_clock::now(); + auto t = std::chrono::system_clock::to_time_t(now); + std::stringstream ss; + ss << std::put_time(std::localtime(&t), "%F %T"); + // get milliseconds + auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + ss << '.' << std::setfill('0') << std::setw(MILLSECOND_DIGIT) << ms.count(); + auto time = ss.str(); + HiSysEventParam faultTime = { .name = "FAULT_TIME", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(time.c_str()) }, .arraySize = 0 }; + HiSysEventParam faultType = { .name = "FAULT_TYPE", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.faultType.c_str()) }, .arraySize = 0 }; + HiSysEventParam bundleName = { .name = "BUNDLE_NAME", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.bundleName.c_str()) }, .arraySize = 0 }; + HiSysEventParam moduleName = { .name = "MODULE_NAME", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.moduleName.c_str()) }, .arraySize = 0 }; + HiSysEventParam storeName = { .name = "STORE_NAME", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.storeName.c_str()) }, .arraySize = 0 }; + HiSysEventParam businessType = { .name = "BUSINESS_TYPE", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.businessType.c_str()) }, .arraySize = 0 }; + HiSysEventParam errorCode = { .name = "ERROR_CODE", .t = HISYSEVENT_INT32, + .v = { .i32 = faultInfo.errorCode }, .arraySize = 0 }; + HiSysEventParam appendix = { .name = "APPENDIX", .t = HISYSEVENT_STRING, + .v = { .s = const_cast(faultInfo.appendix.c_str()) }, .arraySize = 0 }; + HiSysEventParam params[] = { faultTime, faultType, bundleName, moduleName, + storeName, businessType, errorCode, appendix }; + int res = OH_HiSysEvent_Write(DOMAIN, EVENT_NAME, HISYSEVENT_FAULT, params, PARAMS_SIZE); + ZLOGI("OH_HiSysEvent_Write, res = %{public}d", res); +} + +std::pair HiViewFaultAdapter::GetCallingName(uint32_t callingTokenid) +{ + std::string callingName; + auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callingTokenid); + int result = -1; + if (tokenType == Security::AccessToken::TOKEN_HAP) { + Security::AccessToken::HapTokenInfo tokenInfo; + result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenid, tokenInfo); + if (result == Security::AccessToken::RET_SUCCESS) { + callingName = tokenInfo.bundleName; + } + } else if (tokenType == Security::AccessToken::TOKEN_NATIVE || tokenType == Security::AccessToken::TOKEN_SHELL) { + Security::AccessToken::NativeTokenInfo tokenInfo; + result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(callingTokenid, tokenInfo); + if (result == Security::AccessToken::RET_SUCCESS) { + callingName = tokenInfo.processName; + } + } else { + ZLOGE("tokenType is invalid, tokenType:%{public}d, Tokenid:%{public}x", tokenType, callingTokenid); + } + return std::make_pair(callingName, result); +} + +RdbTimeCostInfo::~RdbTimeCostInfo() +{ + auto end = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + if (duration > TIME_OUT_MS) { + int64_t milliseconds = duration.count(); + std::string appendix = "callingName:" + HiViewFaultAdapter::GetCallingName(callingTokenId).first; + appendix += ",cost:" + std::to_string(milliseconds) + "ms"; + DataShareFaultInfo faultInfo{TIME_OUT, bundleName, moduleName, storeName, businessType, errorCode, appendix}; + HiViewFaultAdapter::ReportDataFault(faultInfo); + } +} +} +} \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.h b/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..e7a33b273b3a4702cfef0c7f54ce66ef0ffc03e8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/dfx/hiview_fault_adapter.h @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DATASHARESERVICE_HIVIEW_FAULT_ADAPTER_H +#define DATASHARESERVICE_HIVIEW_FAULT_ADAPTER_H + +#include +#include +#include +#include "accesstoken_kit.h" +#include "hisysevent_c.h" +namespace OHOS { +namespace DataShare { +struct DataShareFaultInfo { + std::string faultType; + std::string bundleName; + std::string moduleName; + std::string storeName; + std::string businessType; + int32_t errorCode; + std::string appendix; +}; + +struct RdbTimeCostInfo { + std::chrono::time_point start = std::chrono::steady_clock::now(); + std::string bundleName; + std::string moduleName; + std::string storeName; + std::string businessType; + int32_t errorCode = 0; + uint64_t callingTokenId; + + explicit RdbTimeCostInfo(const std::string &bundleName, const std::string &moduleName, + const std::string &storeName, const std::string &businessType, + uint64_t tokenId) : bundleName(bundleName), moduleName(moduleName), + storeName(storeName), businessType(businessType), callingTokenId(tokenId) + {} + ~RdbTimeCostInfo(); +}; + + +class HiViewFaultAdapter { +public: + static void ReportDataFault(const DataShareFaultInfo &faultInfo); + static std::pair GetCallingName(uint32_t callingTokenid); +}; + +inline const char* TIME_OUT = "TIME_OUT"; +inline const char* RESULTSET_FULL = "RESULTSET_FULL"; +inline const char* CURD_FAILED = "CURD_FAILED"; +inline const std::chrono::milliseconds TIME_OUT_MS = std::chrono::milliseconds(300); +} +} +#endif \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/idata_share_service.h b/services/distributeddataservice/service/data_share/idata_share_service.h index aa2da754aa2d58a7de165d45381b069222b72295..a9cee7dc0d0a43de1a518aa8162faa511f2f20cb 100644 --- a/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/services/distributeddataservice/service/data_share/idata_share_service.h @@ -52,6 +52,9 @@ public: DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS, DATA_SHARE_SERVICE_CMD_REGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_UNREGISTER_OBSERVER, + DATA_SHARE_SERVICE_CMD_INSERTEX, + DATA_SHARE_SERVICE_CMD_DELETEEX, + DATA_SHARE_SERVICE_CMD_UPDATEEX, DATA_SHARE_SERVICE_CMD_MAX }; @@ -59,11 +62,17 @@ public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataShareService"); virtual int32_t Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) = 0; - virtual int32_t Update( - const std::string &uri, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; + virtual int32_t Update(const std::string &uri, const DataSharePredicates &predicate, + const DataShareValuesBucket &valuesBucket) = 0; virtual int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) = 0; - virtual std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, - const std::vector &columns, int &errCode) = 0; + virtual std::pair InsertEx( + const std::string &uri, const std::string &extUri, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) = 0; + virtual std::shared_ptr Query(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; virtual int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) = 0; virtual int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) = 0; virtual std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) = 0; diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp index 3cc60cdb7fc6406e68f21777c17d943b38421513..f0ce98ceca2dc383076b6726044bb0e0c8aa7e5c 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp @@ -32,6 +32,9 @@ bool LoadConfigCommonStrategy::operator()(std::shared_ptr context) context->callerTokenId = IPCSkeleton::GetCallingTokenID(); } context->currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(context->callerTokenId); + if (!URIUtils::GetAppIndexFromProxyURI(context->uri, context->appIndex)) { + return false; + } // sa, userId is in uri, caller token id is from first caller tokenId if (context->currentUserId == 0) { GetInfoFromProxyURI( diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp index f47d62e3cd7a15d36f4d5b7d00c7d5d0521a4d9e..ee18ab8a769cf2faa5ac38cb1d4a1be58e7c336a 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp @@ -31,7 +31,7 @@ LoadConfigDataInfoStrategy::LoadConfigDataInfoStrategy() { } static bool QueryMetaData(const std::string &bundleName, const std::string &storeName, - DistributedData::StoreMetaData &metaData, const int32_t userId) + DistributedData::StoreMetaData &metaData, const int32_t userId, const int32_t appIndex) { DistributedData::StoreMetaData meta; meta.deviceId = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -52,10 +52,13 @@ bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr conte return true; } DistributedData::StoreMetaData metaData; - if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { + if (!QueryMetaData( + context->calledBundleName, context->calledStoreName, metaData, context->currentUserId, context->appIndex)) { // connect extension and retry - ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName); - if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName, wantParams); + if (!QueryMetaData( + context->calledBundleName, context->calledStoreName, metaData, context->currentUserId, context->appIndex)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; return false; @@ -72,10 +75,11 @@ bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr conte bool LoadConfigSingleDataInfoStrategy::operator()(std::shared_ptr context) { DistributedData::StoreMetaData metaData; - if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0, context->appIndex)) { // connect extension and retry - ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName); - if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName, wantParams); + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0, context->appIndex)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; return false; diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp index 78122821059db94d8d98412ce31f2968eb9ba7a0..09dd531f94c74430032d5d8a5d107dad7a711ad4 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp +++ b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp @@ -39,7 +39,8 @@ int PublishedDataSubscriberManager::Add( key, [&observer, &firstCallerTokenId, this](const PublishedDataKey &key, std::vector &value) { ZLOGI("add publish subscriber, uri %{public}s tokenId 0x%{public}x", DistributedData::Anonymous::Change(key.key).c_str(), firstCallerTokenId); - value.emplace_back(observer, firstCallerTokenId, IPCSkeleton::GetCallingTokenID()); + value.emplace_back(observer, firstCallerTokenId, IPCSkeleton::GetCallingTokenID(), + IPCSkeleton::GetCallingPid()); return true; }); return E_OK; @@ -64,13 +65,13 @@ int PublishedDataSubscriberManager::Delete(const PublishedDataKey &key, uint32_t return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -void PublishedDataSubscriberManager::Delete(uint32_t callerTokenId) +void PublishedDataSubscriberManager::Delete(uint32_t callerTokenId, uint32_t callerPid) { - publishedDataCache_.EraseIf([&callerTokenId](const auto &key, std::vector &value) { + publishedDataCache_.EraseIf([&callerTokenId, &callerPid](const auto &key, std::vector &value) { for (auto it = value.begin(); it != value.end();) { - if (it->callerTokenId == callerTokenId) { - ZLOGI("erase start, uri is %{public}s, tokenId is 0x%{public}x", - DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId); + if (it->callerTokenId == callerTokenId && it->callerPid == callerPid) { + ZLOGI("erase start, uri is %{public}s, tokenId is 0x%{public}x, pid is %{public}d", + DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId, callerPid); it = value.erase(it); } else { it++; @@ -266,8 +267,8 @@ bool PublishedDataKey::operator!=(const PublishedDataKey &rhs) const } PublishedDataSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, - uint32_t firstCallerTokenId, uint32_t callerTokenId) - : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId) + uint32_t firstCallerTokenId, uint32_t callerTokenId, uint32_t callerPid) + : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId), callerPid(callerPid) { } } // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h index e22e87015ebfe28a456e8080306b862ba0dcd06a..37356d7e4cdafcff08ca7f33e9763229fae80c77 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h +++ b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h @@ -44,7 +44,7 @@ public: int Add(const PublishedDataKey &key, const sptr observer, uint32_t firstCallerTokenId); int Delete(const PublishedDataKey &key, uint32_t firstCallerTokenId); - void Delete(uint32_t callerTokenId); + void Delete(uint32_t callerTokenId, uint32_t callerPid); int Disable(const PublishedDataKey &key, uint32_t firstCallerTokenId); int Enable(const PublishedDataKey &key, uint32_t firstCallerTokenId); void Emit(const std::vector &keys, int32_t userId, const std::string &ownerBundleName, @@ -58,10 +58,11 @@ public: private: struct ObserverNode { ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, - uint32_t callerTokenId = 0); + uint32_t callerTokenId = 0, uint32_t callerPid = 0); sptr observer; uint32_t firstCallerTokenId; uint32_t callerTokenId; + uint32_t callerPid; bool enabled = true; bool isNotifyOnEnabled = false; }; diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp index c5caf20267bcd352139faeda96a92573986de0a7..9ecc0c8407819b0fb05de063e9d6bc3536b3f1cb 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp +++ b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp @@ -118,9 +118,10 @@ int RdbSubscriberManager::Add(const Key &key, const sptr rdbCache_.Compute(key, [&observer, &context, executorPool, this](const auto &key, auto &value) { ZLOGI("add subscriber, uri %{private}s tokenId 0x%{public}x", key.uri.c_str(), context->callerTokenId); auto callerTokenId = IPCSkeleton::GetCallingTokenID(); - value.emplace_back(observer, context->callerTokenId, callerTokenId); + auto callerPid = IPCSkeleton::GetCallingPid(); + value.emplace_back(observer, context->callerTokenId, callerTokenId, callerPid); std::vector node; - node.emplace_back(observer, context->callerTokenId, callerTokenId); + node.emplace_back(observer, context->callerTokenId, callerTokenId, callerPid); ExecutorPool::Task task = [key, node, context, this]() { LoadConfigDataInfoStrategy loadDataInfo; if (!loadDataInfo(context)) { @@ -163,11 +164,11 @@ int RdbSubscriberManager::Delete(const Key &key, uint32_t firstCallerTokenId) return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -void RdbSubscriberManager::Delete(uint32_t callerTokenId) +void RdbSubscriberManager::Delete(uint32_t callerTokenId, uint32_t callerPid) { - rdbCache_.EraseIf([&callerTokenId, this](const auto &key, std::vector &value) { + rdbCache_.EraseIf([&callerTokenId, &callerPid, this](const auto &key, std::vector &value) { for (auto it = value.begin(); it != value.end();) { - if (it->callerTokenId == callerTokenId) { + if (it->callerTokenId == callerTokenId && it->callerPid == callerPid) { it = value.erase(it); } else { it++; @@ -248,14 +249,19 @@ void RdbSubscriberManager::Emit(const std::string &uri, int32_t userId, if (!URIUtils::IsDataProxyURI(uri)) { return; } - rdbCache_.ForEach([&uri, &userId, &metaData, this](const Key &key, std::vector &val) { + bool hasObserver = false; + rdbCache_.ForEach([&uri, &userId, &metaData, &hasObserver, this](const Key &key, std::vector &val) { if (key.uri != uri) { return false; } + hasObserver = true; Notify(key, userId, val, metaData.dataDir, metaData.version); SetObserverNotifyOnEnabled(val); return false; }); + if (!hasObserver) { + return; + } SchedulerManager::GetInstance().Execute( uri, userId, metaData.dataDir, metaData.version, metaData.bundleName); } @@ -321,7 +327,7 @@ int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vect DistributedData::StoreMetaData meta; meta.dataDir = rdbDir; meta.bundleName = key.bundleName; - auto delegate = DBDelegate::Create(meta); + auto delegate = DBDelegate::Create(meta, key.uri); if (delegate == nullptr) { ZLOGE("Create fail %{public}s %{public}s", DistributedData::Anonymous::Change(key.uri).c_str(), key.bundleName.c_str()); @@ -339,7 +345,8 @@ int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vect changeNode.data_.emplace_back("{\"" + predicate.key_ + "\":" + result + "}"); } - ZLOGI("emit, size %{public}zu %{private}s", val.size(), changeNode.uri_.c_str()); + ZLOGI("emit, valSize: %{public}zu, dataSize:%{public}zu, uri:%{public}s,", + val.size(), changeNode.data_.size(), DistributedData::Anonymous::Change(changeNode.uri_).c_str()); for (const auto &callback : val) { if (callback.enabled && callback.observer != nullptr) { callback.observer->OnChangeFromRdb(changeNode); @@ -353,7 +360,8 @@ void RdbSubscriberManager::Clear() rdbCache_.Clear(); } -void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context) +void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, + const std::string &bundleName, std::shared_ptr context) { if (!URIUtils::IsDataProxyURI(uri)) { return; @@ -370,12 +378,14 @@ void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, st SetObserverNotifyOnEnabled(val); return false; }); - SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version, context->calledBundleName); + Key executeKey(uri, subscriberId, bundleName); + SchedulerManager::GetInstance().Execute(executeKey, context->currentUserId, + context->calledSourceDir, context->version); } RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, - uint32_t firstCallerTokenId, uint32_t callerTokenId) - : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId) + uint32_t firstCallerTokenId, uint32_t callerTokenId, uint32_t callerPid) + : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId), callerPid(callerPid) { } -} // namespace OHOS::DataShare \ No newline at end of file +} // namespace OHOS::DataShare + diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h index 751d64d5d762fb199d67337f40fd2637acfcaf14..74311d18838049c171b3987ab3cd48e4092b0965 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h +++ b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h @@ -58,10 +58,11 @@ public: int Add(const Key &key, const sptr observer, std::shared_ptr context, std::shared_ptr executorPool); int Delete(const Key &key, uint32_t firstCallerTokenId); - void Delete(uint32_t callerTokenId); + void Delete(uint32_t callerTokenId, uint32_t callerPid); int Disable(const Key &key, uint32_t firstCallerTokenId); int Enable(const Key &key, std::shared_ptr context); - void Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context); + void Emit(const std::string &uri, int64_t subscriberId, const std::string &bundleName, + std::shared_ptr context); void Emit(const std::string &uri, std::shared_ptr context); void Emit(const std::string &uri, int32_t userId, DistributedData::StoreMetaData &metaData); void EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version); @@ -71,10 +72,11 @@ public: private: struct ObserverNode { ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, - uint32_t callerTokenId = 0); + uint32_t callerTokenId = 0, uint32_t callerPid = 0); sptr observer; uint32_t firstCallerTokenId; uint32_t callerTokenId; + uint32_t callerPid; bool enabled = true; bool isNotifyOnEnabled = false; }; diff --git a/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp b/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp index e802950ae503f0cb4b2b71ef4e649eb6adcf40d1..b0fe15ee2318ac49b302c0b461f0fdd80de88cd6 100644 --- a/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp +++ b/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp @@ -47,7 +47,9 @@ void SysEventSubscriber::NotifyDataShareReady() AAFwk::Want want; want.SetAction("usual.event.DATA_SHARE_READY"); EventFwk::CommonEventData CommonEventData { want }; - if (!EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData)) { + EventFwk::CommonEventPublishInfo publishInfo; + publishInfo.SetSticky(true); + if (!EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData, publishInfo)) { ZLOGE("Notify dataShare ready failed."); return; } diff --git a/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp b/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp index c8f6a476eeb7caa312d5465131ad013df26e3ace..a90eb98ef0989349283b16ddb47a6f99e947b545 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp @@ -38,6 +38,7 @@ #include "water_version_manager.h" #include "device_manager_adapter.h" #include "utils/anonymous.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace DistributedData; @@ -49,6 +50,31 @@ using ClearMode = DistributedDB::ClearMode; using DMAdapter = DistributedData::DeviceManagerAdapter; using DBInterceptedData = DistributedDB::InterceptedData; constexpr int UUID_WIDTH = 4; +const std::map KVDBGeneralStore::dbStatusMap_ = { + { DBStatus::OK, GenErr::E_OK }, + { DBStatus::CLOUD_NETWORK_ERROR, GenErr::E_NETWORK_ERROR }, + { DBStatus::CLOUD_LOCK_ERROR, GenErr::E_LOCKED_BY_OTHERS }, + { DBStatus::CLOUD_FULL_RECORDS, GenErr::E_RECODE_LIMIT_EXCEEDED }, + { DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT, GenErr::E_NO_SPACE_FOR_ASSET }, + { DBStatus::CLOUD_SYNC_TASK_MERGED, GenErr::E_SYNC_TASK_MERGED }, + { DBStatus::BUSY, GenErr::E_DB_ERROR }, + { DBStatus::DB_ERROR, GenErr::E_DB_ERROR }, + { DBStatus::INVALID_ARGS, GenErr::E_INVALID_ARGS }, + { DBStatus::NOT_FOUND, GenErr::E_RECORD_NOT_FOUND }, + { DBStatus::INVALID_VALUE_FIELDS, GenErr::E_INVALID_VALUE_FIELDS }, + { DBStatus::INVALID_FIELD_TYPE, GenErr::E_INVALID_FIELD_TYPE }, + { DBStatus::CONSTRAIN_VIOLATION, GenErr::E_CONSTRAIN_VIOLATION }, + { DBStatus::INVALID_FORMAT, GenErr::E_INVALID_FORMAT }, + { DBStatus::INVALID_QUERY_FORMAT, GenErr::E_INVALID_QUERY_FORMAT }, + { DBStatus::INVALID_QUERY_FIELD, GenErr::E_INVALID_QUERY_FIELD }, + { DBStatus::NOT_SUPPORT, GenErr::E_NOT_SUPPORT }, + { DBStatus::TIME_OUT, GenErr::E_TIME_OUT }, + { DBStatus::OVER_MAX_LIMITS, GenErr::E_OVER_MAX_LIMITS }, + { DBStatus::EKEYREVOKED_ERROR, GenErr::E_SECURITY_LEVEL_ERROR }, + { DBStatus::SECURITY_OPTION_CHECK_ERROR, GenErr::E_SECURITY_LEVEL_ERROR }, +}; + +constexpr uint32_t LOCK_TIMEOUT = 3600; // second static DBSchema GetDBSchema(const Database &database) { DBSchema schema; @@ -156,7 +182,6 @@ KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) SetDBReceiveDataInterceptor(meta.storeType); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_FOREIGN, &observer_); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_CLOUD, &observer_); - InitWaterVersion(meta); if (DeviceMatrix::GetInstance().IsDynamic(meta) || DeviceMatrix::GetInstance().IsStatics(meta)) { delegate_->SetRemotePushFinishedNotify([meta](const DistributedDB::RemotePushNotifyInfo &info) { DeviceMatrix::GetInstance().OnExchanged(info.deviceId, meta, DeviceMatrix::ChangeType::CHANGE_REMOTE); @@ -243,7 +268,11 @@ bool KVDBGeneralStore::IsBound() int32_t KVDBGeneralStore::Close(bool isForce) { - std::unique_lock lock(rwMutex_); + std::unique_lock lock(rwMutex_, std::chrono::seconds(isForce ? LOCK_TIMEOUT : 0)); + if (!lock) { + return GeneralError::E_BUSY; + } + if (delegate_ == nullptr) { return GeneralError::E_OK; } @@ -303,6 +332,11 @@ int32_t KVDBGeneralStore::MergeMigratedData(const std::string &tableName, VBucke return GeneralError::E_NOT_SUPPORT; } +int32_t KVDBGeneralStore::CleanTrackerData(const std::string &tableName, int64_t cursor) +{ + return GeneralError::E_NOT_SUPPORT; +} + KVDBGeneralStore::DBSyncCallback KVDBGeneralStore::GetDBSyncCompleteCB(DetailAsync async) { if (!async) { @@ -322,13 +356,14 @@ KVDBGeneralStore::DBSyncCallback KVDBGeneralStore::GetDBSyncCompleteCB(DetailAsy }; } -DBStatus KVDBGeneralStore::CloudSync( - const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, int64_t wait) +DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, + int64_t wait, const std::string &prepareTraceId) { DistributedDB::CloudSyncOption syncOption; syncOption.devices = devices; syncOption.mode = cloudSyncMode; syncOption.waitTime = wait; + syncOption.prepareTraceId = prepareTraceId; syncOption.lockAction = DistributedDB::LockAction::NONE; if (storeInfo_.user == 0) { std::vector users; @@ -340,26 +375,27 @@ DBStatus KVDBGeneralStore::CloudSync( return delegate_->Sync(syncOption, GetDBProcessCB(async)); } -int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) +std::pair KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const SyncParam &syncParam) { - auto syncMode = GeneralStore::GetSyncMode(syncParm.mode); + auto syncMode = GeneralStore::GetSyncMode(syncParam.mode); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d", devices.size(), - devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncParm.mode); - return GeneralError::E_ALREADY_CLOSED; + devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncParam.mode); + return { GeneralError::E_ALREADY_CLOSED, DBStatus::OK }; } DBStatus dbStatus; auto dbMode = DistributedDB::SyncMode(syncMode); if (syncMode > NEARBY_END && syncMode < CLOUD_END) { if (!enableCloud_) { - return GeneralError::E_NOT_SUPPORT; + return { GeneralError::E_NOT_SUPPORT, DBStatus::OK }; } - dbStatus = CloudSync(devices, dbMode, async, syncParm.wait); + dbStatus = CloudSync(devices, dbMode, async, syncParam.wait, syncParam.prepareTraceId); } else { if (devices.empty()) { - ZLOGE("Devices is empty! mode:%{public}d", syncParm.mode); - return GeneralError::E_INVALID_ARGS; + ZLOGE("Devices is empty! mode:%{public}d", syncParam.mode); + return { GeneralError::E_INVALID_ARGS, DBStatus::OK }; } KVDBQuery *kvQuery = nullptr; auto ret = query.QueryInterface(kvQuery); @@ -367,7 +403,7 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs if (ret == GeneralError::E_OK && kvQuery != nullptr && kvQuery->IsValidQuery()) { dbQuery = kvQuery->GetDBQuery(); } else { - return GeneralError::E_INVALID_ARGS; + return { GeneralError::E_INVALID_ARGS, DBStatus::OK }; } if (syncMode == NEARBY_SUBSCRIBE_REMOTE) { dbStatus = delegate_->SubscribeRemoteQuery(devices, GetDBSyncCompleteCB(std::move(async)), dbQuery, false); @@ -385,10 +421,10 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs dbStatus = DistributedDB::INVALID_ARGS; } } - return ConvertStatus(dbStatus); + return { ConvertStatus(dbStatus), dbStatus }; } -void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId) +void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account) { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { @@ -399,22 +435,28 @@ void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::s std::vector sameAccountDevs {}; std::vector defaultAccountDevs {}; auto uuids = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); + if (uuids.empty()) { + ZLOGI("no remote device to sync.appId:%{public}s", appId.c_str()); + return; + } GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); if (!sameAccountDevs.empty()) { - auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); - auto syncIdentifier = KvManager::GetKvStoreIdentifier(accountId, appId, storeId); - ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", - Anonymous::Change(storeId).c_str(), Anonymous::Change(accountId).c_str(), - DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); - delegate_->SetEqualIdentifier(syncIdentifier, sameAccountDevs); + auto accountId = account.empty() ? AccountDelegate::GetInstance()->GetUnencryptedAccountId() : account; + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, accountId); + auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId); + ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s", + Anonymous::Change(storeId).c_str(), Anonymous::Change(convertedIds.second).c_str(), + DistributedData::Serializable::Marshall(sameAccountDevs).c_str(), convertedIds.first.c_str()); + delegate_->SetEqualIdentifier(identifier, sameAccountDevs); } if (!defaultAccountDevs.empty()) { - auto syncIdentifier = KvManager::GetKvStoreIdentifier(defaultAccountId, appId, storeId); - ZLOGI("no account set compatible identifier store:%{public}s, device:%{public}.10s", + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, defaultAccountId); + auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId); + ZLOGI("no account store:%{public}s, device:%{public}.10s, appId:%{public}s", Anonymous::Change(storeId).c_str(), - DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); - delegate_->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); + DistributedData::Serializable::Marshall(defaultAccountDevs).c_str(), convertedIds.first.c_str()); + delegate_->SetEqualIdentifier(identifier, defaultAccountDevs); } } @@ -470,7 +512,7 @@ int32_t KVDBGeneralStore::Clean(const std::vector &devices, int32_t default: return GeneralError::E_ERROR; } - return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; + return ConvertStatus(status); } int32_t KVDBGeneralStore::Watch(int32_t origin, Watcher &watcher) @@ -525,31 +567,19 @@ int32_t KVDBGeneralStore::SetDistributedTables( return GeneralError::E_OK; } -int32_t KVDBGeneralStore::SetTrackerTable( - const std::string &tableName, const std::set &trackerColNames, const std::string &extendColName) +int32_t KVDBGeneralStore::SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, + const std::string &extendColName, bool isForceUpgrade) { return GeneralError::E_OK; } KVDBGeneralStore::GenErr KVDBGeneralStore::ConvertStatus(DistributedDB::DBStatus status) { - switch (status) { - case DBStatus::OK: - return GenErr::E_OK; - case DBStatus::CLOUD_NETWORK_ERROR: - return GenErr::E_NETWORK_ERROR; - case DBStatus::CLOUD_LOCK_ERROR: - return GenErr::E_LOCKED_BY_OTHERS; - case DBStatus::CLOUD_FULL_RECORDS: - return GenErr::E_RECODE_LIMIT_EXCEEDED; - case DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT: - return GenErr::E_NO_SPACE_FOR_ASSET; - case DBStatus::CLOUD_SYNC_TASK_MERGED: - return GenErr::E_SYNC_TASK_MERGED; - default: - ZLOGI("status:0x%{public}x", status); - break; + auto it = dbStatusMap_.find(status); + if (it != dbStatusMap_.end()) { + return it->second; } + ZLOGI("status:0x%{public}x", status); return GenErr::E_ERROR; } @@ -587,23 +617,6 @@ std::vector KVDBGeneralStore::GetWaterVersion(const std::string &de return res; } -void KVDBGeneralStore::InitWaterVersion(const StoreMetaData &meta) -{ - CheckerManager::StoreInfo info = { atoi(meta.user.c_str()), meta.tokenId, meta.bundleName, meta.storeId }; - bool isDynamic = CheckerManager::GetInstance().IsDynamic(info); - bool isStatic = CheckerManager::GetInstance().IsStatic(info); - if (!isDynamic && !isStatic) { - return; - } - delegate_->SetGenCloudVersionCallback([info](auto &originVersion) { - return WaterVersionManager::GetInstance().GetWaterVersion(info.bundleName, info.storeId); - }); - callback_ = [meta]() { - auto event = std::make_unique(CloudEvent::CLOUD_SYNC_FINISHED, meta); - EventCenter::GetInstance().PostEvent(std::move(event)); - }; -} - void KVDBGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string &originalId, DBChangeData &&data) { if (!HasWatcher()) { @@ -654,8 +667,8 @@ void KVDBGeneralStore::ObserverProxy::ConvertChangeData(const std::list KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async) { - return [async, callback = callback_](const std::map &processes) { - if (!async && !callback) { + return [async](const std::map &processes) { + if (!async) { return; } DistributedData::GenDetails details; @@ -674,18 +687,15 @@ KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async table.download.success = value.downLoadInfo.successCount; table.download.failed = value.downLoadInfo.failCount; table.download.untreated = table.download.total - table.download.success - table.download.failed; - detail.dataChange = detail.dataChange || - (process.process == FINISHED && - (value.downLoadInfo.insertCount > 0 || value.downLoadInfo.updateCount > 0 || - value.downLoadInfo.deleteCount > 0)); + detail.changeCount = (process.process == FINISHED) + ? value.downLoadInfo.insertCount + value.downLoadInfo.updateCount + + value.downLoadInfo.deleteCount + : 0; } } if (async) { async(details); } - if (!details.empty() && details.begin()->second.dataChange && callback) { - callback(); - } }; } @@ -777,4 +787,19 @@ void KVDBGeneralStore::SetConfig(const GeneralStore::StoreConfig &storeConfig) { enableCloud_ = storeConfig.enableCloud_; } + +std::pair KVDBGeneralStore::LockCloudDB() +{ + return { GeneralError::E_NOT_SUPPORT, 0 }; +} + +int32_t KVDBGeneralStore::UnLockCloudDB() +{ + return GeneralError::E_NOT_SUPPORT; +} + +void KVDBGeneralStore::SetExecutor(std::shared_ptr executor) +{ + return; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/kvdb_general_store.h b/services/distributeddataservice/service/kvdb/kvdb_general_store.h index b974f611cf1d43c90cf21c43203261971c9eb572..aa43834faeeb9cde8ec04ca4af08cee952ecc79b 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_general_store.h +++ b/services/distributeddataservice/service/kvdb/kvdb_general_store.h @@ -51,7 +51,7 @@ public: int32_t SetDistributedTables( const std::vector &tables, int32_t type, const std::vector &references) override; int32_t SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, - const std::string &extendColName) override; + const std::string &extendColName, bool isForceUpgrade = false) override; int32_t Insert(const std::string &table, VBuckets &&values) override; int32_t Update(const std::string &table, const std::string &setSql, Values &&values, const std::string &whereSql, Values &&conditions) override; @@ -60,7 +60,8 @@ public: std::pair> Query(const std::string &table, const std::string &sql, Values &&args) override; std::pair> Query(const std::string &table, GenQuery &query) override; - int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; + std::pair Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const SyncParam &syncParm) override; std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; @@ -72,13 +73,16 @@ public: int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; + int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) override; std::vector GetWaterVersion(const std::string &deviceId) override; - void SetEqualIdentifier(const std::string &appId, const std::string &storeId) override; + void SetEqualIdentifier(const std::string &appId, const std::string &storeId, std::string account = "") override; void SetConfig(const StoreConfig &storeConfig) override; - + void SetExecutor(std::shared_ptr executor) override; static DBPassword GetDBPassword(const StoreMetaData &data); static DBOption GetDBOption(const StoreMetaData &data, const DBPassword &password); static DBSecurity GetDBSecurity(int32_t secLevel); + std::pair LockCloudDB() override; + int32_t UnLockCloudDB() override; private: using KvDelegate = DistributedDB::KvStoreNbDelegate; @@ -92,8 +96,8 @@ private: std::vector GetNewKey(std::vector &key, const std::string &uuid); DBSyncCallback GetDBSyncCompleteCB(DetailAsync async); DBProcessCB GetDBProcessCB(DetailAsync async); - DBStatus CloudSync(const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, int64_t wait); - void InitWaterVersion(const StoreMetaData &meta); + DBStatus CloudSync(const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, int64_t wait, + const std::string &prepareTraceId); void GetIdentifierParams(std::vector &devices, const std::vector &uuids, int32_t authType); class ObserverProxy : public DistributedDB::KvStoreObserver { @@ -126,15 +130,15 @@ private: std::atomic isBound_ = false; std::mutex mutex_; int32_t ref_ = 1; - mutable std::shared_mutex rwMutex_; + mutable std::shared_timed_mutex rwMutex_; StoreInfo storeInfo_; - std::function callback_; static constexpr int32_t NO_ACCOUNT = 0; static constexpr int32_t IDENTICAL_ACCOUNT = 1; - static constexpr const char *defaultAccountId = "default"; + static constexpr const char *defaultAccountId = "ohosAnonymousUid"; bool enableCloud_ = false; bool isPublic_ = false; + static const std::map dbStatusMap_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_KVDB_GENERAL_STORE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 28d4b31baa803b786bdc72113102eaacf5e780f9..09525d466a3979bbe2f7e9e0ea8aaa0bcbff9885 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -49,6 +49,7 @@ #include "utils/constant.h" #include "utils/converter.h" #include "water_version_manager.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; @@ -58,7 +59,10 @@ using system_clock = std::chrono::system_clock; using DMAdapter = DistributedData::DeviceManagerAdapter; using DumpManager = OHOS::DistributedData::DumpManager; using CommContext = OHOS::DistributedData::CommunicatorContext; +using SecretKeyMeta = DistributedData::SecretKeyMetaData; static constexpr const char *DEFAULT_USER_ID = "0"; +static constexpr const char *PASTEBOARD_SERVICE = "pasteboard_service"; +static constexpr const char *PASTEBOARD_USER_ID = "100"; __attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_; KVDBServiceImpl::Factory::Factory() { @@ -99,23 +103,19 @@ void KVDBServiceImpl::Init() auto process = [this](const Event &event) { const auto &evt = static_cast(event); const auto &storeInfo = evt.GetStoreInfo(); - StoreMetaData meta; - meta.storeId = storeInfo.storeName; - meta.bundleName = storeInfo.bundleName; - meta.user = std::to_string(storeInfo.user); + StoreMetaData meta(storeInfo); meta.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s, user = %{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str(), meta.user.c_str()); if (meta.user == "0") { - ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s, user = %{public}s", - meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), meta.user.c_str()); return; } meta.user = "0"; StoreMetaDataLocal localMeta; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true) || !localMeta.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { - ZLOGE("meta empty, not public store. bundleName:%{public}s, storeId:%{public}s, user = %{public}s", - meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), meta.user.c_str()); + ZLOGE("meta empty, not public store."); return; } } @@ -132,6 +132,7 @@ void KVDBServiceImpl::Init() store->RegisterDetailProgressObserver(nullptr); }; EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); + EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process); } void KVDBServiceImpl::RegisterKvServiceInfo() @@ -196,9 +197,12 @@ Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId) }); MetaDataManager::GetInstance().DelMeta(metaData.GetKey()); MetaDataManager::GetInstance().DelMeta(metaData.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(metaData.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(metaData.GetStrategyKey()); - MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetDebugInfoKey(), true); PermitDelegate::GetInstance().DelCache(metaData.GetKey()); AutoCache::GetInstance().CloseStore(tokenId, storeId); ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), @@ -264,35 +268,6 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, SyncInf std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); } -Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) -{ - if (syncInfo.devices.empty()) { - return Status::INVALID_ARGUMENT; - } - StoreMetaData metaData = GetStoreMetaData(appId, storeId); - MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); - auto device = DMAdapter::GetInstance().ToUUID(syncInfo.devices[0]); - if (device.empty()) { - ZLOGE("invalid deviceId, appId:%{public}s storeId:%{public}s deviceId:%{public}s", - metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str(), - Anonymous::Change(syncInfo.devices[0]).c_str()); - return Status::INVALID_ARGUMENT; - } - if (DeviceMatrix::GetInstance().IsSupportMatrix() && - ((!DeviceMatrix::GetInstance().IsStatics(metaData) && !DeviceMatrix::GetInstance().IsDynamic(metaData)) || - !IsRemoteChange(metaData, device))) { - ZLOGD("no change, do not need sync, appId:%{public}s storeId:%{public}s", - metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str()); - DBResult dbResult = { {syncInfo.devices[0], DBStatus::OK} }; - DoComplete(metaData, syncInfo, RefCount(), std::move(dbResult)); - return SUCCESS; - } - syncInfo.syncId = ++syncId_; - return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), 0, - std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); -} - Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay) { StoreMetaData meta = GetStoreMetaData(appId, storeId); @@ -378,17 +353,6 @@ Status KVDBServiceImpl::RegServiceNotifier(const AppId &appId, sptr &password) +Status KVDBServiceImpl::GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password, + int32_t passwordType) { StoreMetaData metaData = GetStoreMetaData(appId, storeId); - return (BackupManager::GetInstance().GetPassWord(metaData, password)) ? SUCCESS : ERROR; + if (passwordType == KVDBService::PasswordType::BACKUP_SECRET_KEY) { + return BackupManager::GetInstance().GetPassWord(metaData, password) ? SUCCESS : ERROR; + } + if (passwordType == KVDBService::PasswordType::SECRET_KEY) { + SecretKeyMetaData secretKey; + MetaDataManager::GetInstance().LoadMeta(metaData.GetSecretKey(), secretKey, true); + return CryptoManager::GetInstance().Decrypt(secretKey.sKey, password) ? SUCCESS : ERROR; + } + ZLOGE("passwordType is invalid, appId:%{public}s, storeId:%{public}s, passwordType:%{public}d", + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), passwordType); + return ERROR; } Status KVDBServiceImpl::SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) @@ -683,16 +658,16 @@ Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, StoreMetaDataLocal oldLocal; MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), oldLocal, true); // when user is 0, old store no "isPublic" attr, as well as new store's "isPublic" is true, do not intercept. - if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || - old.area != meta.area || !options.persistent || + if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || old.area != meta.area || + !options.persistent || (meta.securityLevel != NO_LABEL && (old.securityLevel > meta.securityLevel)) || (Constant::NotEqual(oldLocal.isPublic, options.isPublic) && (old.user != DEFAULT_USER_ID || !options.isPublic))) { ZLOGE("meta appId:%{public}s storeId:%{public}s user:%{public}s type:%{public}d->%{public}d " - "encrypt:%{public}d->%{public}d " - "area:%{public}d->%{public}d persistent:%{public}d isPublic:%{public}d->%{public}d", - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType, - meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, oldLocal.isPublic, - options.isPublic); + "encrypt:%{public}d->%{public}d area:%{public}d->%{public}d persistent:%{public}d " + "securityLevel:%{public}d->%{public}d isPublic:%{public}d->%{public}d", + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType, + meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, + old.securityLevel, meta.securityLevel, oldLocal.isPublic, options.isPublic); return Status::STORE_META_CHANGED; } @@ -784,31 +759,59 @@ int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const return SUCCESS; } +bool KVDBServiceImpl::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta) +{ + std::vector accountIds { accountId, "ohosAnonymousUid", "default" }; + for (auto &id : accountIds) { + auto convertedIds = + AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user); + const std::string &tempTripleIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first, + storeMeta.storeId, false); + if (tempTripleIdentifier == identifier) { + ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s", + Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str()); + return true; + } + } + return false; +} + int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) { ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(identifier).c_str()); + std::vector metaData; - auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid, param.userId }); + auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid }); if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { - ZLOGE("no store in user:%{public}s", param.userId.c_str()); + ZLOGE("no meta data appId:%{public}s", param.appId.c_str()); return STORE_NOT_FOUND; } + auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); for (const auto &storeMeta : metaData) { if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN || - storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END) { + storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END || + (!param.userId.empty() && (param.userId != storeMeta.user)) || + storeMeta.appId == DistributedData::Bootstrap::GetInstance().GetProcessLabel()) { continue; } auto identifierTag = DBManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); - if (identifier != identifierTag) { + bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta); + if (identifier != identifierTag && !isTripleIdentifierEqual) { continue; } auto watchers = GetWatchers(storeMeta.tokenId, storeMeta.storeId); - AutoCache::GetInstance().GetStore(storeMeta, watchers); + auto store = AutoCache::GetInstance().GetStore(storeMeta, watchers); + if (isTripleIdentifierEqual && store != nullptr) { + store->SetEqualIdentifier(storeMeta.appId, storeMeta.storeId, accountId); + } - ZLOGD("user:%{public}s appId:%{public}s storeId:%{public}s", storeMeta.user.c_str(), - storeMeta.bundleName.c_str(), Anonymous::Change(storeMeta.storeId).c_str()); + ZLOGI("isTriple:%{public}d,storeId:%{public}s,appId:%{public}s,size:%{public}zu,user:%{public}s", + isTripleIdentifierEqual, Anonymous::Change(storeMeta.storeId).c_str(), storeMeta.appId.c_str(), + watchers.size(), storeMeta.user.c_str()); } return SUCCESS; } @@ -854,7 +857,14 @@ void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData)); metaData.appType = "harmony"; metaData.hapName = options.hapName; - metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData); + if (metaData.appId == PASTEBOARD_SERVICE) { + auto userId = metaData.user; + metaData.user = PASTEBOARD_USER_ID; + metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData); + metaData.user = userId; + } else { + metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData); + } metaData.schema = options.schema; metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); metaData.isNeedCompress = options.isNeedCompress; @@ -935,26 +945,6 @@ KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenBriefDetails(const GenDetail return dbResults; } -void KVDBServiceImpl::DoCloudSync(bool statics, bool dynamic) -{ - std::vector stores; - if (statics) { - auto staticStores = CheckerManager::GetInstance().GetStaticStores(); - stores.insert(stores.end(), staticStores.begin(), staticStores.end()); - } - if (dynamic) { - auto dynamicStores = CheckerManager::GetInstance().GetDynamicStores(); - stores.insert(stores.end(), dynamicStores.begin(), dynamicStores.end()); - } - for (const auto &store : stores) { - auto status = CloudSync({ store.bundleName }, { store.storeId }, { .triggerMode = MODE_BROADCASTER }); - if (status != SUCCESS) { - ZLOGW("cloud sync failed:%{public}d, appId:%{public}s storeId:%{public}s", status, - store.bundleName.c_str(), Anonymous::Change(store.storeId).c_str()); - } - } -} - Status KVDBServiceImpl::DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo) { if (!meta.enableCloud) { @@ -1024,7 +1014,7 @@ Status KVDBServiceImpl::DoSyncInOrder( if (uuids.empty()) { ZLOGW("no device seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); - return Status::ERROR; + return Status::DEVICE_NOT_ONLINE; } if (IsNeedMetaSync(meta, uuids)) { auto recv = DeviceMatrix::GetInstance().GetRecvLevel(uuids[0], @@ -1077,6 +1067,11 @@ bool KVDBServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vecto isAfterMeta = true; break; } + auto [existLocal, localMask] = DeviceMatrix::GetInstance().GetMask(uuid); + if ((localMask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } } return isAfterMeta; } @@ -1121,8 +1116,9 @@ Status KVDBServiceImpl::DoSyncBegin(const std::vector &devices, con SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, info.syncId, DATA_TYPE, meta.dataType); auto store = AutoCache::GetInstance().GetStore(meta, watcher); if (store == nullptr) { - ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", meta.bundleName.c_str(), - Anonymous::Change(meta.storeId).c_str(), meta.dataDir.c_str()); + ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s storeId length:%{public}zu dir:%{public}s", + meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), + meta.storeId.size(), meta.dataDir.c_str()); RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_FAILED, ERROR_CODE, Status::ERROR, BIZ_STATE, END, SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); @@ -1150,7 +1146,7 @@ Status KVDBServiceImpl::DoSyncBegin(const std::vector &devices, con complete(deviceStatus); }, syncParam); - auto status = Status(ret); + auto status = Status(ret.first); if (status != Status::SUCCESS) { RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, END, SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, @@ -1167,12 +1163,30 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in { ZLOGD("seqId:0x%{public}" PRIx64 " tokenId:0x%{public}x remote:%{public}zu", info.seqId, meta.tokenId, dbResult.size()); - RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_SUCCESS, BIZ_STATE, END, - SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, - std::to_string(info.syncId), DATA_TYPE, meta.dataType); std::map result; - for (auto &[key, status] : dbResult) { - result[key] = ConvertDbStatus(status); + if (AccessTokenKit::GetTokenTypeFlag(meta.tokenId) != TOKEN_HAP) { + for (auto &[key, status] : dbResult) { + result[key] = ConvertDbStatusNative(status); + } + } else { + for (auto &[key, status] : dbResult) { + result[key] = ConvertDbStatus(status); + } + } + bool success = true; + for (auto &[key, status] : result) { + if (status != SUCCESS) { + success = false; + RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, END, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); + break; + } + } + if (success) { + RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_SUCCESS, BIZ_STATE, END, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); } for (const auto &device : info.devices) { auto it = result.find(device); @@ -1195,6 +1209,18 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in return SUCCESS; } +Status KVDBServiceImpl::ConvertDbStatusNative(DBStatus status) +{ + auto innerStatus = static_cast(status); + if (innerStatus < 0) { + return static_cast(status); + } else if (status == DBStatus::COMM_FAILURE) { + return Status::DEVICE_NOT_ONLINE; + } else { + return ConvertDbStatus(status); + } +} + uint32_t KVDBServiceImpl::GetSyncDelayTime(uint32_t delay, const StoreId &storeId) { if (delay != 0) { @@ -1255,6 +1281,43 @@ Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) const return Status::ERROR; } +Status KVDBServiceImpl::ConvertGeneralErr(GeneralError error) const +{ + switch (error) { + case GeneralError::E_DB_ERROR: + return Status::DB_ERROR; + case GeneralError::E_OK: + return Status::SUCCESS; + case GeneralError::E_INVALID_ARGS: + return Status::INVALID_ARGUMENT; + case GeneralError::E_RECORD_NOT_FOUND: + return Status::KEY_NOT_FOUND; + case GeneralError::E_INVALID_VALUE_FIELDS: + return Status::INVALID_VALUE_FIELDS; + case GeneralError::E_INVALID_FIELD_TYPE: + return Status::INVALID_FIELD_TYPE; + case GeneralError::E_CONSTRAIN_VIOLATION: + return Status::CONSTRAIN_VIOLATION; + case GeneralError::E_INVALID_FORMAT: + return Status::INVALID_FORMAT; + case GeneralError::E_INVALID_QUERY_FORMAT: + return Status::INVALID_QUERY_FORMAT; + case GeneralError::E_INVALID_QUERY_FIELD: + return Status::INVALID_QUERY_FIELD; + case GeneralError::E_NOT_SUPPORT: + return Status::NOT_SUPPORT; + case GeneralError::E_TIME_OUT: + return Status::TIME_OUT; + case GeneralError::E_OVER_MAX_LIMITS: + return Status::OVER_MAX_LIMITS; + case GeneralError::E_SECURITY_LEVEL_ERROR: + return Status::SECURITY_LEVEL_ERROR; + default: + break; + } + return Status::ERROR; +} + KVDBServiceImpl::DBMode KVDBServiceImpl::ConvertDBMode(SyncMode syncMode) const { DBMode dbMode; @@ -1376,7 +1439,6 @@ int32_t KVDBServiceImpl::OnInitialize() RegisterKvServiceInfo(); RegisterHandler(); Init(); - RegisterMatrixChange(); return SUCCESS; } @@ -1395,4 +1457,25 @@ bool KVDBServiceImpl::IsOHOSType(const std::vector &ids) } return isOHOSType; } + +Status KVDBServiceImpl::RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) +{ + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); + auto watcher = GetWatchers(metaData.tokenId, metaData.storeId); + auto store = AutoCache::GetInstance().GetStore(metaData, watcher); + if (store == nullptr) { + ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", metaData.bundleName.c_str(), + Anonymous::Change(metaData.storeId).c_str(), metaData.dataDir.c_str()); + return Status::ERROR; + } + + int32_t ret; + if (device.empty()) { + ret = store->Clean({}, KVDBGeneralStore::NEARBY_DATA, ""); + } else { + ret = store->Clean({ DMAdapter::GetInstance().ToUUID(device) }, KVDBGeneralStore::NEARBY_DATA, ""); + } + return ConvertGeneralErr(GeneralError(ret)); +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index 2b32a69f3ea6f3af6ebad149e1612f5008504acd..9e79e0847f32278365e22429736ad817edd52481 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -39,6 +39,7 @@ public: using DBLaunchParam = DistributedDB::AutoLaunchParam; using Handler = std::function> &)>; using RefCount = DistributedData::RefCount; + using StoreMetaData = OHOS::DistributedData::StoreMetaData; API_EXPORT KVDBServiceImpl(); virtual ~KVDBServiceImpl(); Status GetStoreIds(const AppId &appId, std::vector &storeIds) override; @@ -49,7 +50,6 @@ public: Status Close(const AppId &appId, const StoreId &storeId) override; Status CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; - Status SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; Status RegServiceNotifier(const AppId &appId, sptr notifier) override; Status UnregServiceNotifier(const AppId &appId) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; @@ -62,7 +62,8 @@ public: Status RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; - Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; + Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password, + int32_t passwordType) override; Status NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay) override; Status PutSwitch(const AppId &appId, const SwitchData &data) override; Status GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data) override; @@ -74,9 +75,9 @@ public: int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + Status RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) override; private: - using StoreMetaData = OHOS::DistributedData::StoreMetaData; using StrategyMeta = OHOS::DistributedData::StrategyMeta; using StoreMetaDataLocal = OHOS::DistributedData::StoreMetaDataLocal; using ChangeType = OHOS::DistributedData::DeviceMatrix::ChangeType; @@ -87,6 +88,7 @@ private: using DBStatus = DistributedDB::DBStatus; using DBMode = DistributedDB::SyncMode; using Action = OHOS::DistributedData::MetaDataManager::Action; + using GeneralError = DistributedData::GeneralError; enum SyncAction { ACTION_SYNC, ACTION_SUBSCRIBE, @@ -127,6 +129,7 @@ private: Status DoComplete(const StoreMetaData &meta, const SyncInfo &info, RefCount refCount, const DBResult &dbResult); uint32_t GetSyncDelayTime(uint32_t delay, const StoreId &storeId); Status ConvertDbStatus(DBStatus status) const; + Status ConvertGeneralErr(GeneralError error) const; DBMode ConvertDBMode(SyncMode syncMode) const; ChangeType ConvertType(SyncMode syncMode) const; SwitchState ConvertAction(Action action) const; @@ -142,11 +145,13 @@ private: void SaveLocalMetaData(const Options &options, const StoreMetaData &metaData); void RegisterKvServiceInfo(); void RegisterHandler(); - void RegisterMatrixChange(); void DumpKvServiceInfo(int fd, std::map> ¶ms); void TryToSync(const StoreMetaData &metaData, bool force = false); bool IsRemoteChange(const StoreMetaData &metaData, const std::string &device); bool IsOHOSType(const std::vector &ids); + Status ConvertDbStatusNative(DBStatus status); + bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta); static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 973c50bc2a3e77551ada99a5ee4fd2b7d6c6b647..5921553c4cc754a26a285cdbd21dd51b8d064db2 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -41,7 +41,6 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSubscribe, &KVDBServiceStub::OnUnsubscribe, &KVDBServiceStub::OnGetBackupPassword, - &KVDBServiceStub::OnSyncExt, &KVDBServiceStub::OnCloudSync, &KVDBServiceStub::OnNotifyDataChange, &KVDBServiceStub::OnSetConfig, @@ -50,6 +49,7 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSubscribeSwitchData, &KVDBServiceStub::OnUnsubscribeSwitchData, &KVDBServiceStub::OnClose, + &KVDBServiceStub::OnRemoveDeviceData, }; int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) @@ -108,7 +108,7 @@ std::pair KVDBServiceStub::GetStoreInfo(uin bool KVDBServiceStub::CheckPermission(uint32_t code, const StoreInfo &storeInfo) { if (code >= static_cast(KVDBServiceInterfaceCode::TRANS_PUT_SWITCH) && - code < static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)) { + code <= static_cast(KVDBServiceInterfaceCode::TRANS_UNSUBSCRIBE_SWITCH_DATA)) { return CheckerManager::GetInstance().IsSwitches(storeInfo); } return CheckerManager::GetInstance().IsValid(storeInfo); @@ -221,25 +221,6 @@ int32_t KVDBServiceStub::OnCloudSync( return ERR_NONE; } -int32_t KVDBServiceStub::OnSyncExt( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) -{ - SyncInfo syncInfo; - if (!ITypesUtil::Unmarshal( - data, syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); - return IPC_STUB_INVALID_DATA_ERR; - } - int32_t status = SyncExt(appId, storeId, syncInfo); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return ERR_NONE; -} - int32_t KVDBServiceStub::OnNotifyDataChange( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { @@ -440,8 +421,14 @@ int32_t KVDBServiceStub::OnUnsubscribe( int32_t KVDBServiceStub::OnGetBackupPassword( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { + int32_t passwordType; + if (!ITypesUtil::Unmarshal(data, passwordType)) { + ZLOGE("Unmarshal type failed, appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } std::vector password; - int32_t status = GetBackupPassword(appId, storeId, password); + int32_t status = GetBackupPassword(appId, storeId, password, passwordType); if (!ITypesUtil::Marshal(reply, status, password)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); @@ -525,4 +512,21 @@ int32_t KVDBServiceStub::OnSetConfig(const AppId &appId, const StoreId &storeId, } return ERR_NONE; } + +int32_t KVDBServiceStub::OnRemoveDeviceData(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply) +{ + std::string device; + if (!ITypesUtil::Unmarshal(data, device)) { + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t status = RemoveDeviceData(appId, storeId, device); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x appId:%{public}s", status, appId.appId.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return ERR_NONE; +} } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index 71abe63480c24cc018b44169edaf9e7ab3af03d5..a5deeaf1b28c7fe0cc648f0d9def3bfae2a5356b 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -50,7 +50,6 @@ private: int32_t OnSubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnUnsubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetBackupPassword(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnSyncExt(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnNotifyDataChange(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnPutSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); @@ -59,6 +58,7 @@ private: int32_t OnUnsubscribeSwitchData(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnSetConfig(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); + int32_t OnRemoveDeviceData(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); static const Handler HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)]; bool CheckPermission(uint32_t code, const StoreInfo &storeInfo); diff --git a/services/distributeddataservice/service/matrix/include/device_matrix.h b/services/distributeddataservice/service/matrix/include/device_matrix.h index 6f04a79fac05942eb002b7505bbb154d990fbd2f..6fb6068597c4a169c5c9d19783510dd2ffe8c4d9 100644 --- a/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -16,6 +16,7 @@ #define OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H #include #include + #include "eventcenter/event.h" #include "executor_pool.h" #include "lru_bucket.h" @@ -24,6 +25,7 @@ #include "metadata/store_meta_data.h" #include "utils/ref_count.h" #include "visibility.h" + namespace OHOS::DistributedData { class API_EXPORT DeviceMatrix { public: @@ -74,7 +76,6 @@ public: const StoreMetaData &metaData, ChangeType type = ChangeType::CHANGE_ALL); void UpdateLevel(const std::string &device, uint16_t level, LevelType type, bool isConsistent = false); void Clear(); - void RegRemoteChange(std::function observer); void SetExecutor(std::shared_ptr executors); uint16_t GetCode(const StoreMetaData &metaData); std::pair GetMask(const std::string &device, LevelType type = LevelType::DYNAMIC); @@ -141,7 +142,6 @@ private: uint16_t ConvertStatics(const MatrixMetaData &meta, uint16_t mask); MatrixMetaData GetMatrixInfo(const std::string &device); MatrixMetaData GetMatrixMetaData(const std::string &device, const Mask &mask); - std::pair NeedCloudSync(const std::string &device, const MatrixMetaData &newMeta); static inline uint16_t ConvertIndex(uint16_t code); MatrixEvent::MatrixData lasts_; diff --git a/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp b/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp index c9986722a6b7693cc408494942ab965b2d4fcf26..4b6b38b5403c5dc4202b05731e4bd5de8cc9ca7a 100644 --- a/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp +++ b/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp @@ -16,10 +16,11 @@ #define LOG_TAG "AutoSyncMatrix" #include "auto_sync_matrix.h" + #include "bootstrap.h" #include "checker/checker_manager.h" -#include "device_matrix.h" #include "device_manager_adapter.h" +#include "device_matrix.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" @@ -64,7 +65,7 @@ AutoSyncMatrix::AutoSyncMatrix() break; } return true; - }); + }); } AutoSyncMatrix::~AutoSyncMatrix() diff --git a/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/services/distributeddataservice/service/matrix/src/device_matrix.cpp index 4f0cef300c01b28b23684a4828b78c93c5818d43..337ae78613bf6c00286eeb44d462eaef2e53da4e 100644 --- a/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -48,7 +48,7 @@ DeviceMatrix::DeviceMatrix() return true; } auto deviceId = std::move(metaData.deviceId); - ZLOGI("Matrix ver:%{public}u origin:%{public}d device:%{public}s", + ZLOGI("matrix version:%{public}u origin:%{public}d device:%{public}s", metaData.version, metaData.origin, Anonymous::Change(deviceId).c_str()); if (metaData.origin == MatrixMetaData::Origin::REMOTE_CONSISTENT) { return true; @@ -69,7 +69,7 @@ DeviceMatrix::DeviceMatrix() } auto deviceId = std::move(metaData.deviceId); versions_.Set(deviceId, metaData); - ZLOGI("Matrix ver:%{public}u device:%{public}s", + ZLOGI("matrix version:%{public}u device:%{public}s", metaData.version, Anonymous::Change(deviceId).c_str()); return true; }); @@ -118,7 +118,7 @@ bool DeviceMatrix::Initialize(uint32_t token, std::string storeId) newMeta.dynamic = Merge(oldMeta.dynamic, newMeta.dynamic); newMeta.statics = Merge(oldMeta.statics, newMeta.statics); } - ZLOGI("Save Matrix ver:%{public}u -> %{public}u ", oldMeta.version, newMeta.version); + ZLOGI("Save Matrix, oldMeta.version:%{public}u , newMeta.version:%{public}u ", oldMeta.version, newMeta.version); MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta, true); return MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta); } @@ -206,7 +206,6 @@ std::pair DeviceMatrix::OnBroadcast(const std::string &devic mask.statics &= ~dataLevel.statics; } auto meta = GetMatrixMetaData(device, mask); - auto [statics, dynamic] = NeedCloudSync(device, meta); UpdateRemoteMeta(device, mask, meta); { std::lock_guard lockGuard(mutex_); @@ -217,9 +216,6 @@ std::pair DeviceMatrix::OnBroadcast(const std::string &devic } remotes_.insert_or_assign(device, mask); } - if (observer_ && (statics || dynamic)) { - observer_(statics, dynamic); - } return { mask.dynamic, mask.statics }; } @@ -302,25 +298,6 @@ MatrixMetaData DeviceMatrix::GetMatrixMetaData(const std::string &device, const return meta; } -std::pair DeviceMatrix::NeedCloudSync(const std::string &device, const MatrixMetaData &newMeta) -{ - auto [exist, oldMeta] = GetMatrixMeta(device); - if (exist && oldMeta == newMeta) { - return { false, false }; - } - if (exist) { - auto broadStaticVersion = High(newMeta.statics) > High(oldMeta.statics); - auto broadDynamicVersion = High(newMeta.dynamic) > High(oldMeta.dynamic); - auto [isExisted, metaData] = GetMatrixMeta(device, true); - if (!isExisted) { - return { broadStaticVersion, broadDynamicVersion }; - } - return { broadStaticVersion && High(newMeta.statics) > High(metaData.statics), - broadDynamicVersion && High(newMeta.dynamic) > High(metaData.dynamic) }; - } - return { true, true }; -} - void DeviceMatrix::UpdateRemoteMeta(const std::string &device, Mask &mask, MatrixMetaData &newMeta) { auto [exist, oldMeta] = GetMatrixMeta(device); @@ -390,15 +367,15 @@ void DeviceMatrix::Broadcast(const DataLevel &dataLevel) } matrix.dynamic |= Low(lasts_.dynamic); matrix.statics |= Low(lasts_.statics); - if (High(matrix.dynamic) != INVALID_HIGH && High(lasts_.dynamic)!= INVALID_HIGH && + if (High(matrix.dynamic) != INVALID_HIGH && High(lasts_.dynamic) != INVALID_HIGH && High(matrix.dynamic) < High(lasts_.dynamic)) { - matrix.dynamic &= 0x000F; - matrix.dynamic |= High(matrix.dynamic); + matrix.dynamic &= 0x000F; + matrix.dynamic |= High(matrix.dynamic); } - if (High(matrix.statics) != INVALID_HIGH && High(lasts_.statics)!= INVALID_HIGH && + if (High(matrix.statics) != INVALID_HIGH && High(lasts_.statics) != INVALID_HIGH && High(matrix.statics) < High(lasts_.statics)) { - matrix.statics &= 0x000F; - matrix.statics |= High(matrix.statics); + matrix.statics &= 0x000F; + matrix.statics |= High(matrix.statics); } EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_BROADCAST, "", matrix)); lasts_ = matrix; @@ -484,7 +461,7 @@ void DeviceMatrix::OnChanged(const StoreMetaData &metaData) void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, LevelType type, ChangeType changeType) { if (device.empty() || type < LevelType::STATICS || type > LevelType::DYNAMIC) { - ZLOGE("Invalid args.device:%{public}s, code:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + ZLOGE("invalid args, device:%{public}s, code:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), code, type); return; } @@ -698,7 +675,7 @@ void DeviceMatrix::UpdateLevel(const std::string &device, uint16_t level, Device bool isConsistent) { if (device.empty() || type < 0 || type >= LevelType::BUTT) { - ZLOGE("Invalid args.device:%{public}s, level:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + ZLOGE("invalid args, device:%{public}s, level:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), level, type); return; } @@ -736,15 +713,6 @@ MatrixMetaData DeviceMatrix::GetMatrixInfo(const std::string &device) return meta; } -void DeviceMatrix::RegRemoteChange(std::function observer) -{ - if (observer_) { - ZLOGD("duplicate register"); - return; - } - observer_ = std::move(observer); -} - bool DeviceMatrix::IsDynamic(const StoreMetaData &metaData) { if (metaData.dataType != LevelType::DYNAMIC) { diff --git a/services/distributeddataservice/service/object/object_asset_loader.cpp b/services/distributeddataservice/service/object/object_asset_loader.cpp index e349eab18a158f655b3ffc87403c821717bdea5e..c3d582e6aef6ae46beef39d1bc06ae2c34d3794c 100644 --- a/services/distributeddataservice/service/object/object_asset_loader.cpp +++ b/services/distributeddataservice/service/object/object_asset_loader.cpp @@ -67,7 +67,6 @@ bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string& bundle void ObjectAssetLoader::TransferAssetsAsync(const int32_t userId, const std::string& bundleName, const std::string& deviceId, const std::vector& assets, const TransferFunc& callback) { - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::IDLE); if (executors_ == nullptr) { ZLOGE("executors is null, bundleName: %{public}s, deviceId: %{public}s, userId: %{public}d", bundleName.c_str(), DistributedData::Anonymous::Change(deviceId).c_str(), userId); @@ -124,9 +123,6 @@ void ObjectAssetLoader::FinishTask(const std::string& uri, bool result) if (task.downloadAssets.size() == 0 && task.callback != nullptr) { task.callback(result); finishedTasks.emplace_back(seq); - if (result) { - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::RADAR_SUCCESS); - } } return false; }); @@ -171,7 +167,8 @@ bool ObjectAssetLoader::IsDownloaded(const DistributedData::Asset& asset) int32_t ObjectAssetLoader::PushAsset(int32_t userId, const sptr &assetObj, const sptr &sendCallback) { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::IDLE); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::IDLE); ZLOGI("PushAsset start, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); auto status = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PushAsset(userId, assetObj, @@ -179,8 +176,8 @@ int32_t ObjectAssetLoader::PushAsset(int32_t userId, const sptr &asset if (status != OBJECT_SUCCESS) { ZLOGE("PushAsset err status: %{public}d, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", status, assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, status, ObjectStore::FINISHED); } return status; } @@ -189,14 +186,17 @@ int32_t ObjectAssetsSendListener::OnSendResult(const sptr &assetObj, i { if (assetObj == nullptr) { ZLOGE("OnSendResult error! status:%{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); return result; } ZLOGI("OnSendResult, status:%{public}d, asset size:%{public}zu", result, assetObj->uris_.size()); if (result == OBJECT_SUCCESS) { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_SUCCESS); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_SUCCESS); } else { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); } return result; } diff --git a/services/distributeddataservice/service/object/object_data_listener.cpp b/services/distributeddataservice/service/object/object_data_listener.cpp index 83c62ab47b38e876f463e3a5f23de5f5a5bfb3c0..1c58fb4934c315ffb37f25faddceaf7815418497 100644 --- a/services/distributeddataservice/service/object/object_data_listener.cpp +++ b/services/distributeddataservice/service/object/object_data_listener.cpp @@ -32,8 +32,6 @@ ObjectDataListener::~ObjectDataListener() void ObjectDataListener::OnChange(const DistributedDB::KvStoreChangedData &data) { - RADAR_REPORT(ObjectStore::DATA_RESTORE, ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS, - ObjectStore::BIZ_STATE, ObjectStore::START); const auto &insertedDatas = data.GetEntriesInserted(); const auto &updatedDatas = data.GetEntriesUpdated(); std::map> changedData {}; @@ -51,7 +49,6 @@ void ObjectDataListener::OnChange(const DistributedDB::KvStoreChangedData &data) int32_t ObjectAssetsRecvListener::OnStart(const std::string &srcNetworkId, const std::string &dstNetworkId, const std::string &sessionId, const std::string &dstBundleName) { - RADAR_REPORT(ObjectStore::DATA_RESTORE, ObjectStore::ASSETS_RECV, ObjectStore::IDLE); auto objectKey = dstBundleName + sessionId; ZLOGI("OnStart, objectKey:%{public}s", objectKey.c_str()); ObjectStoreManager::GetInstance()->NotifyAssetsStart(objectKey, srcNetworkId); @@ -64,15 +61,14 @@ int32_t ObjectAssetsRecvListener::OnFinished(const std::string &srcNetworkId, co if (assetObj == nullptr) { ZLOGE("OnFinished error! status:%{public}d, srcNetworkId:%{public}s", result, DistributedData::Anonymous::Change(srcNetworkId).c_str()); - RADAR_REPORT(ObjectStore::DATA_RESTORE, ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, result); + ObjectStore::RadarReporter::ReportStageError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, result); return result; } - RADAR_REPORT(ObjectStore::DATA_RESTORE, ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS); auto objectKey = assetObj->dstBundleName_+assetObj->sessionId_; ZLOGI("OnFinished, status:%{public}d objectKey:%{public}s, asset size:%{public}zu", result, objectKey.c_str(), assetObj->uris_.size()); - ObjectStoreManager::GetInstance()->NotifyAssetsReady(objectKey, srcNetworkId); + ObjectStoreManager::GetInstance()->NotifyAssetsReady(objectKey, assetObj->dstBundleName_, srcNetworkId); return OBJECT_SUCCESS; } } // namespace DistributedObject diff --git a/services/distributeddataservice/service/object/object_dms_handler.cpp b/services/distributeddataservice/service/object/object_dms_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ec88aca2eaa6542b5697a2f68c3d72fc803fe15 --- /dev/null +++ b/services/distributeddataservice/service/object/object_dms_handler.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectDmsHandler" + +#include "object_dms_handler.h" + +#include "device_manager_adapter.h" +#include "dms_handler.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DistributedObject { +constexpr const char *PKG_NAME = "ohos.distributeddata.service"; +void DmsEventListener::DSchedEventNotify(DistributedSchedule::EventNotify ¬ify) +{ + ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify); +} + +void ObjectDmsHandler::ReceiveDmsEvent(DistributedSchedule::EventNotify &event) +{ + std::lock_guard lock(mutex_); + auto now = std::chrono::steady_clock::now(); + dmsEvents_.push_back(std::make_pair(event, now)); + if (dmsEvents_.size() > MAX_EVENTS) { + dmsEvents_.pop_front(); + } + ZLOGI("Received dms event, eventType: %{public}d, srcNetworkId: %{public}s, srcBundleName: %{public}s, " + "dstNetworkId: %{public}s, destBundleName: %{public}s", event.dSchedEventType_, + DistributedData::Anonymous::Change(event.srcNetworkId_).c_str(), event.srcBundleName_.c_str(), + DistributedData::Anonymous::Change(event.dstNetworkId_).c_str(), event.destBundleName_.c_str()); +} + +bool ObjectDmsHandler::IsContinue(const std::string &bundleName) +{ + std::lock_guard lock(mutex_); + auto validityTime = std::chrono::steady_clock::now() - std::chrono::seconds(VALIDITY); + DistributedHardware::DmDeviceInfo localDeviceInfo; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo); + for (auto it = dmsEvents_.rbegin(); it != dmsEvents_.rend(); ++it) { + if (it->second < validityTime) { + continue; + } + if (it->first.dSchedEventType_ != DistributedSchedule::DMS_CONTINUE) { + continue; + } + if (it->first.srcNetworkId_ == localDeviceInfo.networkId && it->first.srcBundleName_ == bundleName) { + ZLOGI("Continue source, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str()); + return true; + } + if (it->first.dstNetworkId_ == localDeviceInfo.networkId && it->first.destBundleName_ == bundleName) { + ZLOGI("Continue destination, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str()); + return true; + } + } + ZLOGW("Not in continue, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str()); + return false; +} + +std::string ObjectDmsHandler::GetDstBundleName(const std::string &srcBundleName, const std::string &dstNetworkId) +{ + std::lock_guard lock(mutex_); + auto validityTime = std::chrono::steady_clock::now() - std::chrono::seconds(VALIDITY); + DistributedHardware::DmDeviceInfo localDeviceInfo; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo); + for (auto it = dmsEvents_.rbegin(); it != dmsEvents_.rend(); ++it) { + if (it->second < validityTime) { + continue; + } + if (it->first.dSchedEventType_ != DistributedSchedule::DMS_CONTINUE) { + continue; + } + if (it->first.srcNetworkId_ == localDeviceInfo.networkId && it->first.srcBundleName_ == srcBundleName && + it->first.dstNetworkId_ == dstNetworkId) { + ZLOGI("In continue, srcBundleName: %{public}s, dstBundleName: %{public}s", + srcBundleName.c_str(), it->first.destBundleName_.c_str()); + return it->first.destBundleName_; + } + } + ZLOGW("Not in continue, srcBundleName: %{public}s, srcNetworkId: %{public}s", + srcBundleName.c_str(), DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str()); + return srcBundleName; +} + +void ObjectDmsHandler::RegisterDmsEvent() +{ + ZLOGI("Start register dms event"); + if (dmsEventListener_ == nullptr) { + dmsEventListener_ = sptr(new DmsEventListener); + } + if (dmsEventListener_ == nullptr) { + ZLOGE("Register dms event listener failed, listener is nullptr"); + return; + } + auto status = DistributedSchedule::DmsHandler::GetInstance().RegisterDSchedEventListener( + DistributedSchedule::DSchedEventType::DMS_ALL, dmsEventListener_); + if (status != 0) { + ZLOGE("Register dms event listener failed, status: %{public}d", status); + } +} +} \ No newline at end of file diff --git a/services/distributeddataservice/service/object/object_dms_handler.h b/services/distributeddataservice/service/object/object_dms_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..ee4208a2798901d63f84f781595f62cbee99a74b --- /dev/null +++ b/services/distributeddataservice/service/object/object_dms_handler.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H +#define DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H + +#include + +#include "dms_listener_stub.h" +#include "distributed_sched_types.h" + +namespace OHOS::DistributedObject { +class DmsEventListener : public DistributedSchedule::DSchedEventListenerStub { +public: + DmsEventListener() = default; + ~DmsEventListener() = default; + void DSchedEventNotify(DistributedSchedule::EventNotify ¬ify); +}; + +class ObjectDmsHandler { +public: + static ObjectDmsHandler &GetInstance() + { + static ObjectDmsHandler instance; + return instance; + } + + void ReceiveDmsEvent(DistributedSchedule::EventNotify &event); + bool IsContinue(const std::string &bundleName); + std::string GetDstBundleName(const std::string &srcBundleName, const std::string &dstNetworkId); + void RegisterDmsEvent(); + +private: + ObjectDmsHandler() = default; + ~ObjectDmsHandler() = default; + ObjectDmsHandler(const ObjectDmsHandler &) = delete; + ObjectDmsHandler &operator=(const ObjectDmsHandler &) = delete; + ObjectDmsHandler(ObjectDmsHandler &&) = delete; + ObjectDmsHandler &operator=(ObjectDmsHandler &&) = delete; + + static constexpr int64_t VALIDITY = 15; + static constexpr uint32_t MAX_EVENTS = 20; + std::deque> dmsEvents_{}; + std::mutex mutex_{}; + sptr dmsEventListener_; +}; +} // namespace OHOS::DistributedObject +#endif // DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H diff --git a/services/distributeddataservice/service/object/object_manager.cpp b/services/distributeddataservice/service/object/object_manager.cpp index 58e34682076c0d6f88b1bb0fe924c7e2b69b7a48..ee359c952f97de9cff5dc7ba00a8a9ca8d79539a 100644 --- a/services/distributeddataservice/service/object/object_manager.cpp +++ b/services/distributeddataservice/service/object/object_manager.cpp @@ -17,24 +17,22 @@ #include "object_manager.h" #include -#include -#include #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "block_data.h" #include "bootstrap.h" -#include "checker/checker_manager.h" #include "common/bytes.h" #include "common/string_utils.h" #include "datetime_ex.h" #include "distributed_file_daemon_manager.h" -#include "ipc_skeleton.h" #include "kvstore_utils.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" +#include "object_dms_handler.h" #include "object_radar_reporter.h" +#include "utils/anonymous.h" namespace OHOS { namespace DistributedObject { @@ -42,7 +40,6 @@ using namespace OHOS::DistributedKv; using namespace Security::AccessToken; using StoreMetaData = OHOS::DistributedData::StoreMetaData; using AccountDelegate = DistributedKv::AccountDelegate; -using OHOS::DistributedKv::AccountDelegate; using Account = OHOS::DistributedKv::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; using ValueProxy = OHOS::DistributedData::ValueProxy; @@ -57,17 +54,11 @@ ObjectStoreManager::ObjectStoreManager() ObjectStoreManager::~ObjectStoreManager() { ZLOGI("ObjectStoreManager destroy"); - if (objectAssetsSendListener_ != nullptr) { - delete objectAssetsSendListener_; - objectAssetsSendListener_ = nullptr; - } if (objectAssetsRecvListener_ != nullptr) { auto status = DistributedFileDaemonManager::GetInstance().UnRegisterAssetCallback(objectAssetsRecvListener_); if (status != DistributedDB::DBStatus::OK) { ZLOGE("UnRegister assetsRecvListener err %{public}d", status); } - delete objectAssetsRecvListener_; - objectAssetsRecvListener_ = nullptr; } } @@ -138,61 +129,63 @@ void ObjectStoreManager::ProcessSyncCallback(const std::map> &data, const std::string &deviceId, - sptr callback) + const ObjectRecord &data, const std::string &deviceId, sptr callback) { auto proxy = iface_cast(callback); if (deviceId.size() == 0) { - ZLOGE("deviceId empty"); + ZLOGE("DeviceId empty, appId: %{public}s, sessionId: %{public}s", appId.c_str(), sessionId.c_str()); proxy->Completed(std::map()); return INVALID_ARGUMENT; } int32_t result = Open(); if (result != OBJECT_SUCCESS) { - ZLOGE("Open failed, errCode = %{public}d", result); + ZLOGE("Open object kvstore failed, result: %{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, ObjectStore::GETKV_FAILED, ObjectStore::FINISHED); proxy->Completed(std::map()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, ObjectStore::GETKV_FAILED, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); return STORE_NOT_OPEN; } - - ZLOGD("start SaveToStore"); SaveUserToMeta(); - result = SaveToStore(appId, sessionId, deviceId, data); + std::string dstBundleName = ObjectDmsHandler::GetInstance().GetDstBundleName(appId, deviceId); + result = SaveToStore(dstBundleName, sessionId, deviceId, data); if (result != OBJECT_SUCCESS) { - ZLOGE("Save failed, errCode = %{public}d", result); + ZLOGE("Save to store failed, result: %{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); Close(); proxy->Completed(std::map()); return result; } - SyncCallBack tmp = [proxy, appId, sessionId, deviceId, this](const std::map &results) { - proxy->Completed(results); - ProcessSyncCallback(results, appId, sessionId, deviceId); - }; - ZLOGD("start SyncOnStore"); - std::vector deviceList = {deviceId}; - result = SyncOnStore(GetPropertyPrefix(appId, sessionId, deviceId), deviceList, tmp); + ZLOGI("Sync data, bundleName: %{public}s, sessionId: %{public}s, deviceId: %{public}s", dstBundleName.c_str(), + sessionId.c_str(), Anonymous::Change(deviceId).c_str()); + SyncCallBack syncCallback = + [proxy, dstBundleName, sessionId, deviceId, this](const std::map &results) { + ProcessSyncCallback(results, dstBundleName, sessionId, deviceId); + proxy->Completed(results); + }; + result = SyncOnStore(GetPropertyPrefix(dstBundleName, sessionId, deviceId), {deviceId}, syncCallback); if (result != OBJECT_SUCCESS) { - ZLOGE("sync failed, errCode = %{public}d", result); + ZLOGE("Sync data failed, result: %{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); + Close(); proxy->Completed(std::map()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, result, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); + return result; } - result = PushAssets(std::stoi(GetCurrentUser()), appId, sessionId, data, deviceId); Close(); - return result; + return PushAssets(appId, dstBundleName, sessionId, data, deviceId); } -int32_t ObjectStoreManager::PushAssets(int32_t userId, const std::string &appId, const std::string &sessionId, - const std::map> &data, const std::string &deviceId) +int32_t ObjectStoreManager::PushAssets(const std::string &srcBundleName, const std::string &dstBundleName, + const std::string &sessionId, const ObjectRecord &data, const std::string &deviceId) { Assets assets = GetAssetsFromDBRecords(data); if (assets.empty() || data.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY) == data.end()) { return OBJECT_SUCCESS; } sptr assetObj = new AssetObj(); - assetObj->dstBundleName_ = appId; - assetObj->srcBundleName_ = appId; + assetObj->dstBundleName_ = dstBundleName; + assetObj->srcBundleName_ = srcBundleName; assetObj->dstNetworkId_ = deviceId; assetObj->sessionId_ = sessionId; for (const auto& asset : assets) { @@ -201,6 +194,7 @@ int32_t ObjectStoreManager::PushAssets(int32_t userId, const std::string &appId, if (objectAssetsSendListener_ == nullptr) { objectAssetsSendListener_ = new ObjectAssetsSendListener(); } + int userId = std::atoi(GetCurrentUser().c_str()); auto status = ObjectAssetLoader::GetInstance()->PushAsset(userId, assetObj, objectAssetsSendListener_); return status; } @@ -248,19 +242,18 @@ int32_t ObjectStoreManager::Retrieve( const std::string &bundleName, const std::string &sessionId, sptr callback, uint32_t tokenId) { auto proxy = iface_cast(callback); - ZLOGI("enter"); int32_t result = Open(); if (result != OBJECT_SUCCESS) { - ZLOGE("Open failed, errCode = %{public}d", result); - proxy->Completed(std::map>(), false); + ZLOGE("Open object kvstore failed, result: %{public}d", result); + proxy->Completed(ObjectRecord(), false); return ObjectStore::GETKV_FAILED; } - std::map> results{}; + ObjectRecord results{}; int32_t status = RetrieveFromStore(bundleName, sessionId, results); if (status != OBJECT_SUCCESS) { - ZLOGI("Retrieve failed, status = %{public}d", status); - Close(); - proxy->Completed(std::map>(), false); + ZLOGI("Retrieve from store failed, status: %{public}d, close after one minute.", status); + CloseAfterMinute(); + proxy->Completed(ObjectRecord(), false); return status; } bool allReady = false; @@ -269,26 +262,30 @@ int32_t ObjectStoreManager::Retrieve( allReady = true; } else { auto objectKey = bundleName + sessionId; - restoreStatus_.ComputeIfAbsent( - objectKey, [](const std::string& key) -> auto { - return RestoreStatus::NONE; + restoreStatus_.ComputeIfPresent(objectKey, [&allReady](const auto &key, auto &value) { + if (value == RestoreStatus::ALL_READY) { + allReady = true; + return false; + } + if (value == RestoreStatus::DATA_READY) { + value = RestoreStatus::DATA_NOTIFIED; + } + return true; }); - if (restoreStatus_.Find(objectKey).second == RestoreStatus::ALL_READY) { - allReady = true; - } } - // delete local data status = RevokeSaveToStore(GetPrefixWithoutDeviceId(bundleName, sessionId)); if (status != OBJECT_SUCCESS) { - ZLOGE("revoke save failed, status = %{public}d", status); + ZLOGE("Revoke save failed, status: %{public}d", status); Close(); - proxy->Completed(std::map>(), false); + proxy->Completed(ObjectRecord(), false); return status; } Close(); proxy->Completed(results, allReady); - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, - ObjectStore::FINISHED); + if (allReady) { + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } return status; } @@ -328,26 +325,26 @@ int32_t ObjectStoreManager::Clear() return result; } -int32_t ObjectStoreManager::DeleteByAppId(const std::string &appId) +int32_t ObjectStoreManager::DeleteByAppId(const std::string &appId, int32_t user) { - ZLOGI("enter, %{public}s", appId.c_str()); int32_t result = Open(); if (result != OBJECT_SUCCESS) { - ZLOGE("Open failed, errCode = %{public}d", result); + ZLOGE("Open store failed, result: %{public}d, appId: %{public}s, user: %{public}d", result, + appId.c_str(), user); return STORE_NOT_OPEN; } result = RevokeSaveToStore(appId); if (result != OBJECT_SUCCESS) { - ZLOGE("RevokeSaveToStore failed"); + ZLOGE("Revoke save failed, result: %{public}d, appId: %{public}s, user: %{public}d", result, + appId.c_str(), user); } Close(); - - std::string userId = GetCurrentUser(); - if (userId.empty()) { - return OBJECT_INNER_ERROR; - } + std::string userId = std::to_string(user); std::string metaKey = GetMetaUserIdKey(userId, appId); - DistributedData::MetaDataManager::GetInstance().DelMeta(metaKey, true); + auto status = DistributedData::MetaDataManager::GetInstance().DelMeta(metaKey, true); + if (!status) { + ZLOGE("Delete meta failed, userId: %{public}s, appId: %{public}s", userId.c_str(), appId.c_str()); + } return result; } @@ -397,10 +394,9 @@ void ObjectStoreManager::UnregisterRemoteCallback(const std::string &bundleName, })); } -void ObjectStoreManager::NotifyChange(std::map> &changedData) +void ObjectStoreManager::NotifyChange(ObjectRecord &changedData) { ZLOGI("OnChange start, size:%{public}zu", changedData.size()); - std::map>> data; bool hasAsset = false; SaveInfo saveInfo; for (const auto &[key, value] : changedData) { @@ -409,6 +405,24 @@ void ObjectStoreManager::NotifyChange(std::map break; } } + auto data = GetObjectData(changedData, saveInfo, hasAsset); + if (!hasAsset) { + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, saveInfo.bundleName); + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data, true); // no asset, data ready means all ready + return false; + }); + return; + } + NotifyDataChanged(data, saveInfo); + SaveUserToMeta(); +} + +std::map ObjectStoreManager::GetObjectData(const ObjectRecord& changedData, + SaveInfo& saveInfo, bool& hasAsset) +{ + std::map data; std::string keyPrefix = saveInfo.ToPropertyPrefix(); if (!keyPrefix.empty()) { std::string observerKey = saveInfo.bundleName + saveInfo.sessionId; @@ -425,9 +439,15 @@ void ObjectStoreManager::NotifyChange(std::map } else { for (const auto &item : changedData) { std::vector splitKeys = SplitEntryKey(item.first); - if (splitKeys.empty()) { + if (splitKeys.size() <= PROPERTY_NAME_INDEX) { continue; } + if (saveInfo.sourceDeviceId.empty() || saveInfo.bundleName.empty()) { + saveInfo.sourceDeviceId = splitKeys[SOURCE_DEVICE_UDID_INDEX]; + saveInfo.bundleName = splitKeys[BUNDLE_NAME_INDEX]; + saveInfo.sessionId = splitKeys[SESSION_ID_INDEX]; + saveInfo.timestamp = splitKeys[TIME_INDEX]; + } std::string prefix = splitKeys[BUNDLE_NAME_INDEX] + splitKeys[SESSION_ID_INDEX]; std::string propertyName = splitKeys[PROPERTY_NAME_INDEX]; data[prefix].insert_or_assign(propertyName, item.second); @@ -436,57 +456,53 @@ void ObjectStoreManager::NotifyChange(std::map } } } - if (!hasAsset) { - callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { - DoNotify(tokenId, value, data, true); // no asset, data ready means all ready - return false; - }); - return; - } - NotifyDataChanged(data); - SaveUserToMeta(); + return data; } -void ObjectStoreManager::ComputeStatus(const std::string& objectKey, - const std::map>>& data) +void ObjectStoreManager::ComputeStatus(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map& data) { - restoreStatus_.Compute(objectKey, [this, &data] (const auto &key, auto &value) { - if (value == RestoreStatus::ASSETS_READY) { - value = RestoreStatus::ALL_READY; - callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { - DoNotify(tokenId, value, data, true); - return false; - }); - } else { - value = RestoreStatus::DATA_READY; - callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { - DoNotify(tokenId, value, data, false); - return false; - }); - WaitAssets(key); - } - return true; + restoreStatus_.Compute(objectKey, [this, &data, saveInfo] (const auto &key, auto &value) { + if (value == RestoreStatus::ASSETS_READY) { + value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS); + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data, true); + return false; + }); + } else { + value = RestoreStatus::DATA_READY; + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, saveInfo.bundleName); + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data, false); + return false; + }); + WaitAssets(key, saveInfo, data); + } + return true; }); } -void ObjectStoreManager::NotifyDataChanged(std::map>>& data) +void ObjectStoreManager::NotifyDataChanged(const std::map& data, const SaveInfo& saveInfo) { for (auto const& [objectKey, results] : data) { restoreStatus_.ComputeIfAbsent( objectKey, [](const std::string& key) -> auto { return RestoreStatus::NONE; }); - ComputeStatus(objectKey, data); + ComputeStatus(objectKey, saveInfo, data); } } -int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey) +int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map& data) { - auto taskId = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this, objectKey]() { - ZLOGE("wait assets finisehd timeout, objectKey:%{public}s", objectKey.c_str()); - RADAR_REPORT(ObjectStore::DATA_RESTORE, ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, ObjectStore::TIMEOUT); - NotifyAssetsReady(objectKey); + auto taskId = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this, objectKey, data, saveInfo]() { + ZLOGE("wait assets finisehd timeout, try pull assets, objectKey:%{public}s", objectKey.c_str()); + PullAssets(data, saveInfo); + DoNotifyWaitAssetTimeout(objectKey); }); objectTimer_.ComputeIfAbsent( @@ -496,21 +512,54 @@ int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey) return OBJECT_SUCCESS; } -void ObjectStoreManager::NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId) +void ObjectStoreManager::PullAssets(const std::map& data, const SaveInfo& saveInfo) +{ + std::map changedAssets; + for (auto const& [objectId, result] : data) { + changedAssets[objectId] = GetAssetsFromDBRecords(result); + } + for (const auto& [objectId, assets] : changedAssets) { + std::string networkId = DmAdaper::GetInstance().ToNetworkID(saveInfo.sourceDeviceId); + auto block = std::make_shared>>(WAIT_TIME, std::tuple{ true, true }); + ObjectAssetLoader::GetInstance()->TransferAssetsAsync(std::stoi(GetCurrentUser()), + saveInfo.bundleName, networkId, assets, [this, block](bool success) { + block->SetValue({ false, success }); + }); + auto [timeout, success] = block->GetValue(); + ZLOGI("Pull assets end, timeout: %{public}d, success: %{public}d, size:%{public}zu, deviceId: %{public}s", + timeout, success, assets.size(), DistributedData::Anonymous::Change(networkId).c_str()); + } +} + +void ObjectStoreManager::NotifyAssetsReady(const std::string& objectKey, const std::string& bundleName, + const std::string& srcNetworkId) { restoreStatus_.ComputeIfAbsent( objectKey, [](const std::string& key) -> auto { return RestoreStatus::NONE; }); - restoreStatus_.Compute(objectKey, [this] (const auto &key, auto &value) { - if (value == RestoreStatus::DATA_READY) { + restoreStatus_.Compute(objectKey, [this, &bundleName] (const auto &key, auto &value) { + if (value == RestoreStatus::DATA_NOTIFIED) { value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS); callbacks_.ForEach([this, key](uint32_t tokenId, const CallbackInfo& value) { DoNotifyAssetsReady(tokenId, value, key, true); return false; }); + } else if (value == RestoreStatus::DATA_READY) { + value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS); + auto [has, taskId] = objectTimer_.Find(key); + if (has) { + executors_->Remove(taskId); + objectTimer_.Erase(key); + } } else { value = RestoreStatus::ASSETS_READY; + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, bundleName); } return true; }); @@ -529,8 +578,7 @@ bool ObjectStoreManager::IsAssetKey(const std::string& key) return key.find(ObjectStore::ASSET_DOT) != std::string::npos; } -bool ObjectStoreManager::IsAssetComplete(const std::map>& result, - const std::string& assetPrefix) +bool ObjectStoreManager::IsAssetComplete(const ObjectRecord& result, const std::string& assetPrefix) { if (result.find(assetPrefix + ObjectStore::NAME_SUFFIX) == result.end() || result.find(assetPrefix + ObjectStore::URI_SUFFIX) == result.end() || @@ -543,7 +591,7 @@ bool ObjectStoreManager::IsAssetComplete(const std::map>& result) +Assets ObjectStoreManager::GetAssetsFromDBRecords(const ObjectRecord& result) { Assets assets{}; std::set assetKey; @@ -583,7 +631,7 @@ Assets ObjectStoreManager::GetAssetsFromDBRecords(const std::map>>& data, bool allReady) + const std::map& data, bool allReady) { for (const auto& observer : value.observers_) { auto it = data.find(observer.first); @@ -593,6 +641,13 @@ void ObjectStoreManager::DoNotify(uint32_t tokenId, const CallbackInfo& value, observer.second->Completed((*it).second, allReady); if (allReady) { restoreStatus_.Erase(observer.first); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } else { + restoreStatus_.ComputeIfPresent(observer.first, [](const auto &key, auto &value) { + value = RestoreStatus::DATA_NOTIFIED; + return true; + }); } } } @@ -604,9 +659,11 @@ void ObjectStoreManager::DoNotifyAssetsReady(uint32_t tokenId, const CallbackInf if (objectKey != observer.first) { continue; } - observer.second->Completed(std::map>(), allReady); + observer.second->Completed(ObjectRecord(), allReady); if (allReady) { restoreStatus_.Erase(objectKey); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); } auto [has, taskId] = objectTimer_.Find(objectKey); if (has) { @@ -616,6 +673,29 @@ void ObjectStoreManager::DoNotifyAssetsReady(uint32_t tokenId, const CallbackInf } } +void ObjectStoreManager::DoNotifyWaitAssetTimeout(const std::string &objectKey) +{ + ObjectStore::RadarReporter::ReportStageError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, ObjectStore::TIMEOUT); + callbacks_.ForEach([this, &objectKey](uint32_t tokenId, const CallbackInfo &value) { + for (const auto& observer : value.observers_) { + if (objectKey != observer.first) { + continue; + } + observer.second->Completed(ObjectRecord(), true); + restoreStatus_.Erase(objectKey); + auto [has, taskId] = objectTimer_.Find(objectKey); + if (has) { + executors_->Remove(taskId); + objectTimer_.Erase(objectKey); + } + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_FAILED, ObjectStore::TIMEOUT, ObjectStore::FINISHED); + } + return false; + }); +} + void ObjectStoreManager::SetData(const std::string &dataDir, const std::string &userId) { ZLOGI("enter %{public}s", dataDir.c_str()); @@ -629,21 +709,21 @@ void ObjectStoreManager::SetData(const std::string &dataDir, const std::string & int32_t ObjectStoreManager::Open() { if (kvStoreDelegateManager_ == nullptr) { - ZLOGE("not init"); + ZLOGE("Kvstore delegate manager not init"); return OBJECT_INNER_ERROR; } std::lock_guard lock(kvStoreMutex_); if (delegate_ == nullptr) { - ZLOGI("open store"); delegate_ = OpenObjectKvStore(); if (delegate_ == nullptr) { - ZLOGE("open failed,please check DB status"); + ZLOGE("Open object kvstore failed"); return OBJECT_DBSTATUS_ERROR; } syncCount_ = 1; + ZLOGI("Open object kvstore success"); } else { syncCount_++; - ZLOGI("syncCount = %{public}d", syncCount_); + ZLOGI("Object kvstore syncCount: %{public}d", syncCount_); } return OBJECT_SUCCESS; } @@ -675,8 +755,19 @@ void ObjectStoreManager::SyncCompleted( SetSyncStatus(false); FlushClosedStore(); } + for (const auto &item : results) { + if (item.second == DistributedDB::DBStatus::OK) { + ZLOGI("Sync data success, sequenceId: 0x%{public}" PRIx64 "", sequenceId); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } else { + ZLOGE("Sync data failed, sequenceId: 0x%{public}" PRIx64 ", status: %{public}d", sequenceId, item.second); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_FAILED, item.second, ObjectStore::FINISHED); + } + } } - + void ObjectStoreManager::FlushClosedStore() { std::lock_guard lock(kvStoreMutex_); @@ -703,11 +794,14 @@ void ObjectStoreManager::ProcessOldEntry(const std::string &appId) { std::vector entries; auto status = delegate_->GetEntries(std::vector(appId.begin(), appId.end()), entries); + if (status == DistributedDB::DBStatus::NOT_FOUND) { + ZLOGI("Get old entries empty, bundleName: %{public}s", appId.c_str()); + return; + } if (status != DistributedDB::DBStatus::OK) { - ZLOGE("GetEntries fail %{public}d", status); + ZLOGE("Get old entries failed, bundleName: %{public}s, status %{public}d", appId.c_str(), status); return; } - std::map sessionIds; int64_t oldestTime = 0; std::string deleteKey; @@ -731,42 +825,45 @@ void ObjectStoreManager::ProcessOldEntry(const std::string &appId) if (sessionIds.size() < MAX_OBJECT_SIZE_PER_APP) { return; } - ZLOGI("app object is full, delete oldest one %{public}s", deleteKey.c_str()); int32_t result = RevokeSaveToStore(deleteKey); if (result != OBJECT_SUCCESS) { - ZLOGE("RevokeSaveToStore fail %{public}d", result); + ZLOGE("Delete old entries failed, deleteKey: %{public}s, status: %{public}d", deleteKey.c_str(), result); return; } + ZLOGI("Delete old entries success, deleteKey: %{public}s", deleteKey.c_str()); } int32_t ObjectStoreManager::SaveToStore(const std::string &appId, const std::string &sessionId, - const std::string &toDeviceId, const std::map> &data) + const std::string &toDeviceId, const ObjectRecord &data) { ProcessOldEntry(appId); RevokeSaveToStore(GetPropertyPrefix(appId, sessionId, toDeviceId)); std::string timestamp = std::to_string(GetSecondsSince1970ToNow()); - std::vector entries; + std::string prefix = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR; DistributedDB::Entry saveInfoEntry; - std::string saveInfoKey = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR + SAVE_INFO; + std::string saveInfoKey = prefix + SAVE_INFO; saveInfoEntry.key = std::vector(saveInfoKey.begin(), saveInfoKey.end()); SaveInfo saveInfo(appId, sessionId, DmAdaper::GetInstance().GetLocalDevice().udid, toDeviceId, timestamp); std::string saveInfoValue = DistributedData::Serializable::Marshall(saveInfo); saveInfoEntry.value = std::vector(saveInfoValue.begin(), saveInfoValue.end()); + std::vector entries; entries.emplace_back(saveInfoEntry); for (auto &item : data) { DistributedDB::Entry entry; - std::string tmp = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR + item.first; - entry.key = std::vector(tmp.begin(), tmp.end()); + std::string key = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR + item.first; + entry.key = std::vector(key.begin(), key.end()); entry.value = item.second; entries.emplace_back(entry); } auto status = delegate_->PutBatch(entries); if (status != DistributedDB::DBStatus::OK) { - ZLOGE("putBatch fail %{public}d", status); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); + ZLOGE("PutBatch failed, bundleName: %{public}s, sessionId: %{public}s, dstNetworkId: %{public}s, " + "status: %{public}d", appId.c_str(), sessionId.c_str(), Anonymous::Change(toDeviceId).c_str(), status); + return status; } - return status; + ZLOGI("PutBatch success, bundleName: %{public}s, sessionId: %{public}s, dstNetworkId: %{public}s, " + "count: %{public}zu", appId.c_str(), sessionId.c_str(), Anonymous::Change(toDeviceId).c_str(), entries.size()); + return OBJECT_SUCCESS; } int32_t ObjectStoreManager::SyncOnStore( @@ -774,43 +871,39 @@ int32_t ObjectStoreManager::SyncOnStore( { std::vector syncDevices; for (auto &device : deviceList) { - // save to local, do not need sync if (device == LOCAL_DEVICE) { - ZLOGI("save to local successful"); - std::map result; - result[LOCAL_DEVICE] = OBJECT_SUCCESS; - callback(result); + ZLOGI("Save to local, do not need sync, prefix: %{public}s", prefix.c_str()); + callback({{LOCAL_DEVICE, OBJECT_SUCCESS}}); return OBJECT_SUCCESS; } syncDevices.emplace_back(DmAdaper::GetInstance().GetUuidByNetworkId(device)); } - if (!syncDevices.empty()) { - uint64_t sequenceId = SequenceSyncManager::GetInstance()->AddNotifier(userId_, callback); - DistributedDB::Query dbQuery = DistributedDB::Query::Select(); - dbQuery.PrefixKey(std::vector(prefix.begin(), prefix.end())); - ZLOGD("start sync"); - auto status = delegate_->Sync( - syncDevices, DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY, - [this, sequenceId](const std::map &devicesMap) { - ZLOGI("objectstore sync finished"); - std::map result; - for (auto &item : devicesMap) { - result[DmAdaper::GetInstance().ToNetworkID(item.first)] = item.second; - } - SyncCompleted(result, sequenceId); - }, - dbQuery, false); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("sync error %{public}d", status); - std::string tmp; - SequenceSyncManager::GetInstance()->DeleteNotifier(sequenceId, tmp); - return status; - } - SetSyncStatus(true); - } else { - ZLOGI("single device"); + if (syncDevices.empty()) { + ZLOGI("Device list is empty, prefix: %{public}s", Anonymous::Change(prefix).c_str()); callback(std::map()); + return OBJECT_SUCCESS; } + uint64_t sequenceId = SequenceSyncManager::GetInstance()->AddNotifier(userId_, callback); + DistributedDB::Query dbQuery = DistributedDB::Query::Select(); + dbQuery.PrefixKey(std::vector(prefix.begin(), prefix.end())); + ZLOGI("Start sync data, sequenceId: 0x%{public}" PRIx64 "", sequenceId); + auto status = delegate_->Sync(syncDevices, DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY, + [this, sequenceId](const std::map &devicesMap) { + ZLOGI("Sync data finished, sequenceId: 0x%{public}" PRIx64 "", sequenceId); + std::map result; + for (auto &item : devicesMap) { + result[DmAdaper::GetInstance().ToNetworkID(item.first)] = item.second; + } + SyncCompleted(result, sequenceId); + }, dbQuery, false); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("Sync data failed, prefix: %{public}s, sequenceId: 0x%{public}" PRIx64 ", status: %{public}d", + Anonymous::Change(prefix).c_str(), sequenceId, status); + std::string tmp; + SequenceSyncManager::GetInstance()->DeleteNotifier(sequenceId, tmp); + return status; + } + SetSyncStatus(true); return OBJECT_SUCCESS; } @@ -826,41 +919,46 @@ int32_t ObjectStoreManager::RevokeSaveToStore(const std::string &prefix) std::vector entries; auto status = delegate_->GetEntries(std::vector(prefix.begin(), prefix.end()), entries); if (status == DistributedDB::DBStatus::NOT_FOUND) { - ZLOGI("not found entry"); + ZLOGI("Get entries empty, prefix: %{public}s", Anonymous::Change(prefix).c_str()); return OBJECT_SUCCESS; } if (status != DistributedDB::DBStatus::OK) { - ZLOGE("GetEntries failed, status = %{public}d", status); + ZLOGE("Get entries failed, prefix: %{public}s, status: %{public}d", Anonymous::Change(prefix).c_str(), status); return DB_ERROR; } std::vector> keys; - std::for_each( - entries.begin(), entries.end(), [&keys](const DistributedDB::Entry &entry) { keys.emplace_back(entry.key); }); - if (!keys.empty()) { - status = delegate_->DeleteBatch(keys); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("DeleteBatch failed, status = %{public}d", status); - return DB_ERROR; - } + std::for_each(entries.begin(), entries.end(), [&keys](const DistributedDB::Entry &entry) { + keys.emplace_back(entry.key); + }); + if (keys.empty()) { + return OBJECT_SUCCESS; + } + status = delegate_->DeleteBatch(keys); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("Delete entries failed, prefix: %{public}s, status: %{public}d", Anonymous::Change(prefix).c_str(), + status); + return DB_ERROR; } + ZLOGI("Delete entries success, prefix: %{public}s, count: %{public}zu", Anonymous::Change(prefix).c_str(), + keys.size()); return OBJECT_SUCCESS; } -int32_t ObjectStoreManager::RetrieveFromStore( - const std::string &appId, const std::string &sessionId, std::map> &results) +int32_t ObjectStoreManager::RetrieveFromStore(const std::string &appId, const std::string &sessionId, + ObjectRecord &results) { std::vector entries; std::string prefix = GetPrefixWithoutDeviceId(appId, sessionId); auto status = delegate_->GetEntries(std::vector(prefix.begin(), prefix.end()), entries); if (status == DistributedDB::DBStatus::NOT_FOUND) { - ZLOGW("key not found, status = %{public}d", status); + ZLOGI("Get entries empty, prefix: %{public}s, status: %{public}d", prefix.c_str(), status); return KEY_NOT_FOUND; } if (status != DistributedDB::DBStatus::OK) { - ZLOGE("GetEntries failed, status = %{public}d", status); + ZLOGE("Get entries failed, prefix: %{public}s, status: %{public}d", prefix.c_str(), status); return DB_ERROR; } - ZLOGI("GetEntries successfully"); + ZLOGI("Get entries success, prefix: %{public}s, count: %{public}zu", prefix.c_str(), entries.size()); for (const auto &entry : entries) { std::string key(entry.key.begin(), entry.key.end()); if (key.find(SAVE_INFO) != std::string::npos) { @@ -1113,7 +1211,7 @@ int32_t ObjectStoreManager::OnAssetChanged(const uint32_t tokenId, const std::st auto snapshotKey = appId + SEPERATOR + sessionId; int32_t res = OBJECT_SUCCESS; bool exist = snapshots_.ComputeIfPresent(snapshotKey, - [&res, &dataAsset, &deviceId](std::string key, std::shared_ptr snapshot) { + [&res, &dataAsset, &deviceId](const std::string &key, std::shared_ptr snapshot) { if (snapshot != nullptr) { res = snapshot->OnDataChanged(dataAsset, deviceId); // needChange } diff --git a/services/distributeddataservice/service/object/object_manager.h b/services/distributeddataservice/service/object/object_manager.h index c2f5b9730aca2c7f2d5dc61af6e38e3a96043340..c750c61345f125e0c4396d03a3a59238cc9ba184 100644 --- a/services/distributeddataservice/service/object/object_manager.h +++ b/services/distributeddataservice/service/object/object_manager.h @@ -34,7 +34,7 @@ namespace OHOS { namespace DistributedObject { using SyncCallBack = std::function &results)>; - +using ObjectRecord = std::map>; class SequenceSyncManager { public: enum Result { @@ -68,6 +68,7 @@ public: enum RestoreStatus : int32_t { NONE = 0, DATA_READY, + DATA_NOTIFIED, ASSETS_READY, ALL_READY, STATUS_BUTT @@ -80,23 +81,23 @@ public: static ObjectStoreManager *manager = new ObjectStoreManager(); return manager; } - int32_t Save(const std::string &appId, const std::string &sessionId, - const std::map> &data, const std::string &deviceId, - sptr callback); + int32_t Save(const std::string &appId, const std::string &sessionId, const ObjectRecord &data, + const std::string &deviceId, sptr callback); int32_t RevokeSave( const std::string &appId, const std::string &sessionId, sptr callback); int32_t Retrieve(const std::string &bundleName, const std::string &sessionId, sptr callback, uint32_t tokenId); void SetData(const std::string &dataDir, const std::string &userId); int32_t Clear(); - int32_t DeleteByAppId(const std::string &appId); + int32_t DeleteByAppId(const std::string &appId, int32_t user); void RegisterRemoteCallback(const std::string &bundleName, const std::string &sessionId, pid_t pid, uint32_t tokenId, sptr callback); void UnregisterRemoteCallback(const std::string &bundleName, pid_t pid, uint32_t tokenId, const std::string &sessionId = ""); - void NotifyChange(std::map> &changedData); - void NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId = ""); + void NotifyChange(ObjectRecord &changedData); + void NotifyAssetsReady(const std::string& objectKey, const std::string& bundleName, + const std::string& srcNetworkId = ""); void NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId = ""); void CloseAfterMinute(); int32_t Open(); @@ -151,11 +152,10 @@ private: void Close(); int32_t SetSyncStatus(bool status); int32_t SaveToStore(const std::string &appId, const std::string &sessionId, const std::string &toDeviceId, - const std::map> &data); + const ObjectRecord &data); int32_t SyncOnStore(const std::string &prefix, const std::vector &deviceList, SyncCallBack &callback); int32_t RevokeSaveToStore(const std::string &prefix); - int32_t RetrieveFromStore( - const std::string &appId, const std::string &sessionId, std::map> &results); + int32_t RetrieveFromStore(const std::string &appId, const std::string &sessionId, ObjectRecord &results); void SyncCompleted(const std::map &results, uint64_t sequenceId); std::vector SplitEntryKey(const std::string &key); void ProcessOldEntry(const std::string &appId); @@ -163,22 +163,25 @@ private: const std::string &sessionId, const std::string &deviceId); void SaveUserToMeta(); std::string GetCurrentUser(); - void DoNotify(uint32_t tokenId, const CallbackInfo& value, - const std::map>>& data, bool allReady); + void DoNotify(uint32_t tokenId, const CallbackInfo& value, const std::map& data, + bool allReady); void DoNotifyAssetsReady(uint32_t tokenId, const CallbackInfo& value, const std::string& objectKey, bool allReady); - std::map> GetAssetsFromStore( - const std::map>& changedData); + void DoNotifyWaitAssetTimeout(const std::string &objectKey); + std::map> GetAssetsFromStore(const ObjectRecord& changedData); static bool IsAssetKey(const std::string& key); - static bool IsAssetComplete(const std::map>& result, - const std::string& assetPrefix); - Assets GetAssetsFromDBRecords(const std::map>& result); + static bool IsAssetComplete(const ObjectRecord& result, const std::string& assetPrefix); + Assets GetAssetsFromDBRecords(const ObjectRecord& result); bool RegisterAssetsLister(); - void ComputeStatus(const std::string& objectKey, - const std::map>>& data); - void NotifyDataChanged(std::map>>& data); - int32_t PushAssets(int32_t userId, const std::string &appId, const std::string &sessionId, - const std::map> &data, const std::string &deviceId); - int32_t WaitAssets(const std::string& objectKey); + void ComputeStatus(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map& data); + void NotifyDataChanged(const std::map& data, const SaveInfo& saveInfo); + int32_t PushAssets(const std::string &srcBundleName, const std::string &dstBundleName, const std::string &sessionId, + const ObjectRecord &data, const std::string &deviceId); + int32_t WaitAssets(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map& data); + void PullAssets(const std::map& data, const SaveInfo& saveInfo); + std::map GetObjectData(const ObjectRecord& changedData, SaveInfo& saveInfo, + bool& hasAsset); inline std::string GetPropertyPrefix(const std::string &appId, const std::string &sessionId) { return appId + SEPERATOR + sessionId + SEPERATOR + DmAdaper::GetInstance().GetLocalDevice().udid + SEPERATOR; diff --git a/services/distributeddataservice/service/object/object_service_impl.cpp b/services/distributeddataservice/service/object/object_service_impl.cpp index 8dec4d2d17f0e76a185f51b5cb6ff3db2dc2241d..5c32afaaa7794c3d99de0f3d2f1b71709edf420e 100644 --- a/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/services/distributeddataservice/service/object/object_service_impl.cpp @@ -19,6 +19,7 @@ #include +#include "accesstoken_kit.h" #include "account/account_delegate.h" #include "bootstrap.h" #include "checker/checker_manager.h" @@ -31,6 +32,7 @@ #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "object_asset_loader.h" +#include "object_dms_handler.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" #include "utils/anonymous.h" @@ -63,7 +65,8 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const sptr callback) { ZLOGI("begin."); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { @@ -73,8 +76,8 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); } - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, - ObjectStore::FINISHED); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS); return status; } @@ -109,6 +112,19 @@ int32_t ObjectServiceImpl::BindAssetStore(const std::string &bundleName, const s return status; } +int32_t ObjectServiceImpl::IsContinue(bool &result) +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + Security::AccessToken::HapTokenInfo tokenInfo; + auto status = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (status != 0) { + ZLOGE("Get hap token info failed, tokenId: %{public}u, status: %{public}d", tokenId, status); + return status; + } + result = ObjectDmsHandler::GetInstance().IsContinue(tokenInfo.bundleName); + return OBJECT_SUCCESS; +} + int32_t ObjectServiceImpl::OnInitialize() { ZLOGI("Initialize"); @@ -156,6 +172,7 @@ int32_t ObjectServiceImpl::OnInitialize() saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str()); RegisterObjectServiceInfo(); RegisterHandler(); + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); return OBJECT_SUCCESS; } @@ -196,8 +213,6 @@ int32_t ObjectServiceImpl::ObjectStoreRetrieve( status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback, tokenId); if (status != OBJECT_SUCCESS) { ZLOGE("retrieve fail %{public}d", status); - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); return status; } return OBJECT_SUCCESS; @@ -269,13 +284,14 @@ void ObjectServiceImpl::Clear() int32_t ObjectServiceImpl::ObjectStatic::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) { - ZLOGI("begin. %{public}s", bundleName.c_str()); - int32_t result = ObjectStoreManager::GetInstance()->DeleteByAppId(bundleName); + int32_t result = ObjectStoreManager::GetInstance()->DeleteByAppId(bundleName, user); if (result != OBJECT_SUCCESS) { - pid_t uid = IPCSkeleton::GetCallingUid(); - ZLOGE("Delete fail %{public}d, bundleName = %{public}s, uid = %{public}d", - result, bundleName.c_str(), uid); + ZLOGE("Delete object data failed, result:%{public}d, bundleName:%{public}s, user:%{public}d, index:%{public}d", + result, bundleName.c_str(), user, index); + return result; } + ZLOGI("Delete object data, bundleName:%{public}s, userId:%{public}d, index:%{public}d", bundleName.c_str(), user, + index); return result; } @@ -285,7 +301,7 @@ int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, Dist param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(), DistributedData::Anonymous::Change(identifier).c_str()); std::vector metaData; - auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid, param.userId }); + auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid }); if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { ZLOGE("no store in user:%{public}s", param.userId.c_str()); return OBJECT_STORE_NOT_FOUND; diff --git a/services/distributeddataservice/service/object/object_service_impl.h b/services/distributeddataservice/service/object/object_service_impl.h index 60cf85aeb75141aefd0991ed9100159bf498ebbf..437d49e9e47f5cda46271b5cf91686ea797edfb9 100644 --- a/services/distributeddataservice/service/object/object_service_impl.h +++ b/services/distributeddataservice/service/object/object_service_impl.h @@ -51,6 +51,7 @@ public: const std::string &deviceId, const ObjectStore::Asset &assetValue) override; int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) override; + int32_t IsContinue(bool &result) override; private: using StaticActs = DistributedData::StaticActs; class ObjectStatic : public StaticActs { diff --git a/services/distributeddataservice/service/object/object_service_stub.cpp b/services/distributeddataservice/service/object/object_service_stub.cpp index 3e332204b871e7d825d7227e392f1708f9951f47..20255eab45911b9c02250c8a6bc9421e70040497 100644 --- a/services/distributeddataservice/service/object/object_service_stub.cpp +++ b/services/distributeddataservice/service/object/object_service_stub.cpp @@ -181,6 +181,17 @@ int32_t ObjectServiceStub::OnDeleteSnapshot(MessageParcel &data, MessageParcel & return 0; } +int32_t ObjectServiceStub::OnIsContinue(MessageParcel &data, MessageParcel &reply) +{ + bool isContinue = false; + int32_t status = IsContinue(isContinue); + if (!ITypesUtil::Marshal(reply, isContinue)) { + ZLOGE("Marshal isContinue failed, isContinue: %{public}d, status: %{public}d", isContinue, status); + return -1; + } + return 0; +} + bool ObjectServiceStub::CheckInterfaceToken(MessageParcel& data) { auto localDescriptor = IObjectService::GetDescriptor(); diff --git a/services/distributeddataservice/service/object/object_service_stub.h b/services/distributeddataservice/service/object/object_service_stub.h index 8e71f9523cbb54ea4c2ff760b2c394d0a4908909..fef5c7ecaac6985175b2a45baf113ea1eaf075c4 100644 --- a/services/distributeddataservice/service/object/object_service_stub.h +++ b/services/distributeddataservice/service/object/object_service_stub.h @@ -36,6 +36,7 @@ private: int32_t OnAssetChangedOnRemote(MessageParcel &data, MessageParcel &reply); int32_t ObjectStoreBindAssetOnRemote(MessageParcel &data, MessageParcel &reply); int32_t OnDeleteSnapshot(MessageParcel &data, MessageParcel &reply); + int32_t OnIsContinue(MessageParcel &data, MessageParcel &reply); using RequestHandle = int (ObjectServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(ObjectCode::OBJECTSTORE_SERVICE_CMD_MAX)] = { &ObjectServiceStub::ObjectStoreSaveOnRemote, @@ -46,6 +47,7 @@ private: &ObjectServiceStub::OnAssetChangedOnRemote, &ObjectServiceStub::ObjectStoreBindAssetOnRemote, &ObjectServiceStub::OnDeleteSnapshot, + &ObjectServiceStub::OnIsContinue, }; }; } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/services/distributeddataservice/service/rdb/rdb_cloud.cpp index d1543625291791e698705e176b292731de4dc00e..69be4d82c32fb8a4cc8a6dfa428caf06467d5351 100644 --- a/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -42,6 +42,7 @@ DBStatus RdbCloud::BatchInsert( VBuckets temp = records; auto error = cloudDB_->BatchInsert(tableName, std::move(records), extends); PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -57,6 +58,7 @@ DBStatus RdbCloud::BatchUpdate( VBuckets temp = records; auto error = cloudDB_->BatchUpdate(tableName, std::move(records), extends); PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -65,6 +67,7 @@ DBStatus RdbCloud::BatchDelete(const std::string &tableName, std::vectorBatchDelete(tableName, extends); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -115,15 +118,13 @@ DistributedData::GeneralError RdbCloud::PreSharing(const std::string& tableName, std::pair RdbCloud::Lock() { - auto error = cloudDB_->Lock(); - return std::make_pair( // int64_t <-> uint32_t, s <-> ms - ConvertStatus(static_cast(error)), cloudDB_->AliveTime() * TO_MS); + auto result = InnerLock(FLAG::SYSTEM_ABILITY); + return { ConvertStatus(result.first), result.second }; } DBStatus RdbCloud::UnLock() { - auto error = cloudDB_->Unlock(); - return ConvertStatus(static_cast(error)); + return ConvertStatus(InnerUnLock(FLAG::SYSTEM_ABILITY)); } DBStatus RdbCloud::HeartBeat() @@ -138,6 +139,34 @@ DBStatus RdbCloud::Close() return ConvertStatus(static_cast(error)); } +std::pair RdbCloud::InnerLock(FLAG flag) +{ + std::lock_guard lock(mutex_); + flag_ |= flag; + // int64_t <-> uint32_t, s <-> ms + return std::make_pair(static_cast(cloudDB_->Lock()), cloudDB_->AliveTime() * TO_MS); +} + +GeneralError RdbCloud::InnerUnLock(FLAG flag) +{ + std::lock_guard lock(mutex_); + flag_ &= ~flag; + if (flag_ == 0) { + return static_cast(cloudDB_->Unlock()); + } + return GeneralError::E_OK; +} + +std::pair RdbCloud::LockCloudDB(FLAG flag) +{ + return InnerLock(flag); +} + +GeneralError RdbCloud::UnLockCloudDB(FLAG flag) +{ + return InnerUnLock(flag); +} + std::pair RdbCloud::GetEmptyCursor(const std::string &tableName) { auto [error, cursor] = cloudDB_->GetEmptyCursor(tableName); @@ -161,6 +190,14 @@ DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) return DBStatus::CLOUD_VERSION_CONFLICT; case GeneralError::E_RECORD_EXIST_CONFLICT: return DBStatus::CLOUD_RECORD_EXIST_CONFLICT; + case GeneralError::E_RECORD_NOT_FOUND: + return DBStatus::CLOUD_RECORD_NOT_FOUND; + case GeneralError::E_RECORD_ALREADY_EXISTED: + return DBStatus::CLOUD_RECORD_ALREADY_EXISTED; + case GeneralError::E_FILE_NOT_EXIST: + return DBStatus::LOCAL_ASSET_NOT_FOUND; + case GeneralError::E_TIME_OUT: + return DBStatus::TIME_OUT; default: ZLOGI("error:0x%{public}x", error); break; @@ -288,4 +325,32 @@ void RdbCloud::PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, it->second->Uploaded(asset); } } -} // namespace OHOS::DistributedRdb + +uint8_t RdbCloud::GetLockFlag() const +{ + return flag_; +} + +void RdbCloud::ConvertErrorField(DistributedData::VBuckets& extends) +{ + for (auto& extend : extends) { + auto errorField = extend.find(SchemaMeta::ERROR_FIELD); + if (errorField == extend.end()) { + continue; + } + auto errCode = Traits::get_if(&(errorField->second)); + if (errCode == nullptr) { + continue; + } + errorField->second = ConvertStatus(static_cast(*errCode)); + } +} + +void RdbCloud::SetPrepareTraceId(const std::string &traceId) +{ + if (cloudDB_ == nullptr) { + return; + } + cloudDB_->SetPrepareTraceId(traceId); +} +} // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_cloud.h b/services/distributeddataservice/service/rdb/rdb_cloud.h index be8b11793242e1aed296fb1ed4f900e2a1dbf008..ac93e253d3c22618ea75faad8164d3b935bbbda9 100644 --- a/services/distributeddataservice/service/rdb/rdb_cloud.h +++ b/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -15,6 +15,9 @@ #ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H + +#include + #include "cloud/cloud_db.h" #include "cloud/cloud_store_types.h" #include "cloud/icloud_db.h" @@ -24,11 +27,16 @@ namespace OHOS::DistributedRdb { class RdbCloud : public DistributedDB::ICloudDb { public: + enum FLAG : uint8_t { + SYSTEM_ABILITY = 1, + APPLICATION + }; using DBStatus = DistributedDB::DBStatus; using DBVBucket = DistributedDB::VBucket; using DBQueryNodes = std::vector; using DataBucket = DistributedData::VBucket; using BindAssets = DistributedData::BindAssets; + using GeneralError = DistributedData::GeneralError; explicit RdbCloud(std::shared_ptr cloudDB, BindAssets* bindAssets); virtual ~RdbCloud() = default; @@ -45,6 +53,10 @@ public: DBStatus Close() override; std::pair GetEmptyCursor(const std::string &tableName) override; static DBStatus ConvertStatus(DistributedData::GeneralError error); + uint8_t GetLockFlag() const; + std::pair LockCloudDB(FLAG flag); + GeneralError UnLockCloudDB(FLAG flag); + void SetPrepareTraceId(const std::string &traceId) override; private: static constexpr const char *TYPE_FIELD = "#_type"; @@ -52,9 +64,12 @@ private: using QueryNodes = std::vector; static std::pair ConvertQuery(DBVBucket& extend); static QueryNodes ConvertQuery(DBQueryNodes&& nodes); + static void ConvertErrorField(DistributedData::VBuckets& extends); static constexpr int32_t TO_MS = 1000; // s > ms std::shared_ptr cloudDB_; BindAssets* snapshots_; + uint8_t flag_ = 0; + std::mutex mutex_; void PostEvent(DistributedData::VBuckets& records, std::set& skipAssets, DistributedData::VBuckets& extend, DistributedData::AssetEvent eventId); @@ -62,6 +77,8 @@ private: DistributedData::AssetEvent eventId); void PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, std::set& skipAssets, DistributedData::AssetEvent eventId); + std::pair InnerLock(FLAG flag); + GeneralError InnerUnLock(FLAG flag); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H diff --git a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp index f6fb43dced0fdb25d29c674996eed8ae4bc938d9..833474bd410f5f8f0d8cb55bf1e5b33447f22b8e 100644 --- a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp +++ b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp @@ -12,12 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "RdbCloudDataTranslate" + #include "rdb_cloud_data_translate.h" #include "utils/endian_converter.h" #include "value_proxy.h" -#include "log_print.h" namespace OHOS::DistributedRdb { using Asset = DistributedDB::Asset; @@ -132,7 +131,6 @@ size_t RdbCloudDataTranslate::ParserRawData(const uint8_t *data, size_t length, num = DistributedData::NetToHost(*(reinterpret_cast(alignData.data()))); used += sizeof(num); uint16_t count = 0; - std::set names; while (used < length && count < num) { DataAsset asset; auto dataLen = ParserRawData(&data[used], length - used, asset); @@ -140,32 +138,12 @@ size_t RdbCloudDataTranslate::ParserRawData(const uint8_t *data, size_t length, break; } used += dataLen; - if (!names.insert(asset.name).second) { - ZLOGE("duplicate assets! name:%{public}.6s start merge.", asset.name.c_str()); - MergeAsset(assets, asset); - } else { - assets.push_back(std::move(asset)); - } + assets.push_back(std::move(asset)); count++; } return used; } -void RdbCloudDataTranslate::MergeAsset(DataAssets &assets, DataAsset &asset) -{ - auto it = assets.begin(); - while (it != assets.end()) { - if (it->name == asset.name && - strtoll(it->modifyTime.c_str(), nullptr, 0) < strtoll(asset.modifyTime.c_str(), nullptr, 0)) { - assets.erase(it); - assets.push_back(std::move(asset)); - break; - } - it++; - } - return; -} - bool RdbCloudDataTranslate::InnerAsset::Marshal(OHOS::DistributedData::Serializable::json &node) const { bool ret = true; diff --git a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h index 9f6792f5fd780366f03b396c028f172075950200..dd8129e5d22444d006255f8418e498150cfa48b4 100644 --- a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h +++ b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h @@ -46,7 +46,6 @@ private: }; size_t ParserRawData(const uint8_t *data, size_t length, DataAsset &asset); size_t ParserRawData(const uint8_t *data, size_t length, DataAssets &assets); - void MergeAsset(DataAssets &assets, DataAsset &asset); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_DATA_TRASLATE_H diff --git a/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/services/distributeddataservice/service/rdb/rdb_general_store.cpp index ceef58d99780dfac93b2b17c7baebdb358297deb..3be1df0a51c926e619df7b3c1e9ec720a054f8b2 100644 --- a/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -20,8 +20,10 @@ #include #include "cache_cursor.h" +#include "changeevent/remote_change_event.h" #include "cloud/asset_loader.h" #include "cloud/cloud_db.h" +#include "cloud/cloud_lock_event.h" #include "cloud/cloud_store_types.h" #include "cloud/schema_meta.h" #include "cloud_service.h" @@ -57,11 +59,13 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; constexpr const char *INSERT = "INSERT INTO "; constexpr const char *REPLACE = "REPLACE INTO "; constexpr const char *VALUES = " VALUES "; +constexpr const char *LOGOUT_DELETE_FLAG = "DELETE#ALL_CLOUDDATA"; constexpr const LockAction LOCK_ACTION = static_cast(static_cast(LockAction::INSERT) | static_cast(LockAction::UPDATE) | static_cast(LockAction::DELETE) | static_cast(LockAction::DOWNLOAD)); constexpr uint32_t CLOUD_SYNC_FLAG = 1; constexpr uint32_t SEARCHABLE_FLAG = 2; +constexpr uint32_t LOCK_TIMEOUT = 3600; // second static DBSchema GetDBSchema(const Database &database) { @@ -84,10 +88,23 @@ static DBSchema GetDBSchema(const Database &database) return schema; } -RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) +void RdbGeneralStore::InitStoreInfo(const StoreMetaData &meta) +{ + storeInfo_.tokenId = meta.tokenId; + storeInfo_.bundleName = meta.bundleName; + storeInfo_.storeName = meta.storeId; + storeInfo_.instanceId = meta.instanceId; + storeInfo_.user = std::stoi(meta.user); + storeInfo_.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; +} + +RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) + : manager_(meta.appId, meta.user, meta.instanceId), tasks_(std::make_shared>()) { observer_.storeId_ = meta.storeId; + observer_.meta_ = meta; RelationalStoreDelegate::Option option; + option.syncDualTupleMode = true; option.observer = &observer_; if (meta.isEncrypt) { std::string key = meta.GetSecretKey(); @@ -106,20 +123,18 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI break; } manager_.CloseStore(delegate_); + delegate_ = nullptr; } } else { auto ret = manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); if (ret != DBStatus::OK || delegate_ == nullptr) { manager_.CloseStore(delegate_); + delegate_ = nullptr; } } - storeInfo_.tokenId = meta.tokenId; - storeInfo_.bundleName = meta.bundleName; - storeInfo_.storeName = meta.storeId; - storeInfo_.instanceId = meta.instanceId; - storeInfo_.user = std::stoi(meta.user); - storeInfo_.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + InitStoreInfo(meta); + if (meta.isSearchable) { syncNotifyFlag_ |= SEARCHABLE_FLAG; } @@ -129,6 +144,10 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI static_cast(const_cast(static_cast(&meta.isManualClean))); delegate_->Pragma(PragmaCmd::LOGIC_DELETE_SYNC_DATA, data); } + ZLOGI("Get rdb store, tokenId:%{public}u, bundleName:%{public}s, storeName:%{public}s, user:%{public}s," + "isEncrypt:%{public}d, isManualClean:%{public}d, isSearchable:%{public}d", + meta.tokenId, meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), meta.user.c_str(), + meta.isEncrypt, meta.isManualClean, meta.isSearchable); } RdbGeneralStore::~RdbGeneralStore() @@ -142,6 +161,9 @@ RdbGeneralStore::~RdbGeneralStore() bindInfo_.db_ = nullptr; rdbCloud_ = nullptr; rdbLoader_ = nullptr; + RemoveTasks(); + tasks_ = nullptr; + executor_ = nullptr; } int32_t RdbGeneralStore::BindSnapshots(std::shared_ptr>> bindAssets) @@ -177,15 +199,18 @@ int32_t RdbGeneralStore::Bind(Database &database, const std::map(BindEvent::BIND_SNAPSHOT, std::move(eventInfo)); EventCenter::GetInstance().PostEvent(std::move(evt)); bindInfo_ = std::move(bindInfo); - rdbCloud_ = std::make_shared(bindInfo_.db_, &snapshots_); - rdbLoader_ = std::make_shared(bindInfo_.loader_, &snapshots_); + { + std::unique_lock lock(rdbCloudMutex_); + rdbCloud_ = std::make_shared(bindInfo_.db_, &snapshots_); + rdbLoader_ = std::make_shared(bindInfo_.loader_, &snapshots_); + } DistributedDB::CloudSyncConfig dbConfig; dbConfig.maxUploadCount = config.maxNumber; dbConfig.maxUploadSize = config.maxSize; dbConfig.maxRetryConflictTimes = config.maxRetryConflictTimes; DBSchema schema = GetDBSchema(database); - std::unique_lock lock(rwMutex_); + std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("database:%{public}s already closed!", Anonymous::Change(database.name).c_str()); return GeneralError::E_ALREADY_CLOSED; @@ -206,25 +231,38 @@ bool RdbGeneralStore::IsBound() int32_t RdbGeneralStore::Close(bool isForce) { - std::unique_lock lock(rwMutex_); - if (delegate_ == nullptr) { - return 0; - } - if (!isForce && delegate_->GetCloudSyncTaskCount() > 0) { - return GeneralError::E_BUSY; - } - auto status = manager_.CloseStore(delegate_); - if (status != DBStatus::OK) { - return status; + { + std::unique_lock lock(rwMutex_, std::chrono::seconds(isForce ? LOCK_TIMEOUT : 0)); + if (!lock) { + return GeneralError::E_BUSY; + } + + if (delegate_ == nullptr) { + return GeneralError::E_OK; + } + if (!isForce && delegate_->GetCloudSyncTaskCount() > 0) { + return GeneralError::E_BUSY; + } + if (isForce && bindInfo_.loader_ != nullptr) { + bindInfo_.loader_->Cancel(); + } + auto status = manager_.CloseStore(delegate_); + if (status != DBStatus::OK) { + return status; + } + delegate_ = nullptr; } - delegate_ = nullptr; + RemoveTasks(); bindInfo_.loader_ = nullptr; if (bindInfo_.db_ != nullptr) { bindInfo_.db_->Close(); } bindInfo_.db_ = nullptr; - rdbCloud_ = nullptr; - rdbLoader_ = nullptr; + { + std::unique_lock lock(rdbCloudMutex_); + rdbCloud_ = nullptr; + rdbLoader_ = nullptr; + } return GeneralError::E_OK; } @@ -444,7 +482,8 @@ std::pair> RdbGeneralStore::Query(const std::st ZLOGE("RemoteQuery: devices size error! size:%{public}zu", rdbQuery->GetDevices().size()); return { GeneralError::E_ERROR, nullptr }; } - return { GeneralError::E_OK, RemoteQuery(*rdbQuery->GetDevices().begin(), rdbQuery->GetRemoteCondition()) }; + auto cursor = RemoteQuery(*rdbQuery->GetDevices().begin(), rdbQuery->GetRemoteCondition()); + return { cursor != nullptr ? GeneralError::E_OK : GeneralError::E_ERROR, cursor}; } return { GeneralError::E_ERROR, nullptr }; } @@ -462,7 +501,21 @@ int32_t RdbGeneralStore::MergeMigratedData(const std::string &tableName, VBucket return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; } -int32_t RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParam) +int32_t RdbGeneralStore::CleanTrackerData(const std::string &tableName, int64_t cursor) +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("Database already closed! database:%{public}s, table:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(tableName).c_str()); + return GeneralError::E_ERROR; + } + + auto status = delegate_->CleanTrackerData(tableName, cursor); + return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; +} + +std::pair RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const SyncParam &syncParam) { DistributedDB::Query dbQuery; RdbQuery *rdbQuery = nullptr; @@ -481,18 +534,34 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsy ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " "wait:%{public}d", devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncParam.mode, syncParam.wait); - return GeneralError::E_ALREADY_CLOSED; + return { GeneralError::E_ALREADY_CLOSED, DBStatus::OK }; } auto highMode = GetHighMode(static_cast(syncParam.mode)); - uint32_t syncId = ++syncTaskId_; - auto status = (syncMode < NEARBY_END) - ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), syncParam.wait != 0) - : (syncMode > NEARBY_END && syncMode < CLOUD_END) - ? delegate_->Sync({ devices, dbMode, dbQuery, syncParam.wait, (isPriority || highMode == MANUAL_SYNC_MODE), - syncParam.isCompensation, {}, highMode == AUTO_SYNC_MODE, LOCK_ACTION }, - GetDBProcessCB(std::move(async), syncMode, syncId, highMode)) - : DistributedDB::INVALID_ARGS; - return status; + SyncId syncId = ++syncTaskId_; + auto dbStatus = DistributedDB::INVALID_ARGS; + if (syncMode < NEARBY_END) { + dbStatus = delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), syncParam.wait != 0); + } else if (syncMode > NEARBY_END && syncMode < CLOUD_END) { + auto callback = GetDBProcessCB(std::move(async), syncMode, syncId, highMode); + if (executor_ != nullptr && tasks_ != nullptr) { + auto id = executor_->Schedule(std::chrono::minutes(INTERVAL), GetFinishTask(syncId)); + tasks_->Insert(syncId, { id, callback }); + } + dbStatus = delegate_->Sync({ devices, dbMode, dbQuery, syncParam.wait, + (isPriority || highMode == MANUAL_SYNC_MODE), syncParam.isCompensation, {}, + highMode == AUTO_SYNC_MODE, LOCK_ACTION, syncParam.prepareTraceId }, + tasks_ != nullptr ? GetCB(syncId) : callback, syncId); + if (dbStatus == DBStatus::OK || tasks_ == nullptr) { + return { ConvertStatus(dbStatus), dbStatus }; + } + tasks_->ComputeIfPresent(syncId, [executor = executor_](SyncId syncId, const FinishTask &task) { + if (executor != nullptr) { + executor->Remove(task.taskId); + } + return false; + }); + } + return { ConvertStatus(dbStatus), dbStatus }; } std::pair> RdbGeneralStore::PreSharing(GenQuery &query) @@ -518,17 +587,16 @@ std::pair> RdbGeneralStore::PreSharing(GenQuery return { GeneralError::E_ALREADY_CLOSED, nullptr }; } auto [errCode, ret] = QuerySql(sql, rdbQuery->GetBindArgs()); - if (errCode != GeneralError::E_OK) { - values = std::move(ret); - } + values = std::move(ret); } - if (rdbCloud_ == nullptr || values.empty()) { - ZLOGW("rdbCloud is %{public}s, values size:%{public}zu", rdbCloud_ == nullptr ? "nullptr" : "not nullptr", + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr || values.empty()) { + ZLOGW("rdbCloud is %{public}s, values size:%{public}zu", rdbCloud == nullptr ? "nullptr" : "not nullptr", values.size()); return { GeneralError::E_CLOUD_DISABLED, nullptr }; } VBuckets extends = ExtractExtend(values); - rdbCloud_->PreSharing(*tables.begin(), extends); + rdbCloud->PreSharing(*tables.begin(), extends); for (auto value = values.begin(), extend = extends.begin(); value != values.end() && extend != extends.end(); ++value, ++extend) { value->insert_or_assign(DistributedRdb::Field::SHARING_RESOURCE_FIELD, (*extend)[SchemaMeta::SHARING_RESOURCE]); @@ -660,17 +728,19 @@ RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) }; } -RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t syncId, +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t syncMode, SyncId syncId, uint32_t highMode) { - return [async, autoAsync = async_, highMode, storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode, syncId]( - const std::map &processes) { + std::shared_lock lock(asyncMutex_); + return [async, autoAsync = async_, highMode, storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode, syncId, + rdbCloud = GetRdbCloud()](const std::map &processes) { DistributedData::GenDetails details; for (auto &[id, process] : processes) { + bool isDownload = false; auto &detail = details[id]; detail.progress = process.process; detail.code = ConvertStatus(process.errCode); - detail.dbCode = DB_ERR_OFFSET + process.errCode; + detail.dbCode = process.errCode; uint32_t totalCount = 0; for (auto [key, value] : process.tableProcess) { auto &table = detail.details[key]; @@ -679,14 +749,15 @@ RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, table.upload.failed = value.upLoadInfo.failCount; table.upload.untreated = table.upload.total - table.upload.success - table.upload.failed; totalCount += table.upload.total; + isDownload = table.download.total > 0; table.download.total = value.downLoadInfo.total; table.download.success = value.downLoadInfo.successCount; table.download.failed = value.downLoadInfo.failCount; table.download.untreated = table.download.total - table.download.success - table.download.failed; - detail.dataChange = detail.dataChange || - (process.process == FINISHED && - (value.downLoadInfo.insertCount > 0 || value.downLoadInfo.updateCount > 0 || - value.downLoadInfo.deleteCount > 0)); + detail.changeCount = (process.process == FINISHED) + ? value.downLoadInfo.insertCount + value.downLoadInfo.updateCount + + value.downLoadInfo.deleteCount + : 0; totalCount += table.download.total; } if (process.process == FINISHED) { @@ -694,6 +765,11 @@ RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, } else { RdbGeneralStore::OnSyncStart(storeInfo, flag, syncMode, syncId, totalCount); } + + if (isDownload && (process.process == FINISHED || process.process == PROCESSING) && rdbCloud != nullptr && + (rdbCloud->GetLockFlag() & RdbCloud::FLAG::APPLICATION)) { + rdbCloud->LockCloudDB(RdbCloud::FLAG::APPLICATION); + } } if (async) { async(details); @@ -762,8 +838,8 @@ int32_t RdbGeneralStore::SetDistributedTables(const std::vector &ta return GeneralError::E_OK; } -int32_t RdbGeneralStore::SetTrackerTable( - const std::string &tableName, const std::set &trackerColNames, const std::string &extendColName) +int32_t RdbGeneralStore::SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, + const std::string &extendColName, bool isForceUpgrade) { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { @@ -771,7 +847,7 @@ int32_t RdbGeneralStore::SetTrackerTable( Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(tableName).c_str()); return GeneralError::E_ALREADY_CLOSED; } - auto status = delegate_->SetTrackerTable({ tableName, extendColName, trackerColNames }); + auto status = delegate_->SetTrackerTable({ tableName, extendColName, trackerColNames, isForceUpgrade }); if (status == DBStatus::WITH_INVENTORY_DATA) { ZLOGI("Set tracker table with inventory data, database:%{public}s, tables name:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(tableName).c_str()); @@ -830,12 +906,14 @@ bool RdbGeneralStore::IsValid() int32_t RdbGeneralStore::RegisterDetailProgressObserver(GeneralStore::DetailAsync async) { + std::unique_lock lock(asyncMutex_); async_ = std::move(async); return GenErr::E_OK; } int32_t RdbGeneralStore::UnregisterDetailProgressObserver() { + std::unique_lock lock(asyncMutex_); async_ = nullptr; return GenErr::E_OK; } @@ -918,6 +996,20 @@ std::vector RdbGeneralStore::GetIntersection(std::vector &tables, ChangeType type) +{ + RemoteChangeEvent::DataInfo info; + info.userId = meta.user; + info.storeId = meta.storeId; + info.deviceId = meta.deviceId; + info.bundleName = meta.bundleName; + info.tables = tables; + info.changeType = type; + auto evt = std::make_unique(RemoteChangeEvent::DATA_CHANGE, std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} + void RdbGeneralStore::ObserverProxy::OnChange(const DBChangedIF &data) { if (!HasWatcher()) { @@ -955,17 +1047,153 @@ void RdbGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string genOrigin.store = storeId_; Watcher::PRIFields fields; Watcher::ChangeInfo changeInfo; + bool notifyFlag = false; for (uint32_t i = 0; i < DistributedDB::OP_BUTT; ++i) { auto &info = changeInfo[data.tableName][i]; for (auto &priData : data.primaryData[i]) { Watcher::PRIValue value; Convert(std::move(*(priData.begin())), value); + if (notifyFlag || origin != DBOrigin::ORIGIN_CLOUD || i != DistributedDB::OP_DELETE) { + info.push_back(std::move(value)); + continue; + } + auto deleteKey = std::get_if(&value); + if (deleteKey != nullptr && (*deleteKey == LOGOUT_DELETE_FLAG)) { + // notify to start app + notifyFlag = true; + } info.push_back(std::move(value)); } } + if (notifyFlag) { + PostDataChange(meta_, {}, CLOUD_DATA_CLEAN); + } if (!data.field.empty()) { fields[std::move(data.tableName)] = std::move(*(data.field.begin())); } watcher_->OnChange(genOrigin, fields, std::move(changeInfo)); } + +std::pair RdbGeneralStore::LockCloudDB() +{ + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr) { + return { GeneralError::E_ERROR, 0 }; + } + return rdbCloud->LockCloudDB(RdbCloud::FLAG::APPLICATION); +} + +int32_t RdbGeneralStore::UnLockCloudDB() +{ + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr) { + return GeneralError::E_ERROR; + } + return rdbCloud->UnLockCloudDB(RdbCloud::FLAG::APPLICATION); +} + +std::shared_ptr RdbGeneralStore::GetRdbCloud() const +{ + std::shared_lock lock(rdbCloudMutex_); + return rdbCloud_; +} + +bool RdbGeneralStore::IsFinished(SyncId syncId) const +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); + return true; + } + return delegate_->GetCloudTaskStatus(syncId).process == DistributedDB::FINISHED; +} + +Executor::Task RdbGeneralStore::GetFinishTask(SyncId syncId) +{ + return [this, executor = executor_, task = tasks_, syncId]() { + auto [exist, finishTask] = task->Find(syncId); + if (!exist || finishTask.cb == nullptr) { + task->Erase(syncId); + return; + } + if (!IsFinished(syncId)) { + task->ComputeIfPresent(syncId, [executor = executor_, this](SyncId syncId, FinishTask &task) { + task.taskId = executor->Schedule(std::chrono::minutes(INTERVAL), GetFinishTask(syncId)); + return true; + }); + return; + } + DBProcessCB cb; + task->ComputeIfPresent(syncId, [&cb, executor = executor_](SyncId syncId, const FinishTask &task) { + cb = task.cb; + return false; + }); + if (cb != nullptr) { + ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", + Anonymous::Change(storeInfo_.storeName).c_str(), syncId); + std::map result; + result.insert({ "", { DistributedDB::FINISHED, DBStatus::DB_ERROR } }); + cb(result); + } + }; +} + +void RdbGeneralStore::SetExecutor(std::shared_ptr executor) +{ + if (executor_ == nullptr) { + executor_ = executor; + } +} + +void RdbGeneralStore::RemoveTasks() +{ + if (tasks_ == nullptr) { + return; + } + std::list cbs; + std::list taskIds; + tasks_->EraseIf([&cbs, &taskIds, store = storeInfo_.storeName](SyncId syncId, const FinishTask &task) { + if (task.cb != nullptr) { + ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", Anonymous::Change(store).c_str(), + syncId); + } + cbs.push_back(std::move(task.cb)); + taskIds.push_back(task.taskId); + return true; + }); + if (executor_ != nullptr) { + for (auto taskId : taskIds) { + executor_->Remove(taskId, true); + } + } + std::map result; + result.insert({ "", { DistributedDB::FINISHED, DBStatus::DB_ERROR } }); + for (auto &cb : cbs) { + if (cb != nullptr) { + cb(result); + } + } +} + +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetCB(SyncId syncId) +{ + return [task = tasks_, executor = executor_, syncId](const std::map &progress) { + if (task == nullptr) { + return; + } + DBProcessCB cb; + task->ComputeIfPresent(syncId, [&cb, &progress, executor](SyncId syncId, FinishTask &finishTask) { + cb = finishTask.cb; + bool isFinished = !progress.empty() && progress.begin()->second.process == DistributedDB::FINISHED; + if (isFinished) { + finishTask.cb = nullptr; + } + return true; + }); + if (cb != nullptr) { + cb(progress); + } + return; + }; +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_general_store.h b/services/distributeddataservice/service/rdb/rdb_general_store.h index 8216a5122088227696495d0216fa7c3bb7639e6d..eb90a6074ca4dab3da41438ee20643d6fa062f93 100644 --- a/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -19,6 +19,7 @@ #include #include +#include "concurrent_map.h" #include "metadata/store_meta_data.h" #include "rdb_asset_loader.h" #include "rdb_cloud.h" @@ -52,6 +53,7 @@ public: uint32_t traceId, uint32_t syncCount); static void OnSyncFinish(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, uint32_t traceId); + void SetExecutor(std::shared_ptr executor) override; int32_t Bind(Database &database, const std::map &bindInfos, const CloudConfig &config) override; bool IsBound() override; @@ -60,7 +62,7 @@ public: int32_t SetDistributedTables(const std::vector &tables, int32_t type, const std::vector &references) override; int32_t SetTrackerTable(const std::string& tableName, const std::set& trackerColNames, - const std::string& extendColName) override; + const std::string& extendColName, bool isForceUpgrade = false) override; int32_t Insert(const std::string &table, VBuckets &&values) override; int32_t Update(const std::string &table, const std::string &setSql, Values &&values, const std::string &whereSql, Values &&conditions) override; @@ -69,8 +71,8 @@ public: std::pair> Query(const std::string &table, const std::string &sql, Values &&args) override; std::pair> Query(const std::string &table, GenQuery &query) override; - int32_t Sync( - const Devices &devices, GenQuery &query, DetailAsync async, DistributedData::SyncParam &syncParam) override; + std::pair Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const DistributedData::SyncParam &syncParam) override; std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; @@ -82,7 +84,10 @@ public: int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets&& values) override; + int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) override; std::vector GetWaterVersion(const std::string &deviceId) override; + std::pair LockCloudDB() override; + int32_t UnLockCloudDB() override; private: RdbGeneralStore(const RdbGeneralStore& rdbGeneralStore); @@ -92,11 +97,16 @@ private: using SyncProcess = DistributedDB::SyncProcess; using DBBriefCB = DistributedDB::SyncStatusCallback; using DBProcessCB = std::function &processes)>; + using TaskId = ExecutorPool::TaskId; + using Time = std::chrono::steady_clock::time_point; + using SyncId = uint64_t; static GenErr ConvertStatus(DistributedDB::DBStatus status); + void InitStoreInfo(const StoreMetaData &meta); // GetIntersection and return results in the order of collecter1 static std::vector GetIntersection(std::vector &&syncTables, const std::set &localTables); static constexpr inline uint64_t REMOTE_QUERY_TIME_OUT = 30 * 1000; + static constexpr int64_t INTERVAL = 1; static constexpr const char* CLOUD_GID = "cloud_gid"; static constexpr const char* DATE_KEY = "data_key"; static constexpr const char* QUERY_TABLES_SQL = "select name from sqlite_master where type = 'table';"; @@ -117,13 +127,21 @@ private: return watcher_ != nullptr; } private: + enum ChangeType { + CLOUD_DATA_CHANGE = 0, + CLOUD_DATA_CLEAN + }; + void PostDataChange(const StoreMetaData &meta, const std::vector &tables, ChangeType type); friend RdbGeneralStore; Watcher *watcher_ = nullptr; std::string storeId_; + StoreMetaData meta_; }; DBBriefCB GetDBBriefCB(DetailAsync async); - DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t syncId, + DBProcessCB GetCB(SyncId syncId); + DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t syncMode, SyncId syncId, uint32_t highMode = AUTO_SYNC_MODE); + Executor::Task GetFinishTask(SyncId syncId); std::shared_ptr RemoteQuery(const std::string &device, const DistributedDB::RemoteCondition &remoteCondition); std::string BuildSql(const std::string& table, const std::string& statement, @@ -133,7 +151,10 @@ private: VBuckets ExtractExtend(VBuckets& values) const; size_t SqlConcatenate(VBucket &value, std::string &strColumnSql, std::string &strRowValueSql); bool IsPrintLog(DistributedDB::DBStatus status); - + std::shared_ptr GetRdbCloud() const; + bool IsFinished(uint64_t syncId) const; + void RemoveTasks(); + ObserverProxy observer_; RdbManager manager_; RdbDelegate *delegate_ = nullptr; @@ -144,7 +165,7 @@ private: std::atomic isBound_ = false; std::mutex mutex_; int32_t ref_ = 1; - mutable std::shared_mutex rwMutex_; + mutable std::shared_timed_mutex rwMutex_; BindAssets snapshots_; DistributedData::StoreInfo storeInfo_; @@ -153,7 +174,15 @@ private: static constexpr uint32_t PRINT_ERROR_CNT = 150; uint32_t lastErrCnt_ = 0; uint32_t syncNotifyFlag_ = 0; - std::atomic syncTaskId_ = 0; + std::atomic syncTaskId_ = 0; + std::shared_mutex asyncMutex_ {}; + mutable std::shared_mutex rdbCloudMutex_; + struct FinishTask { + TaskId taskId = Executor::INVALID_TASK_ID; + DBProcessCB cb = nullptr; + }; + std::shared_ptr executor_ = nullptr; + std::shared_ptr> tasks_; }; } // namespace OHOS::DistributedRdb -#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp b/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp index 8fd00e9cd1938c055dc3e85b08539286573cdc14..a4eeac395df9db33d2276809090f9b649bf62da4 100644 --- a/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp @@ -330,16 +330,6 @@ int RdbResultSetImpl::GetAssets(int32_t col, NativeRdb::ValueObject::Assets& val } return Get(col, value); } - -int RdbResultSetImpl::GetFloat32Array(int32_t index, NativeRdb::ValueObject::FloatVector& vecs) -{ - std::shared_lock lock(mutex_); - if (resultSet_ == nullptr) { - return NativeRdb::E_ALREADY_CLOSED; - } - return NativeRdb::E_NOT_SUPPORT; -} - int RdbResultSetImpl::Get(int32_t col, NativeRdb::ValueObject& value) { std::shared_lock lock(mutex_); diff --git a/services/distributeddataservice/service/rdb/rdb_result_set_impl.h b/services/distributeddataservice/service/rdb/rdb_result_set_impl.h index 49d0c9fe2941c7691f75a346e42135568d28d4ca..934a42b92d31d9acc7a87d256c507129c65b960e 100644 --- a/services/distributeddataservice/service/rdb/rdb_result_set_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_result_set_impl.h @@ -58,7 +58,6 @@ public: int Close() override; int GetAsset(int32_t col, NativeRdb::ValueObject::Asset& value) override; int GetAssets(int32_t col, NativeRdb::ValueObject::Assets& value) override; - int GetFloat32Array(int32_t index, NativeRdb::ValueObject::FloatVector& vecs) override; int Get(int32_t col, NativeRdb::ValueObject& value) override; int GetRow(NativeRdb::RowEntity& rowEntity) override; int GetSize(int columnIndex, size_t& size) override; diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index 0653a48bbd33d496badd16d06a9686e1178f89d7..f2d4df36c02ee2e7be62e317a95bda1169726594 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -14,17 +14,20 @@ */ #define LOG_TAG "RdbServiceImpl" #include "rdb_service_impl.h" + +#include "abs_rdb_predicates.h" #include "accesstoken_kit.h" #include "account/account_delegate.h" -#include "checker/checker_manager.h" -#include "abs_rdb_predicates.h" #include "changeevent/remote_change_event.h" +#include "checker/checker_manager.h" #include "cloud/change_event.h" +#include "cloud/cloud_lock_event.h" #include "cloud/cloud_share_event.h" #include "cloud/make_query_event.h" -#include "commonevent/data_change_event.h" +#include "cloud/schema_meta.h" #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" +#include "device_matrix.h" #include "directory/directory_manager.h" #include "dump/dump_manager.h" #include "eventcenter/event_center.h" @@ -32,23 +35,22 @@ #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/auto_launch_meta_data.h" +#include "metadata/capability_meta_data.h" #include "metadata/meta_data_manager.h" +#include "metadata/store_debug_info.h" #include "metadata/store_meta_data.h" -#include "rdb_watcher.h" +#include "rdb_general_store.h" #include "rdb_notifier_proxy.h" #include "rdb_query.h" +#include "rdb_result_set_impl.h" +#include "rdb_watcher.h" #include "store/general_store.h" #include "tokenid_kit.h" #include "types_export.h" #include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" -#include "cloud/schema_meta.h" -#include "rdb_general_store.h" -#include "rdb_result_set_impl.h" #include "xcollie.h" -#include "device_matrix.h" -#include "metadata/capability_meta_data.h" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; @@ -118,6 +120,7 @@ RdbServiceImpl::RdbServiceImpl() store->RegisterDetailProgressObserver(GetCallbacks(meta.tokenId, storeInfo.storeName)); }; EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); + EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process); EventCenter::GetInstance().Subscribe(CloudEvent::MAKE_QUERY, [](const Event& event) { auto& evt = static_cast(event); @@ -156,7 +159,7 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib } auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier( - entry.user, entry.appId, entry.storeId); + "", entry.appId, entry.storeId, true); ZLOGD("%{public}s %{public}s %{public}s", entry.user.c_str(), entry.appId.c_str(), Anonymous::Change(entry.storeId).c_str()); if (aIdentifier != identifier) { @@ -172,7 +175,7 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib if (entry.isEncrypt) { param.option.iterateTimes = ITERATE_TIMES; param.option.cipher = DistributedDB::CipherType::AES_256_GCM; - GetPassword(entry, param.option.passwd); + GetDBPassword(entry, param.option.passwd); } AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId)); return true; @@ -206,6 +209,7 @@ int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const } AutoCache::GetInstance().Enable(tokenId); } + heartbeatTaskIds_.Erase(pid); return E_OK; } @@ -216,10 +220,6 @@ bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::strin storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); storeInfo.bundleName = bundleName; storeInfo.storeId = RemoveSuffix(storeName); - auto [instanceId, user] = GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName); - if (instanceId != 0) { - return false; - } return !CheckerManager::GetInstance().GetAppId(storeInfo).empty(); } @@ -274,13 +274,18 @@ std::shared_ptr RdbServiceImpl::GetStore(const Rd } int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, - const std::vector &references, int32_t type) + const std::vector &references, bool isRebuild, int32_t type) { if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } + if (type == DistributedRdb::DistributedTableType::DISTRIBUTED_SEARCH) { + DistributedData::SetSearchableEvent::EventInfo eventInfo; + eventInfo.isRebuild = isRebuild; + return PostSearchEvent(CloudEvent::SET_SEARCH_TRIGGER, param, eventInfo); + } auto meta = GetStoreMetaData(param); if (type == DistributedRdb::DistributedTableType::DISTRIBUTED_DEVICE) { @@ -456,7 +461,7 @@ int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option [this, tokenId, pid, seqNum = option.seqNum](const GenDetails &result) mutable { OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result)); }, - syncParam); + syncParam).first; } bool RdbServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids) @@ -477,6 +482,11 @@ bool RdbServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector isAfterMeta = true; break; } + auto [existLocal, localMask] = DeviceMatrix::GetInstance().GetMask(uuid); + if ((localMask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } } return isAfterMeta; } @@ -673,9 +683,12 @@ int32_t RdbServiceImpl::Delete(const RdbSyncerParam ¶m) auto storeMeta = GetStoreMetaData(tmpParam); MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey()); MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(storeMeta.GetStrategyKey()); - MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetDebugInfoKey(), true); return RDB_OK; } @@ -747,6 +760,7 @@ void RdbServiceImpl::SetReturnParam(StoreMetaData &metadata, RdbSyncerParam &par param.isEncrypt_ = metadata.isEncrypt; param.isAutoClean_ = !metadata.isManualClean; param.isSearchable_ = metadata.isSearchable; + param.haMode_ = metadata.haMode; } int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) @@ -777,6 +791,9 @@ int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) EventCenter::GetInstance().PostEvent(std::move(evt)); } } + + SaveDebugInfo(meta, param); + AppIDMetaData appIdMeta; appIdMeta.bundleName = meta.bundleName; appIdMeta.appId = meta.appId; @@ -841,6 +858,7 @@ StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m) metaData.isEncrypt = param.isEncrypt_; metaData.isManualClean = !param.isAutoClean_; metaData.isSearchable = param.isSearchable_; + metaData.haMode = param.haMode_; return metaData; } @@ -887,7 +905,7 @@ Details RdbServiceImpl::HandleGenDetails(const GenDetails &details) return dbDetails; } -bool RdbServiceImpl::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) +bool RdbServiceImpl::GetDBPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) { if (!metaData.isEncrypt) { return true; @@ -1046,7 +1064,7 @@ RdbServiceImpl::~RdbServiceImpl() } int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, - uint32_t delay) + const RdbNotifyConfig &rdbNotifyConfig) { XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (!CheckAccess(param.bundleName_, param.storeName_)) { @@ -1064,42 +1082,84 @@ int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbC storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; DataChangeEvent::EventInfo eventInfo; + eventInfo.isFull = rdbNotifyConfig.isFull_; for (const auto& [key, value] : rdbChangedData.tableData) { DataChangeEvent::TableChangeProperties tableChangeProperties = {value.isTrackedDataChange}; eventInfo.tableProperties.insert_or_assign(key, std::move(tableChangeProperties)); } + if (IsPostImmediately(IPCSkeleton::GetCallingPid(), rdbNotifyConfig, storeInfo, eventInfo, param.storeName_)) { + auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo)); + EventCenter::GetInstance().PostEvent(std::move(evt)); + } + + return RDB_OK; +} + +bool RdbServiceImpl::IsPostImmediately(const int32_t callingPid, const RdbNotifyConfig &rdbNotifyConfig, + StoreInfo &storeInfo, DataChangeEvent::EventInfo &eventInfo, const std::string &storeName) +{ bool postImmediately = false; - heartbeatTaskIds_.Compute(param.storeName_, - [this, &postImmediately, delay, storeInfo, eventInfo] (const std::string &key, ExecutorPool::TaskId &value) { - if (delay == 0) { - if (value != ExecutorPool::INVALID_TASK_ID && executors_ != nullptr) { - executors_->Remove(value); + heartbeatTaskIds_.Compute(callingPid, [this, &postImmediately, &rdbNotifyConfig, &storeInfo, &eventInfo, + &storeName](const int32_t &key, std::map &tasks) { + auto iter = tasks.find(storeName); + ExecutorPool::TaskId taskId = ExecutorPool::INVALID_TASK_ID; + if (iter != tasks.end()) { + taskId = iter->second; + } + if (rdbNotifyConfig.delay_ == 0) { + if (taskId != ExecutorPool::INVALID_TASK_ID && executors_ != nullptr) { + executors_->Remove(taskId); } postImmediately = true; - return false; + tasks.erase(storeName); + return !tasks.empty(); } if (executors_ != nullptr) { - auto task = [storeInfoInner = storeInfo, eventInfoInner = eventInfo]() -> int { + auto task = [storeInfoInner = storeInfo, eventInfoInner = eventInfo]() { auto evt = std::make_unique(std::move(storeInfoInner), std::move(eventInfoInner)); EventCenter::GetInstance().PostEvent(std::move(evt)); - return RDB_OK; }; - if (value == ExecutorPool::INVALID_TASK_ID) { - value = executors_->Schedule(std::chrono::milliseconds(delay), task); + if (taskId == ExecutorPool::INVALID_TASK_ID) { + taskId = executors_->Schedule(std::chrono::milliseconds(rdbNotifyConfig.delay_), task); } else { - value = executors_->Reset(value, std::chrono::milliseconds(delay)); + taskId = executors_->Reset(taskId, std::chrono::milliseconds(rdbNotifyConfig.delay_)); } } + tasks.insert_or_assign(storeName, taskId); return true; }); + return postImmediately; +} - if (postImmediately) { - auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo)); - EventCenter::GetInstance().PostEvent(std::move(evt)); +int32_t RdbServiceImpl::SetSearchable(const RdbSyncerParam& param, bool isSearchable) +{ + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; } + SetSearchableEvent::EventInfo eventInfo; + eventInfo.isSearchable = isSearchable; + return PostSearchEvent(CloudEvent::SET_SEARCHABLE, param, eventInfo); +} +int32_t RdbServiceImpl::PostSearchEvent(int32_t evtId, const RdbSyncerParam& param, + SetSearchableEvent::EventInfo &eventInfo) +{ + StoreInfo storeInfo; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.bundleName = param.bundleName_; + storeInfo.storeName = RemoveSuffix(param.storeName_); + auto [instanceId, user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_); + storeInfo.instanceId = instanceId; + storeInfo.user = user; + storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + + auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo), evtId); + EventCenter::GetInstance().PostEvent(std::move(evt)); return RDB_OK; } @@ -1108,13 +1168,140 @@ int32_t RdbServiceImpl::Disable(const RdbSyncerParam& param) auto tokenId = IPCSkeleton::GetCallingTokenID(); auto storeId = RemoveSuffix(param.storeName_); AutoCache::GetInstance().Disable(tokenId, storeId); - return E_OK; + return RDB_OK; } + int32_t RdbServiceImpl::Enable(const RdbSyncerParam& param) { auto tokenId = IPCSkeleton::GetCallingTokenID(); auto storeId = RemoveSuffix(param.storeName_); AutoCache::GetInstance().Enable(tokenId, storeId); - return E_OK; + return RDB_OK; +} + +int32_t RdbServiceImpl::GetPassword(const RdbSyncerParam ¶m, std::vector &password) +{ + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + auto meta = GetStoreMetaData(param); + SecretKeyMetaData secretKey; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKey, true)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_NO_META; + } + + if (!CryptoManager::GetInstance().Decrypt(secretKey.sKey, password)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. decrypt err", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + return RDB_OK; +} + +StoreInfo RdbServiceImpl::GetStoreInfo(const RdbSyncerParam ¶m) +{ + StoreInfo storeInfo; + storeInfo.bundleName = param.bundleName_; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId); + storeInfo.storeName = RemoveSuffix(param.storeName_); + return storeInfo; +} + +std::pair RdbServiceImpl::LockCloudContainer(const RdbSyncerParam ¶m) +{ + std::pair result { RDB_ERROR, 0 }; + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return result; + } + + auto storeInfo = GetStoreInfo(param); + + CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) { + result.first = status; + result.second = expiredTime; + }; + auto evt = std::make_unique(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), callback); + EventCenter::GetInstance().PostEvent(std::move(evt)); + return result; +} + +int32_t RdbServiceImpl::UnlockCloudContainer(const RdbSyncerParam ¶m) +{ + int32_t result = RDB_ERROR; + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return result; + } + + auto storeInfo = GetStoreInfo(param); + + CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) { + (void)expiredTime; + result = status; + }; + auto evt = std::make_unique(CloudEvent::UNLOCK_CLOUD_CONTAINER, std::move(storeInfo), callback); + EventCenter::GetInstance().PostEvent(std::move(evt)); + return result; +} + +int32_t RdbServiceImpl::GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) +{ + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + auto metaData = GetStoreMetaData(param); + auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true); + if (!isCreated) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta data", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_OK; + } + DistributedData::StoreDebugInfo debugMeta; + isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetDebugInfoKey(), debugMeta, true); + if (!isCreated) { + return RDB_OK; + } + + for (auto &[name, fileDebug] : debugMeta.fileInfos) { + RdbDebugInfo rdbInfo; + rdbInfo.inode_ = fileDebug.inode; + rdbInfo.size_ = fileDebug.size; + rdbInfo.dev_ = fileDebug.dev; + rdbInfo.mode_ = fileDebug.mode; + rdbInfo.uid_ = fileDebug.uid; + rdbInfo.gid_ = fileDebug.gid; + debugInfo.insert(std::pair{ name, rdbInfo }); + } + return RDB_OK; +} + +int32_t RdbServiceImpl::SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam ¶m) +{ + if (param.infos_.empty()) { + return RDB_OK; + } + DistributedData::StoreDebugInfo debugMeta; + for (auto &[name, info] : param.infos_) { + DistributedData::StoreDebugInfo::FileInfo fileInfo; + fileInfo.inode = info.inode_; + fileInfo.size = info.size_; + fileInfo.dev = info.dev_; + fileInfo.mode = info.mode_; + fileInfo.uid = info.uid_; + fileInfo.gid = info.gid_; + debugMeta.fileInfos.insert(std::pair{name, fileInfo}); + } + MetaDataManager::GetInstance().SaveMeta(metaData.GetDebugInfoKey(), debugMeta, true); + return RDB_OK; } } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.h b/services/distributeddataservice/service/rdb/rdb_service_impl.h index 6aafb2f4480c628a037b2a849f55b41c78a13d4f..e4a86fb3ac1b7ebd75a337e7c2961e700648ee63 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -22,6 +22,8 @@ #include #include #include "cloud/cloud_event.h" +#include "commonevent/data_change_event.h" +#include "commonevent/set_searchable_event.h" #include "concurrent_map.h" #include "feature/static_acts.h" #include "metadata/secret_key_meta_data.h" @@ -53,7 +55,7 @@ public: int32_t InitNotifier(const RdbSyncerParam ¶m, sptr notifier) override; int32_t SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, - const std::vector &references, int32_t type = DISTRIBUTED_DEVICE) override; + const std::vector &references, bool isRebuild, int32_t type = DISTRIBUTED_DEVICE) override; std::pair> RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs) override; @@ -86,7 +88,8 @@ public: int32_t OnInitialize() override; int32_t NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, - uint32_t delay = 0) override; + const RdbNotifyConfig &rdbNotifyConfig) override; + int32_t SetSearchable(const RdbSyncerParam& param, bool isSearchable) override; int32_t Disable(const RdbSyncerParam& param) override; int32_t Enable(const RdbSyncerParam& param) override; @@ -94,6 +97,14 @@ public: int32_t AfterOpen(const RdbSyncerParam ¶m) override; + int32_t GetPassword(const RdbSyncerParam ¶m, std::vector &password) override; + + std::pair LockCloudContainer(const RdbSyncerParam ¶m) override; + + int32_t UnlockCloudContainer(const RdbSyncerParam ¶m) override; + + int32_t GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) override; + private: using Watchers = DistributedData::AutoCache::Watchers; using StaticActs = DistributedData::StaticActs; @@ -177,7 +188,7 @@ private: static std::pair GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName); - static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); + static bool GetDBPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); void GetCloudSchema(const RdbSyncerParam ¶m); @@ -187,10 +198,20 @@ private: SyncResult ProcessResult(const std::map &results); + StoreInfo GetStoreInfo(const RdbSyncerParam ¶m); + + int32_t SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam ¶m); + + int32_t PostSearchEvent(int32_t evtId, const RdbSyncerParam& param, + DistributedData::SetSearchableEvent::EventInfo &eventInfo); + + bool IsPostImmediately(const int32_t callingPid, const RdbNotifyConfig &rdbNotifyConfig, StoreInfo &storeInfo, + DistributedData::DataChangeEvent::EventInfo &eventInfo, const std::string &storeName); + static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; - ConcurrentMap heartbeatTaskIds_; + ConcurrentMap> heartbeatTaskIds_; }; } // namespace OHOS::DistributedRdb #endif \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 29129f260e0aff905fe7e9467f3e4ac02036702c..8d7713811c45b0790dd0867cd825ae41d8a0dbca 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -111,13 +111,14 @@ int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, Messag std::vector tables; std::vector references; int32_t type; - if (!ITypesUtil::Unmarshal(data, param, tables, references, type)) { + bool isRebuild; + if (!ITypesUtil::Unmarshal(data, param, tables, references, type, isRebuild)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables size:%{public}zu type:%{public}d", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), tables.size(), type); return IPC_STUB_INVALID_DATA_ERR; } - auto status = SetDistributedTables(param, tables, references, type); + auto status = SetDistributedTables(param, tables, references, isRebuild, type); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -186,7 +187,7 @@ int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel { RdbSyncerParam param; SubscribeOption option; - if (!ITypesUtil::Unmarshal(data, param)) { + if (!ITypesUtil::Unmarshal(data, param, option)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; @@ -284,14 +285,32 @@ int32_t RdbServiceStub::OnRemoteNotifyDataChange(MessageParcel &data, MessagePar { RdbSyncerParam param; RdbChangedData rdbChangedData; - uint32_t delay = 0; - if (!ITypesUtil::Unmarshal(data, param, rdbChangedData, delay)) { + RdbNotifyConfig rdbNotifyConfig; + if (!ITypesUtil::Unmarshal(data, param, rdbChangedData, rdbNotifyConfig)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s ", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = NotifyDataChange(param, rdbChangedData, rdbNotifyConfig); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteSetSearchable(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + bool isSearchable = true; + if (!ITypesUtil::Unmarshal(data, param, isSearchable)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s ", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - auto status = NotifyDataChange(param, rdbChangedData, delay); + auto status = SetSearchable(param, isSearchable); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -352,4 +371,69 @@ int32_t RdbServiceStub::OnEnable(MessageParcel& data, MessageParcel& reply) } return RDB_OK; } + +int32_t RdbServiceStub::OnGetPassword(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + std::vector key; + auto status = GetPassword(param, key); + if (!ITypesUtil::Marshal(reply, status, key)) { + key.assign(key.size(), 0); + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + key.assign(key.size(), 0); + return RDB_OK; +} + +int32_t RdbServiceStub::OnLockCloudContainer(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + uint32_t expiredTime = 0; + if (!ITypesUtil::Unmarshal(data, param, expiredTime)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto result = LockCloudContainer(param); + return ITypesUtil::Marshal(reply, result.first, result.second) ? RDB_OK : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t RdbServiceStub::OnUnlockCloudContainer(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = UnlockCloudContainer(param); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} + +int32_t RdbServiceStub::OnGetDebugInfo(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + std::map debugInfo; + auto status = GetDebugInfo(param, debugInfo); + if (!ITypesUtil::Marshal(reply, status, debugInfo)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.h b/services/distributeddataservice/service/rdb/rdb_service_stub.h index eef8b94d62d833c8143aa73ebe154619751be247..eb506e8550e6dfe0f5519eecbb76959d2245b19a 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_stub.h +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -56,6 +56,8 @@ private: int32_t OnRemoteNotifyDataChange(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteSetSearchable(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteQuerySharingResource(MessageParcel& data, MessageParcel& reply); int32_t OnBeforeOpen(MessageParcel& data, MessageParcel& reply); @@ -65,6 +67,14 @@ private: int32_t OnDisable(MessageParcel& data, MessageParcel& reply); int32_t OnEnable(MessageParcel& data, MessageParcel& reply); + + int32_t OnGetPassword(MessageParcel& data, MessageParcel& reply); + + int32_t OnLockCloudContainer(MessageParcel& data, MessageParcel& reply); + + int32_t OnUnlockCloudContainer(MessageParcel& data, MessageParcel& reply); + + int32_t OnGetDebugInfo(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(RdbServiceCode::RDB_SERVICE_CMD_MAX)] = { @@ -85,12 +95,20 @@ private: &RdbServiceStub::OnRemoteUnregisterDetailProgressObserver, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_NOTIFY_DATA_CHANGE)] = &RdbServiceStub::OnRemoteNotifyDataChange, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_SEARCHABLE)] = + &RdbServiceStub::OnRemoteSetSearchable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_QUERY_SHARING_RESOURCE)] = &RdbServiceStub::OnRemoteQuerySharingResource, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_DISABLE)] = &RdbServiceStub::OnDisable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_ENABLE)] = &RdbServiceStub::OnEnable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_BEFORE_OPEN)] = &RdbServiceStub::OnBeforeOpen, - [static_cast(RdbServiceCode::RDB_SERVICE_CMD_AFTER_OPEN)] = &RdbServiceStub::OnAfterOpen + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_AFTER_OPEN)] = &RdbServiceStub::OnAfterOpen, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_PASSWORD)] = &RdbServiceStub::OnGetPassword, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER)] = + &RdbServiceStub::OnLockCloudContainer, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER)] = + &RdbServiceStub::OnUnlockCloudContainer, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_DEBUG_INFO)] = &RdbServiceStub::OnGetDebugInfo }; }; } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index a9ff08a08325cba03e695971d07f3b8c5b5f5615..1168f3153b8b41afa5ff6884d66d56f9e86d467b 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -34,6 +34,7 @@ config("module_private_config") { "${data_service_path}/service/directory/include/", "${data_service_path}/service/data_share/common", "${data_service_path}/service/data_share/data", + "${data_service_path}/service/data_share/dfx", "${data_service_path}/service/data_share/strategies", "${data_service_path}/service/data_share/subscriber_managers", "${data_service_path}/service/data_share", @@ -46,6 +47,8 @@ config("module_private_config") { "${data_service_path}/service/waterversion", "${dataobject_path}/interfaces/innerkits", "${dataobject_path}/frameworks/innerkitsimpl/include", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/include/", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/common_type/include", ] @@ -76,6 +79,7 @@ ohos_unittest("CloudDataTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -129,6 +133,12 @@ ohos_unittest("CloudDataTest") { "mock:distributeddata_mock_static", "//third_party/googletest:gtest_main", ] + + cflags = [ + "-fno-access-control", # Ignore Private Member Access Control + ] + + cflags_cc = cflags } ohos_unittest("CloudTest") { @@ -461,6 +471,46 @@ ohos_unittest("RdbServiceTest") { ] } +ohos_unittest("ObjectAssetLoaderTest") { + module_out_path = module_output_path + sources = [ + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_snapshot.cpp", + "object_asset_loader_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + "${relational_store_path}/interfaces/inner_api/common_type/include", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + ohos_unittest("ObjectAssetMachineTest") { module_out_path = module_output_path sources = [ @@ -495,6 +545,123 @@ ohos_unittest("ObjectAssetMachineTest") { ] } +ohos_unittest("ObjectDmsHandlerTest") { + module_out_path = module_output_path + sources = [ + "../object/object_dms_handler.cpp", + "object_dms_handler_test.cpp", + ] + + include_dirs = [] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dmsfwk:distributed_sdk", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + +ohos_unittest("ObjectManagerTest") { + module_out_path = module_output_path + sources = [ + "${data_service_path}/service/common/value_proxy.cpp", + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_callback_proxy.cpp", + "../object/object_data_listener.cpp", + "../object/object_manager.cpp", + "../object/object_snapshot.cpp", + "mock/kv_store_nb_delegate_mock.cpp", + "object_manager_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include", + "${data_service_path}/service/common", + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + +ohos_unittest("ObjectSnapshotTest") { + module_out_path = module_output_path + sources = [ + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_snapshot.cpp", + "object_snapshot_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + "${relational_store_path}/interfaces/inner_api/common_type/include", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ohos_unittest("MetaDataTest") { module_out_path = module_output_path sources = [ @@ -600,6 +767,7 @@ ohos_unittest("WaterVersionManagerTest") { "${data_service_path}/service/backup/src/backup_manager.cpp", "${data_service_path}/service/bootstrap/src/bootstrap.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -700,6 +868,8 @@ ohos_unittest("DataShareServiceImplTest") { "${data_service_path}/service/data_share/data_share_service_stub.cpp", "${data_service_path}/service/data_share/data_share_silent_config.cpp", "${data_service_path}/service/data_share/data_share_types_util.cpp", + "${data_service_path}/service/data_share/dfx/hiview_adapter.cpp", + "${data_service_path}/service/data_share/dfx/hiview_fault_adapter.cpp", "${data_service_path}/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", "${data_service_path}/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", "${data_service_path}/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp", @@ -739,6 +909,7 @@ ohos_unittest("DataShareServiceImplTest") { ] external_deps = [ + "ability_base:base", "ability_base:want", "ability_base:zuri", "ability_runtime:dataobs_manager", @@ -835,6 +1006,37 @@ ohos_unittest("KvdbServiceImplTest") { ] } +ohos_unittest("DumpHelperTest") { + module_out_path = module_output_path + sources = [ + "${data_service_path}/service/dumper/src/dump_helper.cpp", + "dump_helper_test.cpp", + ] + + include_dirs = [ "${data_service_path}/service/dumper/include" ] + + configs = [ ":module_private_config" ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -852,10 +1054,15 @@ group("unittest") { ":DataShareServiceImplTest", ":DeviceMatrixTest", ":DirectoryManagerTest", + ":DumpHelperTest", ":KVDBGeneralStoreTest", ":KvdbServiceImplTest", ":MetaDataTest", + ":ObjectAssetLoaderTest", ":ObjectAssetMachineTest", + ":ObjectDmsHandlerTest", + ":ObjectManagerTest", + ":ObjectSnapshotTest", ":RdbResultSetImplTest", ":RdbServiceTest", ":UdmfRunTimeStoreTest", diff --git a/services/distributeddataservice/service/test/cloud_data_test.cpp b/services/distributeddataservice/service/test/cloud_data_test.cpp index 6e797c74b02b68036af57146de9e462723c066c1..c76a320199b55979985a2bca7b5554ee7d4d3faa 100644 --- a/services/distributeddataservice/service/test/cloud_data_test.cpp +++ b/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -23,9 +23,12 @@ #include "cloud/change_event.h" #include "cloud/cloud_event.h" #include "cloud/cloud_server.h" +#include "cloud/cloud_share_event.h" #include "cloud/schema_meta.h" #include "cloud_service_impl.h" #include "cloud_types.h" +#include "cloud_types_util.h" +#include "cloud_value_util.h" #include "communicator/device_manager_adapter.h" #include "device_matrix.h" #include "eventcenter/event_center.h" @@ -51,7 +54,11 @@ using namespace OHOS::Security::AccessToken; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Querykey = OHOS::CloudData::QueryKey; using CloudSyncInfo = OHOS::CloudData::CloudSyncInfo; - +using SharingCfm = OHOS::CloudData::SharingUtil::SharingCfm; +using Confirmation = OHOS::CloudData::Confirmation; +using CenterCode = OHOS::DistributedData::SharingCenter::SharingCode; +using Status = OHOS::CloudData::CloudService::Status; +using GenErr = OHOS::DistributedData::GeneralError; uint64_t g_selfTokenID = 0; void AllocHapToken(const HapPolicyParams &policy) @@ -75,6 +82,33 @@ static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store"; static constexpr const char *TEST_CLOUD_ID = "test_cloud_id"; static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1"; static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_2 = "test_cloud_database_alias_2"; +static constexpr const char *PERMISSION_CLOUDDATA_CONFIG = "ohos.permission.CLOUDDATA_CONFIG"; +static constexpr const char *PERMISSION_GET_NETWORK_INFO = "ohos.permission.GET_NETWORK_INFO"; +static constexpr const char *PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; +static constexpr const char *PERMISSION_ACCESS_SERVICE_DM = "ohos.permission.ACCESS_SERVICE_DM"; +static constexpr const char *PERMISSION_MANAGE_LOCAL_ACCOUNTS = "ohos.permission.MANAGE_LOCAL_ACCOUNTS"; +PermissionDef GetPermissionDef(const std::string &permission) +{ + PermissionDef def = { .permissionName = permission, + .bundleName = "test_cloud_bundleName", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "test_cloud_bundleName", + .descriptionId = 1 }; + return def; +} + +PermissionStateFull GetPermissionStateFull(const std::string &permission) +{ + PermissionStateFull stateFull = { .permissionName = permission, + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } }; + return stateFull; +} class CloudDataTest : public testing::Test { public: static void SetUpTestCase(void); @@ -102,6 +136,7 @@ public: virtual ~CloudServerMock() = default; static constexpr uint64_t REMAINSPACE = 1000; static constexpr uint64_t TATALSPACE = 2000; + static constexpr int32_t INVALID_USER_ID = -1; }; CloudInfo CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo) @@ -125,6 +160,14 @@ CloudInfo CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo) std::pair CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) { + if (userId == INVALID_USER_ID) { + return { E_ERROR, CloudDataTest::schemaMeta_ }; + } + + if (bundleName.empty()) { + SchemaMeta schemaMeta; + return { E_OK, schemaMeta }; + } return { E_OK, CloudDataTest::schemaMeta_ }; } @@ -196,52 +239,37 @@ void CloudDataTest::InitCloudInfo() void CloudDataTest::SetUpTestCase(void) { - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); MetaDataManager::GetInstance().SetSyncer( [](const auto &, auto) { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); }); auto cloudServerMock = new CloudServerMock(); CloudServer::RegisterCloudInstance(cloudServerMock); - HapPolicyParams policy = { .apl = APL_SYSTEM_BASIC, .domain = "test.domain", - .permList = { - { - .permissionName = "ohos.permission.CLOUDDATA_CONFIG", - .bundleName = "test_cloud_bundleName", - .grantMode = 1, - .availableLevel = APL_SYSTEM_BASIC, - .label = "label", - .labelId = 1, - .description = "test_cloud_bundleName", - .descriptionId = 1 - } - }, - .permStateList = { - { - .permissionName = "ohos.permission.CLOUDDATA_CONFIG", - .isGeneral = true, - .resDeviceID = { "local" }, - .grantStatus = { PermissionState::PERMISSION_GRANTED }, - .grantFlags = { 1 } - } - } - }; + .permList = { GetPermissionDef(PERMISSION_CLOUDDATA_CONFIG), GetPermissionDef(PERMISSION_GET_NETWORK_INFO), + GetPermissionDef(PERMISSION_DISTRIBUTED_DATASYNC), GetPermissionDef(PERMISSION_ACCESS_SERVICE_DM), + GetPermissionDef(PERMISSION_MANAGE_LOCAL_ACCOUNTS) }, + .permStateList = { GetPermissionStateFull(PERMISSION_CLOUDDATA_CONFIG), + GetPermissionStateFull(PERMISSION_GET_NETWORK_INFO), + GetPermissionStateFull(PERMISSION_DISTRIBUTED_DATASYNC), + GetPermissionStateFull(PERMISSION_ACCESS_SERVICE_DM), + GetPermissionStateFull(PERMISSION_MANAGE_LOCAL_ACCOUNTS)} }; g_selfTokenID = GetSelfTokenID(); AllocHapToken(policy); - - InitCloudInfo(); - InitMetaData(); - InitSchemaMeta(); - size_t max = 12; size_t min = 5; auto executor = std::make_shared(max, min); cloudServiceImpl_->OnBind( { "CloudDataTest", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); - Bootstrap::GetInstance().LoadCheckers(); + auto dmExecutor = std::make_shared(max, min); + DeviceManagerAdapter::GetInstance().Init(dmExecutor); + InitCloudInfo(); + InitMetaData(); + InitSchemaMeta(); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); } void CloudDataTest::TearDownTestCase() @@ -282,7 +310,8 @@ HWTEST_F(CloudDataTest, GetSchema, TestSize.Level0) StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; auto event = std::make_unique(CloudEvent::GET_SCHEMA, storeInfo); EventCenter::GetInstance().PostEvent(std::move(event)); - ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + auto ret = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true); + ASSERT_TRUE(ret); } /** @@ -455,17 +484,7 @@ HWTEST_F(CloudDataTest, QueryLastSyncInfo004, TestSize.Level0) ZLOGI("CloudDataTest QueryLastSyncInfo004 start"); auto ret = cloudServiceImpl_->DisableCloud(TEST_CLOUD_ID); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - auto rdbServiceImpl = std::make_shared(); - DistributedRdb::RdbSyncerParam param; - param.bundleName_ = TEST_CLOUD_BUNDLE; - param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; - DistributedRdb::RdbService::Option option; - option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; - option.isAutoSync = true; - option.isAsync = false; - DistributedRdb::PredicatesMemo memo; - rdbServiceImpl->Sync(param, option, memo, nullptr); + cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID); sleep(1); @@ -487,23 +506,11 @@ HWTEST_F(CloudDataTest, QueryLastSyncInfo005, TestSize.Level0) ZLOGI("CloudDataTest QueryLastSyncInfo005 start"); std::map switches; switches.emplace(TEST_CLOUD_ID, true); - auto ret = cloudServiceImpl_->EnableCloud(TEST_CLOUD_ID, switches); - EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, false); - EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - auto rdbServiceImpl = std::make_shared(); - DistributedRdb::RdbSyncerParam param; - param.bundleName_ = TEST_CLOUD_BUNDLE; - param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; - DistributedRdb::RdbService::Option option; - option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; - option.isAutoSync = true; - option.isAsync = false; - DistributedRdb::PredicatesMemo memo; - rdbServiceImpl->Sync(param, option, memo, nullptr); - + CloudInfo info; + MetaDataManager::GetInstance().LoadMeta(cloudInfo_.GetKey(), info, true); + info.apps[TEST_CLOUD_BUNDLE].cloudSwitch = false; + MetaDataManager::GetInstance().SaveMeta(info.GetKey(), info, true); + cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID); sleep(1); auto [status, result] = @@ -655,10 +662,12 @@ HWTEST_F(CloudDataTest, AllocResourceAndShare001, TestSize.Level0) HWTEST_F(CloudDataTest, SetGlobalCloudStrategy001, TestSize.Level0) { std::vector values; - const int64_t wifi = 0x01; - values.push_back(wifi); - CloudData::Strategy strategy = CloudData::STRATEGY_NETWORK; + values.push_back(CloudData::NetWorkStrategy::WIFI); + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_BUTT; auto ret = cloudServiceImpl_->SetGlobalCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + strategy = CloudData::Strategy::STRATEGY_NETWORK; + ret = cloudServiceImpl_->SetGlobalCloudStrategy(strategy, values); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); } @@ -671,10 +680,12 @@ HWTEST_F(CloudDataTest, SetGlobalCloudStrategy001, TestSize.Level0) HWTEST_F(CloudDataTest, SetCloudStrategy001, TestSize.Level0) { std::vector values; - const int64_t wifi = 0x01; - values.push_back(wifi); - CloudData::Strategy strategy = CloudData::STRATEGY_NETWORK; + values.push_back(CloudData::NetWorkStrategy::WIFI); + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_BUTT; auto ret = cloudServiceImpl_->SetCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + strategy = CloudData::Strategy::STRATEGY_NETWORK; + ret = cloudServiceImpl_->SetCloudStrategy(strategy, values); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); } @@ -686,10 +697,49 @@ HWTEST_F(CloudDataTest, SetCloudStrategy001, TestSize.Level0) */ HWTEST_F(CloudDataTest, Clean001, TestSize.Level0) { + std::map actions; + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_BUTT); + std::string id = "testId"; + std::string bundleName = "testBundleName"; + auto ret = cloudServiceImpl_->Clean(id, actions); + EXPECT_EQ(ret, CloudData::CloudService::ERROR); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::ERROR); + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_INFO); + actions.insert_or_assign(bundleName, CloudData::CloudService::Action::CLEAR_CLOUD_DATA_AND_INFO); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: Clean +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Clean002, TestSize.Level0) +{ + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true); std::map actions; actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_INFO); auto ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + StoreMetaDataLocal localMeta; + localMeta.isPublic = false; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + localMeta.isPublic = true; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + metaData_.user = "0"; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true); + metaData_.user = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId)); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true); } /** @@ -712,19 +762,53 @@ HWTEST_F(CloudDataTest, NotifyDataChange001, TestSize.Level0) */ HWTEST_F(CloudDataTest, NotifyDataChange002, TestSize.Level0) { - constexpr const int32_t userId = 100; + constexpr const int32_t invalidUserId = -1; std::string extraData; - auto ret = cloudServiceImpl_->NotifyDataChange("", extraData, userId); + auto ret = cloudServiceImpl_->NotifyDataChange("", extraData, invalidUserId); EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); - ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, userId); + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{data:test}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{\"data\":\"{\\\"accountId\\\":\\\"id\\\",\\\"bundleName\\\":\\\"test_cloud_" + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", \\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"cloud_" + "bundleName_test\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", " + "\\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); +} + +/** +* @tc.name: NotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange003, TestSize.Level0) +{ + constexpr const int32_t userId = 100; + constexpr const int32_t defaultUserId = 0; + std::string extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"test_cloud_" + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", " + "\\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"\\\\\\\"]\\\"}\"}"; + auto ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, defaultUserId); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"test_cloud_" - "bundleName\\\",\\\"containerName\\\":\\\"alias\\\", \\\"databaseScopes\\\": " + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", \\\"databaseScopes\\\": " "\\\"[\\\\\\\"private\\\\\\\", " - "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"xxx\\\\\\\",\\\\\\\"yyy\\\\\\\"," - "\\\\\\\"zzz\\\\\\\"]\\\"}\"}"; + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, userId); - EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); } /** @@ -756,5 +840,1078 @@ HWTEST_F(CloudDataTest, Offline001, TestSize.Level0) ret = cloudServiceImpl_->Offline(DeviceManagerAdapter::CLOUD_DEVICE_UUID); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); } + +/** +* @tc.name: CloudShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, CloudShare001, TestSize.Level0) +{ + ZLOGI("weisx CloudShare start"); + StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; + std::pair> result; + CloudShareEvent::Callback asyncCallback = [&result](int32_t status, std::shared_ptr cursor) { + result.first = status; + result.second = cursor; + }; + auto event = std::make_unique(storeInfo, nullptr, nullptr); + EventCenter::GetInstance().PostEvent(std::move(event)); + auto event1 = std::make_unique(storeInfo, nullptr, asyncCallback); + EventCenter::GetInstance().PostEvent(std::move(event1)); + EXPECT_EQ(result.first, GeneralError::E_ERROR); + auto rdbQuery = std::make_shared(); + auto event2 = std::make_unique(storeInfo, rdbQuery, nullptr); + EventCenter::GetInstance().PostEvent(std::move(event2)); + auto event3 = std::make_unique(storeInfo, rdbQuery, asyncCallback); + EventCenter::GetInstance().PostEvent(std::move(event3)); + EXPECT_EQ(result.first, GeneralError::E_ERROR); +} + +/** +* @tc.name: OnUserChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnUserChange001, TestSize.Level0) +{ + constexpr const uint32_t ACCOUNT_DEFAULT = 2; + constexpr const uint32_t ACCOUNT_DELETE = 3; + constexpr const uint32_t ACCOUNT_SWITCHED = 4; + constexpr const uint32_t ACCOUNT_UNLOCKED = 5; + auto ret = cloudServiceImpl_->OnUserChange(ACCOUNT_DEFAULT, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_DELETE, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_SWITCHED, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_UNLOCKED, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); +} + +/** +* @tc.name: DisableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, DisableCloud001, TestSize.Level0) +{ + auto ret = cloudServiceImpl_->DisableCloud("test"); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->DisableCloud(TEST_CLOUD_ID); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: ChangeAppSwitch +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ChangeAppSwitch, TestSize.Level0) +{ + std::string id = "testId"; + std::string bundleName = "testName"; + auto ret = cloudServiceImpl_->ChangeAppSwitch(id, bundleName, CloudData::CloudService::SWITCH_ON); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, bundleName, CloudData::CloudService::SWITCH_ON); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_OFF); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: EnableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, EnableCloud, TestSize.Level0) +{ + std::string bundleName = "testName"; + std::map switches; + switches.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_ON); + switches.insert_or_assign(bundleName, CloudData::CloudService::SWITCH_ON); + auto ret = cloudServiceImpl_->EnableCloud(TEST_CLOUD_ID, switches); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: OnEnableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnEnableCloud, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ENABLE_CLOUD, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string id = "testId"; + std::map switches; + ITypesUtil::Marshal(data, id, switches); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ENABLE_CLOUD, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnDisableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnDisableCloud, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_DISABLE_CLOUD, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_DISABLE_CLOUD, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangeAppSwitch +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangeAppSwitch, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_APP_SWITCH, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteInt32(CloudData::CloudService::SWITCH_ON); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_APP_SWITCH, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnClean +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnClean, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CLEAN, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string id = TEST_CLOUD_ID; + std::map actions; + ITypesUtil::Marshal(data, id, actions); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CLEAN, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnNotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnNotifyDataChange, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnNotifyChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnNotifyChange, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE_EXT, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + int32_t userId = 100; + data.WriteInt32(userId); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE_EXT, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryStatistics +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryStatistics, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_STATISTICS, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteString(TEST_CLOUD_STORE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_STATISTICS, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryLastSyncInfo +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryLastSyncInfo, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_LAST_SYNC_INFO, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteString(TEST_CLOUD_STORE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_LAST_SYNC_INFO, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnSetGlobalCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnSetGlobalCloudStrategy, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = + cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_GLOBAL_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + uint32_t strategy = 0; + std::vector values; + ITypesUtil::Marshal(data, strategy, values); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_GLOBAL_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnAllocResourceAndShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnAllocResourceAndShare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ALLOC_RESOURCE_AND_SHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string storeId = "storeId"; + DistributedRdb::PredicatesMemo predicates; + std::vector columns; + std::vector participants; + ITypesUtil::Marshal(data, storeId, predicates, columns, participants); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ALLOC_RESOURCE_AND_SHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnShare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnUnshare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnUnshare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_UNSHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_UNSHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnExit +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnExit, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_EXIT, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + std::pair result; + ITypesUtil::Marshal(data, sharingRes, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_EXIT, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangePrivilege +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangePrivilege, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_PRIVILEGE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_PRIVILEGE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQuery +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQuery, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::QueryResults results; + ITypesUtil::Marshal(data, sharingRes, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryByInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryByInvitation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_BY_INVITATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string invitation; + CloudData::QueryResults results; + ITypesUtil::Marshal(data, invitation, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_BY_INVITATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnConfirmInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnConfirmInvitation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CONFIRM_INVITATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string invitation; + int32_t confirmation = 0; + std::tuple result; + ITypesUtil::Marshal(data, invitation, confirmation, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CONFIRM_INVITATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangeConfirmation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangeConfirmation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_CONFIRMATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + int32_t confirmation = 0; + std::pair result; + ITypesUtil::Marshal(data, sharingRes, confirmation, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_CONFIRMATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnSetCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnSetCloudStrategy, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + uint32_t strategy = 0; + std::vector values; + ITypesUtil::Marshal(data, strategy, values); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: SharingUtil001 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil001, TestSize.Level0) +{ + auto cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_UNKNOWN); + EXPECT_EQ(cfm, SharingCfm::CFM_UNKNOWN); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_ACCEPTED); + EXPECT_EQ(cfm, SharingCfm::CFM_ACCEPTED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_REJECTED); + EXPECT_EQ(cfm, SharingCfm::CFM_REJECTED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_SUSPENDED); + EXPECT_EQ(cfm, SharingCfm::CFM_SUSPENDED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_UNAVAILABLE); + EXPECT_EQ(cfm, SharingCfm::CFM_UNAVAILABLE); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_BUTT); + EXPECT_EQ(cfm, SharingCfm::CFM_UNKNOWN); +} + +/** +* @tc.name: SharingUtil002 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil002, TestSize.Level0) +{ + auto cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_UNKNOWN); + EXPECT_EQ(cfm, Confirmation::CFM_UNKNOWN); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_ACCEPTED); + EXPECT_EQ(cfm, Confirmation::CFM_ACCEPTED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_REJECTED); + EXPECT_EQ(cfm, Confirmation::CFM_REJECTED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_SUSPENDED); + EXPECT_EQ(cfm, Confirmation::CFM_SUSPENDED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_UNAVAILABLE); + EXPECT_EQ(cfm, Confirmation::CFM_UNAVAILABLE); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_BUTT); + EXPECT_EQ(cfm, Confirmation::CFM_UNKNOWN); +} + +/** +* @tc.name: SharingUtil003 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil003, TestSize.Level0) +{ + auto status = CloudData::SharingUtil::Convert(CenterCode::IPC_ERROR); + EXPECT_EQ(status, Status::IPC_ERROR); + status = CloudData::SharingUtil::Convert(CenterCode::NOT_SUPPORT); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: SharingUtil004 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil004, TestSize.Level0) +{ + auto status = CloudData::SharingUtil::Convert(GenErr::E_OK); + EXPECT_EQ(status, Status::SUCCESS); + status = CloudData::SharingUtil::Convert(GenErr::E_ERROR); + EXPECT_EQ(status, Status::ERROR); + status = CloudData::SharingUtil::Convert(GenErr::E_INVALID_ARGS); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + status = CloudData::SharingUtil::Convert(GenErr::E_BLOCKED_BY_NETWORK_STRATEGY); + EXPECT_EQ(status, Status::STRATEGY_BLOCKING); + status = CloudData::SharingUtil::Convert(GenErr::E_CLOUD_DISABLED); + EXPECT_EQ(status, Status::CLOUD_DISABLE); + status = CloudData::SharingUtil::Convert(GenErr::E_NETWORK_ERROR); + EXPECT_EQ(status, Status::NETWORK_ERROR); + status = CloudData::SharingUtil::Convert(GenErr::E_BUSY); + EXPECT_EQ(status, Status::ERROR); +} + +/** +* @tc.name: DoCloudSync +* @tc.desc: Test the executor_ uninitialized and initialized scenarios +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, DoCloudSync, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager sync; + CloudData::SyncManager::SyncInfo info(user); + auto ret = sync.DoCloudSync(info); + EXPECT_EQ(ret, GenErr::E_NOT_INIT); + ret = sync.StopCloudSync(user); + EXPECT_EQ(ret, GenErr::E_NOT_INIT); + size_t max = 12; + size_t min = 5; + sync.executor_ = std::make_shared(max, min); + ret = sync.DoCloudSync(info); + EXPECT_EQ(ret, GenErr::E_OK); + int32_t invalidUser = -1; + sync.StopCloudSync(invalidUser); + ret = sync.StopCloudSync(user); + EXPECT_EQ(ret, GenErr::E_OK); +} + +/** +* @tc.name: GetPostEventTask +* @tc.desc: Test the interface to verify the package name and table name +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetPostEventTask, TestSize.Level0) +{ + std::vector schemas; + schemaMeta_.databases[0].name = "test"; + schemas.push_back(schemaMeta_); + schemaMeta_.bundleName = "test"; + schemas.push_back(schemaMeta_); + + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + std::vector value; + info.tables_.insert_or_assign(TEST_CLOUD_STORE, value); + + CloudData::SyncManager sync; + std::map traceIds; + auto task = sync.GetPostEventTask(schemas, cloudInfo_, info, true, traceIds); + task(); + EXPECT_TRUE(sync.lastSyncInfos_.Empty()); +} + +/** +* @tc.name: GetRetryer +* @tc.desc: Test the input parameters of different interfaces +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetRetryer, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + CloudData::SyncManager sync; + CloudData::SyncManager::Duration duration; + std::string prepareTraceId; + auto ret = sync.GetRetryer(CloudData::SyncManager::RETRY_TIMES, info, user)(duration, E_OK, E_OK, prepareTraceId); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(CloudData::SyncManager::RETRY_TIMES, info, user)(duration, E_SYNC_TASK_MERGED, + E_SYNC_TASK_MERGED, prepareTraceId); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(0, info, user)(duration, E_OK, E_OK, prepareTraceId); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(0, info, user)(duration, E_SYNC_TASK_MERGED, E_SYNC_TASK_MERGED, prepareTraceId); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: GetCallback +* @tc.desc: Test the processing logic of different progress callbacks +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCallback, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + CloudData::SyncManager sync; + DistributedData::GenDetails result; + StoreInfo storeInfo; + storeInfo.user = user; + storeInfo.bundleName = "testBundleName"; + int32_t triggerMode = MODE_DEFAULT; + std::string prepareTraceId; + GenAsync async = nullptr; + sync.GetCallback(async, storeInfo, triggerMode, prepareTraceId, user)(result); + int32_t process = 0; + async = [&process](const GenDetails &details) { process = details.begin()->second.progress; }; + GenProgressDetail detail; + detail.progress = GenProgress::SYNC_IN_PROGRESS; + result.insert_or_assign("test", detail); + sync.GetCallback(async, storeInfo, triggerMode, prepareTraceId, user)(result); + EXPECT_EQ(process, GenProgress::SYNC_IN_PROGRESS); + detail.progress = GenProgress::SYNC_FINISH; + result.insert_or_assign("test", detail); + storeInfo.user = -1; + sync.GetCallback(async, storeInfo, triggerMode, prepareTraceId, user)(result); + storeInfo.user = user; + sync.GetCallback(async, storeInfo, triggerMode, prepareTraceId, user)(result); + EXPECT_EQ(process, GenProgress::SYNC_FINISH); +} + +/** +* @tc.name: GetInterval +* @tc.desc: Test the Interval transformation logic of the interface +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetInterval, TestSize.Level0) +{ + CloudData::SyncManager sync; + + auto ret = sync.GetInterval(E_LOCKED_BY_OTHERS); + EXPECT_EQ(ret, CloudData::SyncManager::LOCKED_INTERVAL); + ret = sync.GetInterval(E_BUSY); + EXPECT_EQ(ret, CloudData::SyncManager::BUSY_INTERVAL); + ret = sync.GetInterval(E_OK); + EXPECT_EQ(ret, CloudData::SyncManager::RETRY_INTERVAL); +} + +/** +* @tc.name: GetCloudSyncInfo +* @tc.desc: Test get cloudInfo +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudSyncInfo, TestSize.Level0) +{ + CloudData::SyncManager sync; + CloudInfo cloud; + cloud.user = cloudInfo_.user; + cloud.enableCloud = false; + CloudData::SyncManager::SyncInfo info(cloudInfo_.user); + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + info.bundleName_ = "test"; + auto ret = sync.GetCloudSyncInfo(info, cloud); + EXPECT_TRUE(!ret.empty()); +} + +/** +* @tc.name: RetryCallback +* @tc.desc: Test the retry logic +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, RetryCallback, TestSize.Level0) +{ + int32_t user = 100; + std::string prepareTraceId; + CloudData::SyncManager sync; + StoreInfo storeInfo; + int32_t retCode = -1; + CloudData::SyncManager::Retryer retry = [&retCode](CloudData::SyncManager::Duration interval, int32_t code, + int32_t dbCode, const std::string &prepareTraceId) { + retCode = code; + return true; + }; + DistributedData::GenDetails result; + auto task = sync.RetryCallback(storeInfo, retry, MODE_DEFAULT, prepareTraceId, user); + task(result); + GenProgressDetail detail; + detail.progress = GenProgress::SYNC_IN_PROGRESS; + detail.code = 100; + result.insert_or_assign("test", detail); + task = sync.RetryCallback(storeInfo, retry, MODE_DEFAULT, prepareTraceId, user); + task(result); + EXPECT_EQ(retCode, detail.code); +} + +/** +* @tc.name: UpdateCloudInfoFromServer +* @tc.desc: Test updating cloudinfo from the server +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, UpdateCloudInfoFromServer, TestSize.Level0) +{ + auto ret = cloudServiceImpl_->UpdateCloudInfoFromServer(cloudInfo_.user); + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: GetCloudInfo +* @tc.desc: Test get cloudInfo +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudInfo, TestSize.Level0) +{ + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + auto ret = cloudServiceImpl_->GetCloudInfo(cloudInfo_.user); + EXPECT_EQ(ret.first, CloudData::SUCCESS); +} + +/** +* @tc.name: SubTask +* @tc.desc: Test the subtask execution logic +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SubTask, TestSize.Level0) +{ + DistributedData::Subscription sub; + cloudServiceImpl_->InitSubTask(sub, 0); + MetaDataManager::GetInstance().LoadMeta(Subscription::GetKey(cloudInfo_.user), sub, true); + cloudServiceImpl_->InitSubTask(sub, 0); + int32_t userId = 0; + CloudData::CloudServiceImpl::Task task = [&userId]() { userId = cloudInfo_.user; }; + cloudServiceImpl_->GenSubTask(task, cloudInfo_.user)(); + EXPECT_EQ(userId, cloudInfo_.user); +} + +/** +* @tc.name: ConvertCursor +* @tc.desc: Test the cursor conversion logic when the ResultSet is empty and non-null +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ConvertCursor, TestSize.Level0) +{ + std::map entry; + entry.insert_or_assign("test", "entry"); + auto resultSet = std::make_shared(1, entry); + auto cursor = std::make_shared(resultSet); + auto result = cloudServiceImpl_->ConvertCursor(cursor); + EXPECT_TRUE(!result.empty()); + auto resultSet1 = std::make_shared(); + auto cursor1 = std::make_shared(resultSet1); + auto result1 = cloudServiceImpl_->ConvertCursor(cursor1); + EXPECT_TRUE(result1.empty()); +} + +/** +* @tc.name: GetDbInfoFromExtraData +* @tc.desc: Test the GetDbInfoFromExtraData function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetDbInfoFromExtraData, TestSize.Level0) +{ + SchemaMeta::Database database; + database.name = TEST_CLOUD_STORE; + database.alias = TEST_CLOUD_DATABASE_ALIAS_1; + + SchemaMeta schemaMeta; + schemaMeta.databases.push_back(database); + + SchemaMeta::Table table; + table.name = "test_cloud_table_name"; + table.alias = "test_cloud_table_alias"; + database.tables.push_back(table); + SchemaMeta::Table table1; + table1.name = "test_cloud_table_name1"; + table1.alias = "test_cloud_table_alias1"; + table1.sharedTableName = "test_share_table_name1"; + database.tables.emplace_back(table1); + + database.alias = TEST_CLOUD_DATABASE_ALIAS_2; + schemaMeta.databases.push_back(database); + + ExtraData extraData; + extraData.info.containerName = TEST_CLOUD_DATABASE_ALIAS_2; + auto result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); + + std::string tableName = "test_cloud_table_alias2"; + extraData.info.tables.emplace_back(tableName); + result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); + + std::string tableName1 = "test_cloud_table_alias1"; + extraData.info.tables.emplace_back(tableName1); + extraData.info.scopes.emplace_back(DistributedData::ExtraData::SHARED_TABLE); + result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); +} + +/** +* @tc.name: QueryTableStatistic +* @tc.desc: Test the QueryTableStatistic function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryTableStatistic, TestSize.Level0) +{ + auto store = std::make_shared(); + if (store != nullptr) { + std::map entry = { { "inserted", "TEST" }, { "updated", "TEST" }, { "normal", "TEST" } }; + store->MakeCursor(entry); + } + auto [ret, result] = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_TRUE(ret); + if (store != nullptr) { + std::map entry = { { "Test", 1 } }; + store->MakeCursor(entry); + } + std::tie(ret, result) = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_TRUE(ret); + + if (store != nullptr) { + store->cursor_ = nullptr; + } + std::tie(ret, result) = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: GetSchemaMeta +* @tc.desc: Test the GetSchemaMeta function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetSchemaMeta, TestSize.Level0) +{ + int32_t userId = 101; + int32_t instanceId = 0; + CloudInfo cloudInfo; + cloudInfo.user = userId; + cloudInfo.id = TEST_CLOUD_ID; + cloudInfo.enableCloud = true; + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + appInfo.appId = TEST_CLOUD_APPID; + appInfo.version = 1; + appInfo.cloudSwitch = true; + + cloudInfo.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo); + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + std::string bundleName = "testName"; + auto [status, meta] = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + bundleName = TEST_CLOUD_BUNDLE; + DistributedData::SchemaMeta schemeMeta; + schemeMeta.bundleName = TEST_CLOUD_BUNDLE; + schemeMeta.metaVersion = DistributedData::SchemaMeta::CURRENT_VERSION + 1; + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), schemeMeta, true); + std::tie(status, meta) = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + schemeMeta.metaVersion = DistributedData::SchemaMeta::CURRENT_VERSION; + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), schemeMeta, true); + std::tie(status, meta) = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_EQ(meta.metaVersion, DistributedData::SchemaMeta::CURRENT_VERSION); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), true); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetKey(), true); +} + +/** +* @tc.name: GetAppSchemaFromServer +* @tc.desc: Test the GetAppSchemaFromServer function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetAppSchemaFromServer, TestSize.Level0) +{ + int32_t userId = CloudServerMock::INVALID_USER_ID; + std::string bundleName; + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::NONE); + DeviceManagerAdapter::GetInstance().expireTime_ = + std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) + .count() + + 1000; + auto [status, meta] = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::NETWORK_ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SCHEMA_INVALID); + userId = 100; + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SCHEMA_INVALID); + bundleName = TEST_CLOUD_BUNDLE; + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_EQ(meta.bundleName, schemaMeta_.bundleName); +} + +/** +* @tc.name: OnAppUninstall +* @tc.desc: Test the OnAppUninstall function delete the subscription data +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnAppUninstall, TestSize.Level0) +{ + ZLOGI("weisx test OnAppUninstall 111"); + CloudData::CloudServiceImpl::CloudStatic cloudStatic; + int32_t userId = 1001; + Subscription sub; + sub.expiresTime.insert_or_assign(TEST_CLOUD_BUNDLE, 0); + MetaDataManager::GetInstance().SaveMeta(Subscription::GetKey(userId), sub, true); + CloudInfo cloudInfo; + cloudInfo.user = userId; + CloudInfo::AppInfo appInfo; + cloudInfo.apps.insert_or_assign(TEST_CLOUD_BUNDLE, appInfo); + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + int32_t index = 1; + auto ret = cloudStatic.OnAppUninstall(TEST_CLOUD_BUNDLE, userId, index); + EXPECT_EQ(ret, E_OK); + Subscription sub1; + EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(Subscription::GetKey(userId), sub1, true)); + EXPECT_EQ(sub1.expiresTime.size(), 0); +} + +/** +* @tc.name: GetCloudInfo +* @tc.desc: Test the GetCloudInfo with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudInfo001, TestSize.Level0) +{ + ZLOGI("weisx test OnAppUninstall 111"); + int32_t userId = 1000; + auto [status, cloudInfo] = cloudServiceImpl_->GetCloudInfo(userId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::NONE); + DeviceManagerAdapter::GetInstance().expireTime_ = + std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) + .count() + + 1000; + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + std::tie(status, cloudInfo) = cloudServiceImpl_->GetCloudInfo(cloudInfo_.user); + EXPECT_EQ(status, CloudData::CloudService::NETWORK_ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); +} + +/** +* @tc.name: PreShare +* @tc.desc: Test the PreShare with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, PreShare, TestSize.Level0) +{ + int32_t userId = 1000; + StoreInfo info; + info.instanceId = 0; + info.bundleName = TEST_CLOUD_BUNDLE; + info.storeName = TEST_CLOUD_BUNDLE; + info.user = userId; + StoreMetaData meta(info); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true); + DistributedRdb::RdbQuery query; + auto [status, cursor] = cloudServiceImpl_->PreShare(info, query); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: InitSubTask +* @tc.desc: Test the InitSubTask with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, InitSubTask, TestSize.Level0) +{ + uint64_t minInterval = 0; + uint64_t expire = 24 * 60 * 60 * 1000; // 24hours, ms + ExecutorPool::TaskId taskId = 100; + Subscription sub; + sub.expiresTime.insert_or_assign(TEST_CLOUD_BUNDLE, expire); + std::shared_ptr executor = std::move(cloudServiceImpl_->executor_); + cloudServiceImpl_->executor_ = nullptr; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_EQ(sub.GetMinExpireTime(), expire); + cloudServiceImpl_->executor_ = std::move(executor); + cloudServiceImpl_->subTask_ = taskId; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_NE(cloudServiceImpl_->subTask_, taskId); + cloudServiceImpl_->subTask_ = taskId; + cloudServiceImpl_->expireTime_ = 0; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_EQ(cloudServiceImpl_->subTask_, taskId); + cloudServiceImpl_->subTask_ = ExecutorPool::INVALID_TASK_ID; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_NE(cloudServiceImpl_->subTask_, ExecutorPool::INVALID_TASK_ID); +} } // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/cloud_test.cpp b/services/distributeddataservice/service/test/cloud_test.cpp index 827ba018a82572283e39f0ca712a42585006ae5c..4a773db97127f543816774b35361d7cbd9180cfc 100644 --- a/services/distributeddataservice/service/test/cloud_test.cpp +++ b/services/distributeddataservice/service/test/cloud_test.cpp @@ -43,7 +43,7 @@ std::shared_ptr CloudTest::dbStoreMock_ = std::make_sharedGetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); + auto user = defaultUser; oldInfo.user = user; EXPECT_NE(oldInfo.maxNumber, CloudInfo::DEFAULT_BATCH_NUMBER); EXPECT_NE(oldInfo.maxSize, CloudInfo::DEFAULT_BATCH_SIZE); diff --git a/services/distributeddataservice/service/test/data_share_profile_config_test.cpp b/services/distributeddataservice/service/test/data_share_profile_config_test.cpp index 68dec7aedb7ef8ee8e1854966ac2b6b761190db1..71121800e64b8384701cd6543d31b01bdf6d351e 100644 --- a/services/distributeddataservice/service/test/data_share_profile_config_test.cpp +++ b/services/distributeddataservice/service/test/data_share_profile_config_test.cpp @@ -47,18 +47,19 @@ public: HWTEST_F(DataShareProfileConfigTest, GetDbConfig, TestSize.Level1) { DataShareDbConfig dbConfig; - auto result = dbConfig.GetDbConfig("", false, "", "", 0); + DataShareDbConfig::DbConfig config {"", "", "", "", "", 0, false}; + auto result = dbConfig.GetDbConfig(config); EXPECT_EQ(std::get<0>(result), NativeRdb::E_DB_NOT_EXIST); - bool hasExtension = true; - result = dbConfig.GetDbConfig("", hasExtension, "", "", 0); + config.hasExtension = true; + result = dbConfig.GetDbConfig(config); EXPECT_EQ(std::get<0>(result), NativeRdb::E_DB_NOT_EXIST); - std::string uri = DATA_SHARE_URI; - std::string bundleName = "bundleName"; - std::string storeName = "storeName"; - int32_t userId = USER_TEST; - result = dbConfig.GetDbConfig(uri, hasExtension, bundleName, storeName, userId); + config.uri = DATA_SHARE_URI; + config.bundleName = "bundleName"; + config.storeName = "storeName"; + config.userId = USER_TEST; + result = dbConfig.GetDbConfig(config); EXPECT_NE(std::get<0>(result), DataShare::E_OK); } diff --git a/services/distributeddataservice/service/test/data_share_service_impl_test.cpp b/services/distributeddataservice/service/test/data_share_service_impl_test.cpp index bc0e48c9cdf1aef2b3edbba8b33291c7d9964722..d43d2e6700d91bb36d964a7b7ee63850072dd7a2 100644 --- a/services/distributeddataservice/service/test/data_share_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/data_share_service_impl_test.cpp @@ -94,7 +94,7 @@ void DataShareServiceImplTest::TearDown(void) /** * @tc.name: DataShareServiceImpl001 -* @tc.desc: test Insert Update Query Delete abnormal scene +* @tc.desc: test InsertEx UpdateEx Query DeleteEx abnormal scene * @tc.type: FUNC * @tc.require:SQL */ @@ -106,6 +106,47 @@ HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl001, TestSize.Level1) auto resultA = dataShareServiceImpl.EnableSilentProxy(uri, enable); EXPECT_EQ(resultA, DataShare::E_OK); + DataShare::DataShareValuesBucket valuesBucket; + std::string name0 = ""; + valuesBucket.Put("", name0); + auto [errCode, result] = dataShareServiceImpl.InsertEx(uri, "", valuesBucket); + EXPECT_EQ((errCode != 0), true); + + DataShare::DataSharePredicates predicates; + std::string selections = ""; + predicates.SetWhereClause(selections); + auto [errCode1, result1] = dataShareServiceImpl.UpdateEx(uri, "", predicates, valuesBucket); + EXPECT_EQ((errCode1 != 0), true); + + predicates.EqualTo("", ""); + std::vector columns; + int errVal = 0; + auto resQuery = dataShareServiceImpl.Query(uri, "", predicates, columns, errVal); + int resultSet = 0; + if (resQuery != nullptr) { + resQuery->GetRowCount(resultSet); + } + EXPECT_EQ(resultSet, 0); + + predicates.SetWhereClause(selections); + auto [errCode2, result2] = dataShareServiceImpl.DeleteEx(uri, "", predicates); + EXPECT_EQ((errCode2 != 0), true); +} + +/** +* @tc.name: DataShareServiceImpl002 +* @tc.desc: test Insert Update Query Delete abnormal scene +* @tc.type: FUNC +* @tc.require:SQL +*/ +HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl002, TestSize.Level1) +{ + DataShareServiceImpl dataShareServiceImpl; + std::string uri = ""; + bool enable = true; + auto resultA = dataShareServiceImpl.EnableSilentProxy(uri, enable); + EXPECT_EQ(resultA, DataShare::E_OK); + DataShare::DataShareValuesBucket valuesBucket; std::string name0 = ""; valuesBucket.Put("", name0); @@ -121,7 +162,7 @@ HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl001, TestSize.Level1) predicates.EqualTo("", ""); std::vector columns; int errCode = 0; - auto resQuery = dataShareServiceImpl.Query(uri, predicates, columns, errCode); + auto resQuery = dataShareServiceImpl.Query(uri, "", predicates, columns, errCode); int resultSet = 0; if (resQuery != nullptr) { resQuery->GetRowCount(resultSet); diff --git a/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp b/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp index fcfe4dd1752fa88fe4ddb95ce788c5f9ce3540d5..b524f0052812814c252adaa74b170118c468331e 100644 --- a/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp +++ b/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp @@ -142,7 +142,8 @@ HWTEST_F(DataShareSubscriberManagersTest, Delete, TestSize.Level1) auto context = std::make_shared(DATA_SHARE_URI_TEST); DataShare::Key key(context->uri, TEST_SUB_ID, BUNDLE_NAME_TEST); uint32_t tokenId = AccessTokenKit::GetHapTokenID(USER_TEST, BUNDLE_NAME_TEST, USER_TEST); - RdbSubscriberManager::GetInstance().Delete(tokenId); + uint32_t pid = getpid(); + RdbSubscriberManager::GetInstance().Delete(tokenId, pid); auto result = RdbSubscriberManager::GetInstance().Delete(key, tokenId); EXPECT_EQ(result, E_SUBSCRIBER_NOT_EXIST); } @@ -178,7 +179,7 @@ HWTEST_F(DataShareSubscriberManagersTest, Emit, TestSize.Level1) { auto context = std::make_shared(DATA_SHARE_URI_TEST); RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, context); - RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, TEST_SUB_ID, context); + RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, TEST_SUB_ID, BUNDLE_NAME_TEST, context); TemplateId tpltId; tpltId.subscriberId_ = TEST_SUB_ID; tpltId.bundleName_ = BUNDLE_NAME_TEST; diff --git a/services/distributeddataservice/service/test/device_matrix_test.cpp b/services/distributeddataservice/service/test/device_matrix_test.cpp index f72ffc5676763092954985f00f6124aaf9e7b5ad..914ecf9268b8ab3c83a78c5a541fa3d5542ce683 100644 --- a/services/distributeddataservice/service/test/device_matrix_test.cpp +++ b/services/distributeddataservice/service/test/device_matrix_test.cpp @@ -71,7 +71,7 @@ uint32_t DeviceMatrixTest::selfToken_ = 0; CheckerMock DeviceMatrixTest::instance_; void DeviceMatrixTest::SetUpTestCase(void) { - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); MetaDataManager::GetInstance().SetCloudSyncer([]() { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); }); diff --git a/services/distributeddataservice/service/test/dump_helper_test.cpp b/services/distributeddataservice/service/test/dump_helper_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd282d82712c8ca7d0cd6fa067dc37f33e376553 --- /dev/null +++ b/services/distributeddataservice/service/test/dump_helper_test.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "DumpHelperTest " + +#include "gtest/gtest.h" +#include "log_print.h" +#include "dump_helper.h" +#include "dump/dump_manager.h" +#include "types.h" + +using namespace OHOS; +using namespace testing; +using namespace testing::ext; +using namespace OHOS::DistributedData; +namespace OHOS::Test { +namespace DistributedDataTest { +class DumpHelperTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(); + void TearDown(){}; +}; + +void DumpHelperTest::SetUp(void) +{ + DumpManager &dumpManager = DumpManager::GetInstance(); + DumpManager::Config config; + config.dumpName = "test_dump"; + config.fullCmd = "test_full_cmd"; + config.abbrCmd = "test_abbr_cmd"; + config.countPrintf = 1; + config.infoName = "test_info"; + config.minParamsNum = 2; //minParamsNum is 2 + config.maxParamsNum = 5; //maxParamsNum is 5 + config.parentNode = "test_parent"; + config.childNode = "test_child"; + config.dumpCaption = {"test_caption1", "test_caption2"}; + + dumpManager.AddConfig("111", config); + dumpManager.GetHandler(config.infoName); + DumpManager::Config result = dumpManager.GetConfig("111"); + ASSERT_EQ(result.dumpName, config.dumpName); +} + +/** +* @tc.name: GetInstanceTest +* @tc.desc: GetInstance test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DumpHelperTest, GetInstanceTest, TestSize.Level0) +{ + DumpHelper &dumpHelper = DumpHelper::GetInstance(); + EXPECT_NE(&dumpHelper, nullptr); + + int fd = 1; + std::vector args; + EXPECT_TRUE(dumpHelper.Dump(fd, args)); + + args = {"COMMAND_A", "ARG_1", "ARG_2"}; + EXPECT_TRUE(dumpHelper.Dump(fd, args)); +} + +/** +* @tc.name: AddErrorInfoTest +* @tc.desc: AddErrorInfo test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DumpHelperTest, AddErrorInfoTest, TestSize.Level0) +{ + DumpHelper &dumpHelper = DumpHelper::GetInstance(); + EXPECT_NE(&dumpHelper, nullptr); + int32_t errorCode = 1001; + std::string errorInfo = "Test error information"; + + dumpHelper.AddErrorInfo(errorCode, errorInfo); + + const OHOS::DistributedData::DumpHelper::ErrorInfo& lastError = dumpHelper.errorInfo_.back(); + EXPECT_EQ(lastError.errorCode, errorCode); + EXPECT_EQ(lastError.errorInfo, errorInfo); +} +} // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/BUILD.gn index 5a9c822976e76a9150d975c7eba25c00473701cf..6686a1d01f9846051d975d02d513ed167b0f5c61 100644 --- a/services/distributeddataservice/service/test/fuzztest/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/BUILD.gn @@ -20,7 +20,6 @@ group("fuzztest") { deps = [ "cloudservicestub_fuzzer:fuzztest", - "customutdinstaller_fuzzer:fuzztest", "datashareservicestub_fuzzer:fuzztest", "dumphelper_fuzzer:fuzztest", "kvdbservicestub_fuzzer:fuzztest", diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn index 2007179cd6f0d852d467b542be5e1970056f20ab..4f44b6a128887890b0b18fa83a9248cd5b6ed6e4 100644 --- a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn @@ -75,6 +75,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn deleted file mode 100644 index 485c816f6e2d887c8415f4b02f10db49ab13b02c..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -##############################hydra-fuzz######################################## -import("//build/config/features.gni") -import("//build/test.gni") -import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") - -##############################fuzztest########################################## -ohos_fuzztest("CustomUtdInstallerFuzzTest") { - module_out_path = "datamgr_service/datamgr_service" - - include_dirs = [ - "${data_service_path}/service/udmf/utd", - "${udmf_path}/framework/common", - "${udmf_path}/interfaces/innerkits/common", - "${udmf_path}/interfaces/innerkits/data", - "${data_service_path}/framework/include", - "${data_service_path}/service/udmf/lifecycle", - "${data_service_path}/service/udmf/permission", - "${data_service_path}/service/udmf/preprocess", - "${data_service_path}/service/udmf/store", - "${data_service_path}/service/udmf", - "${kv_store_path}/frameworks/common", - "${kv_store_common_path}", - "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", - "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", - "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", - "${kv_store_distributeddb_path}", - "${kv_store_distributeddb_path}/include/", - "${kv_store_distributeddb_path}/interfaces/include/", - "${kv_store_distributeddb_path}/interfaces/include/relational", - "${dataobject_path}/frameworks/innerkitsimpl/include", - "${relational_store_path}/interfaces/inner_api/cloud_data/include", - "${relational_store_path}/interfaces/inner_api/rdb/include", - "${relational_store_path}/interfaces/inner_api/common_type/include", - "//third_party/json/single_include", - "${data_service_path}/framework/include", - "${data_service_path}/adapter/include/communicator", - "${data_service_path}/adapter/include/dfx", - "${data_service_path}/service/bootstrap/include", - "${device_manager_path}/interfaces/inner_kits/native_cpp/include", - "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", - "${kv_store_path}/interfaces/innerkits/distributeddata/include", - "${kv_store_path}/framework/libs/distributeddb/interfaces/include", - "${kv_store_common_path}", - "${udmf_path}/framework/common", - "${udmf_path}/interfaces/innerkits/common", - "${udmf_path}/interfaces/innerkits/data", - ] - - fuzz_config_file = - "${data_service_path}/service/test/fuzztest/customutdinstaller_fuzzer" - - cflags = [ - "-g", - "-O0", - "-Wno-unused-variable", - "-fno-omit-frame-pointer", - ] - - sources = [ - "${data_service_path}/service/udmf/utd/custom_utd_installer.cpp", - "customutdinstaller_fuzzer.cpp", - ] - - deps = [ - "${data_service_path}/adapter:distributeddata_adapter", - "${data_service_path}/adapter/utils:distributeddata_utils_static", - "${data_service_path}/framework:distributeddatasvcfwk", - "${data_service_path}/service:distributeddatasvc", - "${data_service_path}/service/udmf:udmf_server", - "${kv_store_distributeddb_path}:distributeddb", - ] - - external_deps = [ - "ability_base:zuri", - "ability_runtime:uri_permission_mgr", - "access_token:libaccesstoken_sdk", - "app_file_service:remote_file_share_native", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", - "c_utils:utils", - "hilog:libhilog", - "image_framework:image", - "ipc:ipc_core", - "kv_store:distributeddata_inner", - "kv_store:distributeddata_mgr", - "kv_store:distributeddb", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - "udmf:udmf_client", - ] -} - -############################################################################### -group("fuzztest") { - testonly = true - - deps = [ ":CustomUtdInstallerFuzzTest" ] -} -############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml deleted file mode 100644 index e3791389ecf624d1b851a1ef1a3dcdee48a38b7b..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 1000 - - 300 - - 4096 - - \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn index 310150e245ae9863c85bb5dd3dd1525808981214..32424a728d6bc55351d6ebfa45cdb1791ba57e72 100644 --- a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -27,6 +27,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/service/crypto/include", "${data_service_path}/service/data_share/common", "${data_service_path}/service/data_share/data", + "${data_service_path}/service/data_share/dfx", "${data_service_path}/service/data_share/strategies", "${data_service_path}/service/data_share/subscriber_managers", "${data_service_path}/service/data_share", @@ -75,6 +76,8 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/service/data_share/data_share_service_stub.cpp", "${data_service_path}/service/data_share/data_share_silent_config.cpp", "${data_service_path}/service/data_share/data_share_types_util.cpp", + "${data_service_path}/service/data_share/dfx/hiview_adapter.cpp", + "${data_service_path}/service/data_share/dfx/hiview_fault_adapter.cpp", "${data_service_path}/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", "${data_service_path}/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", "${data_service_path}/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp", @@ -104,6 +107,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { ] external_deps = [ + "ability_base:base", "ability_base:want", "ability_base:zuri", "ability_runtime:dataobs_manager", diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn index 6162c07f5ded64659b41844a49b5e930dc434f67..83c0d39844230f6f731274e4f10e1087b397d133 100644 --- a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -63,6 +63,7 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "${data_service_path}/service/bootstrap/src/bootstrap.cpp", "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn index 9f31030817a47d99ddde2c4f3c688d080cb9d5fe..afb0620045554200756a3a6a215764ac54c74ea3 100644 --- a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -62,6 +62,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/common/common_types_utils.cpp", "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -75,6 +76,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/object/object_asset_machine.cpp", "${data_service_path}/service/object/object_callback_proxy.cpp", "${data_service_path}/service/object/object_data_listener.cpp", + "${data_service_path}/service/object/object_dms_handler.cpp", "${data_service_path}/service/object/object_manager.cpp", "${data_service_path}/service/object/object_service_impl.cpp", "${data_service_path}/service/object/object_service_stub.cpp", @@ -104,6 +106,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", "hilog:libhilog", "hisysevent:libhisysevent", "huks:libhukssdk", diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn index f45834eef869489f2f3413fb570e03baab800d97..a6ffe6bb80601d514d992035cc5f049921cc2111 100644 --- a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -69,6 +69,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn index 2c399378cce589d21b55e9a00cef499667a97e7a..6ae8ebdf7e234df66f1a6db2afda2bfdd3402f97 100644 --- a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn @@ -56,10 +56,10 @@ ohos_fuzztest("UdmfServiceFuzzTest") { "bundle_framework:appexecfwk_core", "c_utils:utils", "hilog:libhilog", - "image_framework:image", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", + "kv_store:distributeddb", "udmf:udmf_client", ] } diff --git a/services/distributeddataservice/service/test/kvdb_general_store_test.cpp b/services/distributeddataservice/service/test/kvdb_general_store_test.cpp index 2d0a7d3d6874d719382f1f2719a40683b06f7168..ac6eceae5728e654221ef9694627fefbe5ccbc52 100644 --- a/services/distributeddataservice/service/test/kvdb_general_store_test.cpp +++ b/services/distributeddataservice/service/test/kvdb_general_store_test.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "bootstrap.h" #include "cloud/schema_meta.h" @@ -50,8 +51,8 @@ public: void SetUp(); void TearDown(); protected: - static constexpr const char *bundleName = "test_distributeddata"; - static constexpr const char *storeName = "test_service_meta"; + static constexpr const char *BUNDLE_NAME = "test_distributeddata"; + static constexpr const char *STORE_NAME = "test_service_meta"; void InitMetaData(); static std::vector Random(uint32_t len); @@ -65,15 +66,15 @@ static const uint32_t ENCRYPT_KEY_LENGTH = 48; void KVDBGeneralStoreTest::InitMetaData() { - metaData_.bundleName = bundleName; - metaData_.appId = bundleName; + metaData_.bundleName = BUNDLE_NAME; + metaData_.appId = BUNDLE_NAME; metaData_.user = "0"; metaData_.area = OHOS::DistributedKv::EL1; metaData_.instanceId = 0; metaData_.isAutoSync = true; metaData_.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; - metaData_.storeId = storeName; - metaData_.dataDir = "/data/service/el1/public/database/" + std::string(bundleName) + "/kvdb"; + metaData_.storeId = STORE_NAME; + metaData_.dataDir = "/data/service/el1/public/database/" + std::string(BUNDLE_NAME) + "/kvdb"; metaData_.securityLevel = SecurityLevel::S2; } @@ -154,7 +155,7 @@ public: HWTEST_F(KVDBGeneralStoreTest, GetDBPasswordTest_001, TestSize.Level0) { ZLOGI("GetDBPasswordTest start"); - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true)); EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(metaData_.GetSecretKey(), metaData_, true)); auto dbPassword = KVDBGeneralStore::GetDBPassword(metaData_); @@ -171,7 +172,7 @@ HWTEST_F(KVDBGeneralStoreTest, GetDBPasswordTest_001, TestSize.Level0) HWTEST_F(KVDBGeneralStoreTest, GetDBPasswordTest_002, TestSize.Level0) { ZLOGI("GetDBPasswordTest_002 start"); - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); metaData_.isEncrypt = true; EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true)); @@ -280,6 +281,29 @@ HWTEST_F(KVDBGeneralStoreTest, CloseTest, TestSize.Level0) EXPECT_EQ(ret, GeneralError::E_BUSY); } +/** +* @tc.name: Close +* @tc.desc: RdbGeneralStore Close test +* @tc.type: FUNC +* @tc.require: +* @tc.author: shaoyuanzhao +*/ +HWTEST_F(KVDBGeneralStoreTest, BusyClose, TestSize.Level0) +{ + auto store = std::make_shared(metaData_); + ASSERT_NE(store, nullptr); + std::thread thread([store]() { + std::unique_lockrwMutex_)> lock(store->rwMutex_); + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + auto ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); + thread.join(); + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_OK); +} + /** * @tc.name: SyncTest * @tc.desc: Sync. @@ -290,7 +314,7 @@ HWTEST_F(KVDBGeneralStoreTest, CloseTest, TestSize.Level0) HWTEST_F(KVDBGeneralStoreTest, SyncTest, TestSize.Level0) { ZLOGI("SyncTest start"); - mkdir(("/data/service/el1/public/database/" + std::string(bundleName)).c_str(), + mkdir(("/data/service/el1/public/database/" + std::string(BUNDLE_NAME)).c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); auto store = new (std::nothrow) KVDBGeneralStore(metaData_); ASSERT_NE(store, nullptr); @@ -303,9 +327,9 @@ HWTEST_F(KVDBGeneralStoreTest, SyncTest, TestSize.Level0) syncParam.mode = mixMode; auto ret = store->Sync( {}, query, [](const GenDetails &result) {}, syncParam); - EXPECT_NE(ret, GeneralError::E_OK); - ret = store->Close(); - EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_NE(ret.first, GeneralError::E_OK); + auto status = store->Close(); + EXPECT_EQ(status, GeneralError::E_OK); } /** @@ -386,20 +410,21 @@ HWTEST_F(KVDBGeneralStoreTest, CloudSync, TestSize.Level0) { auto store = new (std::nothrow) KVDBGeneralStore(metaData_); ASSERT_NE(store, nullptr); - store->SetEqualIdentifier(bundleName, storeName); + store->SetEqualIdentifier(BUNDLE_NAME, STORE_NAME); KvStoreNbDelegateMock mockDelegate; store->delegate_ = &mockDelegate; std::vector devices = {"device1", "device2"}; auto asyncs = [](const GenDetails &result) {}; store->storeInfo_.user = 0; auto cloudSyncMode = DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY; - store->SetEqualIdentifier(bundleName, storeName); - auto ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0); + store->SetEqualIdentifier(BUNDLE_NAME, STORE_NAME); + std::string prepareTraceId; + auto ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0, prepareTraceId); EXPECT_EQ(ret, DBStatus::OK); store->storeInfo_.user = 1; cloudSyncMode = DistributedDB::SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH; - ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0); + ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0, prepareTraceId); EXPECT_EQ(ret, DBStatus::OK); } @@ -412,7 +437,7 @@ HWTEST_F(KVDBGeneralStoreTest, CloudSync, TestSize.Level0) */ HWTEST_F(KVDBGeneralStoreTest, Sync, TestSize.Level0) { - mkdir(("/data/service/el1/public/database/" + std::string(bundleName)).c_str(), + mkdir(("/data/service/el1/public/database/" + std::string(BUNDLE_NAME)).c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); auto store = new (std::nothrow) KVDBGeneralStore(metaData_); ASSERT_NE(store, nullptr); @@ -426,43 +451,43 @@ HWTEST_F(KVDBGeneralStoreTest, Sync, TestSize.Level0) KvStoreNbDelegateMock mockDelegate; store->delegate_ = &mockDelegate; auto ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_NOT_SUPPORT); + EXPECT_EQ(ret.first, GeneralError::E_NOT_SUPPORT); GeneralStore::StoreConfig storeConfig; storeConfig.enableCloud_ = true; store->SetConfig(storeConfig); ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_EQ(ret.first, GeneralError::E_OK); syncMode = GeneralStore::SyncMode::NEARBY_END; mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + EXPECT_EQ(ret.first, GeneralError::E_INVALID_ARGS); std::vector devices = {"device1", "device2"}; syncMode = GeneralStore::SyncMode::NEARBY_SUBSCRIBE_REMOTE; mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_EQ(ret.first, GeneralError::E_OK); syncMode = GeneralStore::SyncMode::NEARBY_UNSUBSCRIBE_REMOTE; mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_EQ(ret.first, GeneralError::E_OK); syncMode = GeneralStore::SyncMode::NEARBY_PULL_PUSH; mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_EQ(ret.first, GeneralError::E_OK); syncMode = GeneralStore::SyncMode::MODE_BUTT; mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_ERROR); + EXPECT_EQ(ret.first, GeneralError::E_INVALID_ARGS); } /** @@ -544,6 +569,7 @@ HWTEST_F(KVDBGeneralStoreTest, Release, TestSize.Level0) auto ret = store->Release(); EXPECT_EQ(ret, 0); store = new (std::nothrow) KVDBGeneralStore(metaData_); + store->ref_ = 0; ret = store->Release(); EXPECT_EQ(ret, 0); store->ref_ = 2; @@ -581,7 +607,7 @@ HWTEST_F(KVDBGeneralStoreTest, ConvertStatus, TestSize.Level0) ret = store->ConvertStatus(DBStatus::CLOUD_SYNC_TASK_MERGED); EXPECT_EQ(ret, GeneralError::E_SYNC_TASK_MERGED); ret = store->ConvertStatus(DBStatus::DB_ERROR); - EXPECT_EQ(ret, GeneralError::E_ERROR); + EXPECT_EQ(ret, GeneralError::E_DB_ERROR); } /** @@ -597,7 +623,6 @@ HWTEST_F(KVDBGeneralStoreTest, GetWaterVersion, TestSize.Level0) ASSERT_NE(store, nullptr); std::string deviceId = "deviceId"; std::vector res = {}; - store->InitWaterVersion(metaData_); auto ret = store->GetWaterVersion(deviceId); EXPECT_EQ(ret, res); KvStoreNbDelegateMock mockDelegate; diff --git a/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp b/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp index 16176fadc27d982d006c5a7e837db9ad254f2dfa..0fc237b2b3953e85e9ab0021e5093e18f76b8aaa 100644 --- a/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp @@ -161,12 +161,6 @@ HWTEST_F(KvdbServiceImplTest, KvdbServiceImpl001, TestSize.Level0) SyncInfo syncInfo; status = kvdbServiceImpl_->CloudSync(appId, id1, syncInfo); EXPECT_EQ(status, Status::INVALID_ARGUMENT); - status = kvdbServiceImpl_->SyncExt(appId, id1, syncInfo); - EXPECT_EQ(status, Status::INVALID_ARGUMENT); - syncInfo.devices = {"device1", "device2"}; - syncInfo.query = "query"; - status = kvdbServiceImpl_->SyncExt(appId, id1, syncInfo); - EXPECT_EQ(status, Status::INVALID_ARGUMENT); DistributedKv::StoreConfig storeConfig; status = kvdbServiceImpl_->SetConfig(appId, id1, storeConfig); @@ -481,13 +475,9 @@ HWTEST_F(KvdbServiceImplTest, UnsubscribeTest001, TestSize.Level0) HWTEST_F(KvdbServiceImplTest, GetBackupPasswordTest001, TestSize.Level0) { ZLOGI("GetBackupPasswordTest001 start"); - Status status1 = manager.GetSingleKvStore(create, appId, storeId, kvStore); + auto status = manager.GetSingleKvStore(create, appId, storeId, kvStore); ASSERT_NE(kvStore, nullptr); - ASSERT_EQ(status1, Status::SUCCESS); - std::vector password; - auto status = kvdbServiceImpl_->GetBackupPassword(appId, storeId, password); - ZLOGI("GetBackupPasswordTest001 status = :%{public}d", status); - ASSERT_NE(status, Status::SUCCESS); + ASSERT_EQ(status, Status::SUCCESS); } /** @@ -610,7 +600,6 @@ HWTEST_F(KvdbServiceImplTest, ResolveAutoLaunch, TestSize.Level0) auto result = kvdbServiceImpl_->ResolveAutoLaunch(identifier, launchParam); EXPECT_EQ(result, Status::STORE_NOT_FOUND); std::shared_ptr executors = std::make_shared(1, 0); - Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); @@ -672,15 +661,13 @@ HWTEST_F(KvdbServiceImplTest, DoCloudSync, TestSize.Level0) ASSERT_EQ(status, Status::SUCCESS); StoreMetaData metaData; SyncInfo syncInfo; - kvdbServiceImpl_->DoCloudSync(true, true); status = kvdbServiceImpl_->DoCloudSync(metaData, syncInfo); EXPECT_EQ(status, Status::NOT_SUPPORT); syncInfo.devices = {"device1", "device2"}; syncInfo.query = "query"; metaData.enableCloud = true; - kvdbServiceImpl_->DoCloudSync(false, false); status = kvdbServiceImpl_->DoCloudSync(metaData, syncInfo); - EXPECT_EQ(status, Status::NETWORK_ERROR); + EXPECT_EQ(status, Status::CLOUD_DISABLED); } /** diff --git a/services/distributeddataservice/service/test/mock/db_store_mock.cpp b/services/distributeddataservice/service/test/mock/db_store_mock.cpp index 1d43eb96b240cec542efc64e29eb251078cf927f..d6d9c74124281790f0aa227f0635be46af52a36f 100644 --- a/services/distributeddataservice/service/test/mock/db_store_mock.cpp +++ b/services/distributeddataservice/service/test/mock/db_store_mock.cpp @@ -371,5 +371,15 @@ DBStatus DBStoreMock::GetDeviceEntries(const std::string &device, std::vector &entries) const override; DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const override; @@ -110,6 +113,8 @@ public: DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override; DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const override; + DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) override; + DBStatus CancelSync(uint32_t syncId) override; private: static const uint32_t DEFAULT_SIZE = 0; DBStatus Get(ConcurrentMap &store, const Key &key, Value &value) const; diff --git a/services/distributeddataservice/service/test/mock/general_store_mock.cpp b/services/distributeddataservice/service/test/mock/general_store_mock.cpp index dd993083db8bab4149f322a9006a7176987bc601..0b4c426ae5ecf025973bea126ff716f646a65367 100644 --- a/services/distributeddataservice/service/test/mock/general_store_mock.cpp +++ b/services/distributeddataservice/service/test/mock/general_store_mock.cpp @@ -37,8 +37,8 @@ int32_t GeneralStoreMock::SetDistributedTables( return 0; } -int32_t GeneralStoreMock::SetTrackerTable( - const std::string &tableName, const std::set &trackerColNames, const std::string &extendColName) +int32_t GeneralStoreMock::SetTrackerTable(const std::string &tableName, + const std::set &trackerColNames, const std::string &extendColName, bool isForceUpgrade) { return 0; } @@ -69,9 +69,10 @@ std::pair> GeneralStoreMock::Query(const std::s return {GeneralError::E_NOT_SUPPORT, nullptr}; } -int32_t GeneralStoreMock::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) +std::pair GeneralStoreMock::Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const SyncParam &syncParm) { - return 0; + return { GeneralError::E_OK, 0 }; } std::pair> GeneralStoreMock::PreSharing(GenQuery &query) @@ -129,6 +130,11 @@ int32_t GeneralStoreMock::MergeMigratedData(const std::string &tableName, VBucke return 0; } +int32_t GeneralStoreMock::CleanTrackerData(const std::string &tableName, int64_t cursor) +{ + return 0; +} + std::pair> GeneralStoreMock::Query(const std::string &table, const std::string &sql, Values &&args) { @@ -145,5 +151,20 @@ void GeneralStoreMock::MakeCursor(const std::map &entry) auto resultSet = std::make_shared(1, entry); cursor_ = std::make_shared(resultSet); } + +std::pair GeneralStoreMock::LockCloudDB() +{ + return { E_OK, 0 }; +} + +int32_t GeneralStoreMock::UnLockCloudDB() +{ + return E_OK; +} + +void GeneralStoreMock::SetExecutor(std::shared_ptr executor) +{ + return; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/general_store_mock.h b/services/distributeddataservice/service/test/mock/general_store_mock.h index bfc118ce47083d960f93d9b901bfaafd37c13fb4..46b94a14297dfe04d9fb070132186d0578872a05 100644 --- a/services/distributeddataservice/service/test/mock/general_store_mock.h +++ b/services/distributeddataservice/service/test/mock/general_store_mock.h @@ -28,7 +28,7 @@ public: int32_t SetDistributedTables( const std::vector &tables, int32_t type, const std::vector &references) override; int32_t SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, - const std::string &extendColName) override; + const std::string &extendColName, bool isForceUpgrade = false) override; int32_t Insert(const std::string &table, VBuckets &&values) override; int32_t Update(const std::string &table, const std::string &setSql, Values &&values, const std::string &whereSql, Values &&conditions) override; @@ -37,7 +37,8 @@ public: std::pair> Query(const std::string &table, const std::string &sql, Values &&args) override; std::pair> Query(const std::string &table, GenQuery &query) override; - int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; + std::pair Sync(const Devices &devices, GenQuery &query, DetailAsync async, + const SyncParam &syncParm) override; std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; @@ -49,8 +50,12 @@ public: int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; + int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) override; std::vector GetWaterVersion(const std::string &deviceId) override; + void SetExecutor(std::shared_ptr executor) override; void MakeCursor(const std::map &entry); + std::pair LockCloudDB() override; + int32_t UnLockCloudDB() override; private: std::shared_ptr cursor_ = nullptr; diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp index abc59d0a51935c046a5dcf838b92e2d0b9a45411..c21da743f993002536afd3945c58f821496c1fa4 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp @@ -320,4 +320,14 @@ DBStatus KvStoreNbDelegateMock::GetDeviceEntries(const std::string &device, std: { return DBStatus::OK; } + +DBStatus KvStoreNbDelegateMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::CancelSync(uint32_t syncId) +{ + return DBStatus::OK; +} } // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h index 0dac0b9ea805d35e17c554a01be8ce7a5070e96d..83d935fbf26be9904f7c7301f2343ded34541ccd 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h @@ -104,6 +104,8 @@ public: DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor); DBStatus SetCloudSyncConfig(const CloudSyncConfig &config); DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const; + DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess); + DBStatus CancelSync(uint32_t syncId); }; } // namespace DistributedDB #endif // KV_STORE_NB_DELEGATE_H_MOCK \ No newline at end of file diff --git a/services/distributeddataservice/service/test/object_asset_loader_test.cpp b/services/distributeddataservice/service/test/object_asset_loader_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab44449262ffef3f7615f91296eddeae55b9c6b1 --- /dev/null +++ b/services/distributeddataservice/service/test/object_asset_loader_test.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectAssetLoaderTest" + +#include "object_asset_loader.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using namespace OHOS::DistributedData; +namespace OHOS::Test { + +class ObjectAssetLoaderTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + Asset asset_; + std::string uri_; + int32_t userId_ = 1; + std::string bundleName_ = "test_bundleName_1"; + std::string deviceId_ = "test_deviceId__1"; +}; + +void ObjectAssetLoaderTest::SetUp() +{ + uri_ = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; +} + +void ObjectAssetLoaderTest::TearDown() {} + +/** +* @tc.name: UploadTest001 +* @tc.desc: Transfer test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UploadTest001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + auto result = assetLoader->Transfer(userId_, bundleName_, deviceId_, asset_); + ASSERT_EQ(result, false); +} + +/** +* @tc.name: TransferAssetsAsync001 +* @tc.desc: TransferAssetsAsync test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, TransferAssetsAsync001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + std::function lambdaFunc = [](bool success) { + if (success) {} + }; + std::vector assets{ asset_ }; + ASSERT_EQ(assetLoader->executors_, nullptr); + assetLoader->TransferAssetsAsync(userId_, bundleName_, deviceId_, assets, lambdaFunc); +} + +/** +* @tc.name: TransferAssetsAsync002 +* @tc.desc: TransferAssetsAsync test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, TransferAssetsAsync002, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + std::function lambdaFunc = [](bool success) { + if (success) {} + }; + std::vector assets{ asset_ }; + std::shared_ptr executors = std::make_shared(5, 3); + ASSERT_NE(executors, nullptr); + assetLoader->SetThreadPool(executors); + ASSERT_NE(assetLoader->executors_, nullptr); + assetLoader->TransferAssetsAsync(userId_, bundleName_, deviceId_, assets, lambdaFunc); +} + +/** +* @tc.name: FinishTask001 +* @tc.desc: FinishTask test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, FinishTask001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + TransferTask task; + task.downloadAssets.insert(uri_); + assetLoader->FinishTask(asset_.uri, true); + ASSERT_TRUE(assetLoader->tasks_.Empty()); + assetLoader->FinishTask(asset_.uri, false); + ASSERT_TRUE(assetLoader->tasks_.Empty()); +} + +/** +* @tc.name: IsDownloading001 +* @tc.desc: IsDownloading test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, IsDownloading001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + assetLoader->downloading_.InsertOrAssign(asset_.uri, asset_.hash); + auto result = assetLoader->IsDownloading(asset_); + ASSERT_EQ(result, true); + assetLoader->downloading_.Erase(asset_.uri); + result = assetLoader->IsDownloading(asset_); + ASSERT_EQ(result, false); +} + +/** +* @tc.name: IsDownloaded001 +* @tc.desc: IsDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, IsDownloaded001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + auto result = assetLoader->IsDownloaded(asset_); + ASSERT_EQ(result, false); + assetLoader->downloaded_.Insert(asset_.uri, "modifyTime_size"); + result = assetLoader->IsDownloaded(asset_); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: UpdateDownloaded001 +* @tc.desc: UpdateDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UpdateDownloaded001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + while (!assetLoader->assetQueue_.empty()) { + assetLoader->assetQueue_.pop(); + } + assetLoader->UpdateDownloaded(asset_); + auto [success, hash] = assetLoader->downloaded_.Find(asset_.uri); + ASSERT_TRUE(success); + EXPECT_EQ(hash, asset_.hash); +} + +/** +* @tc.name: UpdateDownloaded002 +* @tc.desc: UpdateDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UpdateDownloaded002, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + while (!assetLoader->assetQueue_.empty()) { + assetLoader->assetQueue_.pop(); + } + for (int i = 0; i <= assetLoader->LAST_DOWNLOAD_ASSET_SIZE; i++) { + assetLoader->assetQueue_.push(asset_.uri); + } + assetLoader->UpdateDownloaded(asset_); + EXPECT_NE(assetLoader->assetQueue_.size(), ObjectAssetLoader::LAST_DOWNLOAD_ASSET_SIZE); + EXPECT_EQ(assetLoader->assetQueue_.size(), ObjectAssetLoader::LAST_DOWNLOAD_ASSET_SIZE + 1); + auto [success, hash] = assetLoader->downloaded_.Find(asset_.uri); + EXPECT_EQ(success, false); + EXPECT_EQ(hash, ""); +} +} // namespace OHOS::Test diff --git a/services/distributeddataservice/service/test/object_asset_machine_test.cpp b/services/distributeddataservice/service/test/object_asset_machine_test.cpp index 969122494400b1729b915e82fd879ad839cefe48..6827a7fc4d9a6bd7fb23d4c917591ed77651abe8 100644 --- a/services/distributeddataservice/service/test/object_asset_machine_test.cpp +++ b/services/distributeddataservice/service/test/object_asset_machine_test.cpp @@ -41,6 +41,7 @@ protected: std::map changedAssets_; std::string sessionId = "123"; StoreInfo storeInfo_; + std::shared_ptr machine; }; void ObjectAssetMachineTest::SetUp() @@ -74,47 +75,24 @@ void ObjectAssetMachineTest::SetUp() storeInfo_ = storeInfo; ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); changedAssets_[uri_] = changedAssetInfo; - auto executors = std::make_shared(1, 0); - ObjectAssetLoader::GetInstance()->SetThreadPool(executors); + if (machine == nullptr) { + machine = std::make_shared(); + auto executors = std::make_shared(2, 1); + ObjectAssetLoader::GetInstance()->SetThreadPool(executors); + } } void ObjectAssetMachineTest::TearDown() {} /** * @tc.name: StatusTransfer001 -* @tc.desc: Transfer event. -* @tc.type: FUNC -* @tc.require: -* @tc.author: whj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", - }; - std::pair changedAsset{ "device_1", asset }; - changedAssets_[uri_].status = STATUS_STABLE; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); - ASSERT_EQ(changedAssets_[uri_].deviceId, changedAsset.first); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); -} - -/** -* @tc.name: StatusTransfer002 * @tc.desc: Remote changed when transferring. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) { - auto machine = std::make_shared(); Asset asset{ .name = "test_name", .uri = uri_, @@ -131,42 +109,14 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) } /** -* @tc.name: StatusTransfer003 -* @tc.desc: Compensate transfer in conflict scenario. -* @tc.type: FUNC -* @tc.require: -* @tc.author: whj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", - }; - std::pair changedAsset{ "device_1", asset }; - changedAssets_[uri_].status = STATUS_WAIT_TRANSFER; - changedAssets_[uri_].deviceId = "device_2"; - changedAssets_[uri_].asset.hash = "modifyTime2_size2"; - machine->DFAPostEvent(TRANSFER_FINISHED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); - ASSERT_EQ(changedAssets_[uri_].deviceId, "device_2"); - ASSERT_EQ(changedAssets_[uri_].asset.hash, "modifyTime2_size2"); -} - -/** -* @tc.name: StatusTransfer004 +* @tc.name: StatusTransfer002 * @tc.desc: Transfer finished. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) { - auto machine = std::make_shared(); Asset asset{ .name = "test_name", .uri = uri_, @@ -181,15 +131,14 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) } /** -* @tc.name: StatusTransfer005 +* @tc.name: StatusTransfer003 * @tc.desc: Transfer event * @tc.type: FUNC * @tc.require: * @tc.author: nhj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer005, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) { - auto machine = std::make_shared(); Asset asset{ .name = "test_name", .uri = uri_, @@ -214,7 +163,6 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer005, TestSize.Level0) */ HWTEST_F(ObjectAssetMachineTest, StatusUpload001, TestSize.Level0) { - auto machine = std::make_shared(); Asset asset{ .name = "test_name", .uri = uri_, @@ -239,24 +187,41 @@ HWTEST_F(ObjectAssetMachineTest, StatusUpload001, TestSize.Level0) */ HWTEST_F(ObjectAssetMachineTest, StatusUpload002, TestSize.Level0) { - auto machine = std::make_shared(); + auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + auto timestamp = std::to_string(time); Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", + .name = "name_" + timestamp, + .uri = "uri_" + timestamp, + .modifyTime = "modifyTime_" + timestamp, + .size = "size_" + timestamp, + .hash = "modifyTime_size_" + timestamp, }; - std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(UPLOAD, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_UPLOADING); + AssetBindInfo bindInfo{ + .storeName = "store_" + timestamp, + .tableName = "table_" + timestamp, + .primaryKey = {{ "key_" + timestamp, "value_" + timestamp }}, + .field = "attachment_" + timestamp, + .assetName = "asset_" + timestamp + ".jpg", + }; + StoreInfo storeInfo { + .tokenId = time, + .bundleName = "bundleName_" + timestamp, + .storeName = "store_" + timestamp, + .instanceId = time, + .user = time, + }; + ChangedAssetInfo changedAssetInfo(asset, bindInfo, storeInfo); + std::pair changedAsset{ "device_" + timestamp, asset }; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); + machine->DFAPostEvent(UPLOAD, changedAssetInfo, asset); + ASSERT_EQ(changedAssetInfo.status, STATUS_UPLOADING); - machine->DFAPostEvent(UPLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); + machine->DFAPostEvent(REMOTE_CHANGED, changedAssetInfo, asset, changedAsset); + ASSERT_EQ(changedAssetInfo.status, STATUS_WAIT_TRANSFER); + ASSERT_EQ(changedAssetInfo.asset.hash, asset.hash); + + machine->DFAPostEvent(UPLOAD_FINISHED, changedAssetInfo, asset); + ASSERT_EQ(changedAssetInfo.status, STATUS_TRANSFERRING); } /** @@ -268,48 +233,34 @@ HWTEST_F(ObjectAssetMachineTest, StatusUpload002, TestSize.Level0) */ HWTEST_F(ObjectAssetMachineTest, StatusDownload001, TestSize.Level0) { - auto machine = std::make_shared(); Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", + .name = "name_006", + .uri = "uri_006", + .modifyTime = "modifyTime_006", + .size = "size_006", + .hash = "modifyTime_006_size_006", }; - std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); - - machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); -} - -/** -* @tc.name: StatusDownload002 -* @tc.desc: Conflict scenario: Download before transfer. -* @tc.type: FUNC -* @tc.require: -* @tc.author: nhj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusDownload002, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", + AssetBindInfo AssetBindInfo{ + .storeName = "store_006", + .tableName = "table_006", + .primaryKey = {{ "006", "006" }}, + .field = "attachment_006", + .assetName = "asset_006.jpg", }; - std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); + StoreInfo storeInfo { + .tokenId = 600, + .bundleName = "bundleName_006", + .storeName = "store_006", + .instanceId = 600, + .user = 600, + }; + ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); + std::pair changedAsset{ "device_006", asset }; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); + machine->DFAPostEvent(DOWNLOAD, changedAssetInfo, asset, changedAsset); + ASSERT_EQ(changedAssetInfo.status, STATUS_DOWNLOADING); - machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); + machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssetInfo, asset); + ASSERT_EQ(changedAssetInfo.status, STATUS_STABLE); } } // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/object_dms_handler_test.cpp b/services/distributeddataservice/service/test/object_dms_handler_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8bc94030e4c2ddec6081f22caece8384aa8ef3d9 --- /dev/null +++ b/services/distributeddataservice/service/test/object_dms_handler_test.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectDmsHandlerTest" + +#include "object_dms_handler.h" + +#include + +#include "device_manager_adapter.h" +#include "dms_listener_stub.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +namespace OHOS::Test { +constexpr const char *PKG_NAME = "ohos.distributeddata.service"; +class ObjectDmsHandlerTest : public testing::Test { +public: + void SetUp() {} + void TearDown() {} +}; + +/** +* @tc.name: IsContinueTest_001 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, IsContinue_001, TestSize.Level0) +{ + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); + DistributedHardware::DmDeviceInfo localDeviceInfo; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo); + std::string localNetworkId = localDeviceInfo.networkId; + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = localNetworkId; + notify.dstNetworkId_ = "networkId2"; + notify.srcBundleName_ = "bundleName1"; + notify.destBundleName_ = "bundleName2"; + DmsEventListener listener; + listener.DSchedEventNotify(notify); + auto res = ObjectDmsHandler::GetInstance().IsContinue("bundleName1"); + EXPECT_TRUE(res); + res = ObjectDmsHandler::GetInstance().IsContinue("bundleName2"); + EXPECT_FALSE(res); + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} + +/** +* @tc.name: IsContinueTest_002 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, IsContinue_002, TestSize.Level0) +{ + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); + DistributedHardware::DmDeviceInfo localDeviceInfo; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo); + std::string localNetworkId = localDeviceInfo.networkId; + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = "networkId1"; + notify.dstNetworkId_ = localNetworkId; + notify.srcBundleName_ = "bundleName1"; + notify.destBundleName_ = "bundleName2"; + DmsEventListener listener; + listener.DSchedEventNotify(notify); + auto res = ObjectDmsHandler::GetInstance().IsContinue("bundleName1"); + EXPECT_FALSE(res); + res = ObjectDmsHandler::GetInstance().IsContinue("bundleName2"); + EXPECT_TRUE(res); + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} + +/** +* @tc.name: ReceiveDmsEvent_001 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, ReceiveDmsEvent_001, TestSize.Level0) +{ + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); + DmsEventListener listener; + for (int i = 0; i <= 20; i++) { + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = "srcNetworkId" + std::to_string(i); + notify.dstNetworkId_ = "dstNetworkId" + std::to_string(i); + notify.srcBundleName_ = "srcBundleName" + std::to_string(i); + notify.destBundleName_ = "destBundleName" + std::to_string(i); + ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify); + } + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.size(), 20); + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.front().first.srcNetworkId_, "srcNetworkId1"); + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.back().first.srcNetworkId_, "srcNetworkId20"); + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} + +/** +* @tc.name: GetDstBundleName_001 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, GetDstBundleName_001, TestSize.Level0) +{ + DistributedHardware::DmDeviceInfo localDeviceInfo; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo); + std::string localNetworkId = localDeviceInfo.networkId; + + std::string srcNetworkId = localNetworkId; + std::string srcBundleName = "bundleName1"; + std::string dstNetworkId = "networkId2"; + std::string destBundleName = "bundleName2"; + + auto res = ObjectDmsHandler::GetInstance().GetDstBundleName(srcBundleName, dstNetworkId); + EXPECT_EQ(res, srcBundleName); + + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = srcNetworkId; + notify.dstNetworkId_ = dstNetworkId; + notify.srcBundleName_ = srcBundleName; + notify.destBundleName_ = destBundleName; + ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify); + + res = ObjectDmsHandler::GetInstance().GetDstBundleName(srcBundleName, dstNetworkId); + EXPECT_EQ(res, destBundleName); + + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); + + auto timestamp = std::chrono::steady_clock::now() - std::chrono::seconds(20); + ObjectDmsHandler::GetInstance().dmsEvents_.push_back({notify, timestamp}); + + res = ObjectDmsHandler::GetInstance().GetDstBundleName(srcBundleName, dstNetworkId); + EXPECT_EQ(res, srcBundleName); + + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} +} // namespace OHOS::Test diff --git a/services/distributeddataservice/service/test/object_manager_test.cpp b/services/distributeddataservice/service/test/object_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fad3177ae833c95a54358a6fd38b4516d8ae7249 --- /dev/null +++ b/services/distributeddataservice/service/test/object_manager_test.cpp @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectManagerTest" + +#include "object_manager.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" +#include "object_types.h" +#include "kv_store_nb_delegate_mock.h" +#include + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using AssetValue = OHOS::CommonType::AssetValue; +using RestoreStatus = OHOS::DistributedObject::ObjectStoreManager::RestoreStatus; +namespace OHOS::Test { + +class ObjectManagerTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + Asset asset_; + std::string uri_; + std::string appId_ = "objectManagerTest_appid_1"; + std::string sessionId_ = "123"; + std::vector data_; + std::string deviceId_ = "7001005458323933328a258f413b3900"; + uint64_t sequenceId_ = 10; + uint64_t sequenceId_2 = 20; + uint64_t sequenceId_3 = 30; + std::string userId_ = "100"; + std::string bundleName_ = "com.examples.hmos.notepad"; + OHOS::ObjectStore::AssetBindInfo assetBindInfo_; + pid_t pid_ = 10; + uint32_t tokenId_ = 100; + AssetValue assetValue_; +}; + +void ObjectManagerTest::SetUp() +{ + uri_ = "file:://com.examples.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; + + AssetValue assetValue{ + .id = "test_name", + .name = uri_, + .uri = uri_, + .createTime = "2024.07.23", + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + .path = "/data/storage/el2", + }; + assetValue_ = assetValue; + + data_.push_back(10); // 10 is for testing + data_.push_back(20); // 20 is for testing + data_.push_back(30); // 30 is for testing + + OHOS::ObjectStore::AssetBindInfo AssetBindInfo{ + .storeName = "store_test", + .tableName = "table_test", + .field = "attachment", + .assetName = "asset1.jpg", + }; + assetBindInfo_ = AssetBindInfo; +} + +void ObjectManagerTest::TearDown() {} + +/** +* @tc.name: DeleteNotifier001 +* @tc.desc: DeleteNotifier test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteNotifier001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); +} + +/** +* @tc.name: Process001 +* @tc.desc: Process test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Process001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::map results; + results = {{ "test_cloud", DistributedDB::DBStatus::OK }}; + + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto result = syncManager->Process(sequenceId_, results, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + result = syncManager->Process(sequenceId_, results, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); +} + +/** +* @tc.name: DeleteNotifierNoLock001 +* @tc.desc: DeleteNotifierNoLock test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteNotifierNoLock001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + std::vector seqIds = {sequenceId_, sequenceId_2, sequenceId_3}; + std::string userId = "user_1"; + auto result = syncManager->DeleteNotifierNoLock(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); + syncManager->userIdSeqIdRelations_[userId] = seqIds; + result = syncManager->DeleteNotifierNoLock(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_IN_USE); +} + +/** +* @tc.name: Clear001 +* @tc.desc: Clear test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Clear001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + auto result = manager->Clear(); + ASSERT_EQ(result, OHOS::DistributedObject::OBJECT_STORE_NOT_FOUND); +} + +/** +* @tc.name: registerAndUnregisterRemoteCallback001 +* @tc.desc: test RegisterRemoteCallback and UnregisterRemoteCallback. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, registerAndUnregisterRemoteCallback001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + sptr callback; + manager->RegisterRemoteCallback(bundleName_, sessionId_, pid_, tokenId_, callback); + ObjectStoreManager::CallbackInfo callbackInfo = manager->callbacks_.Find(tokenId_).second; + std::string prefix = bundleName_ + sessionId_; + ASSERT_NE(callbackInfo.observers_.find(prefix), callbackInfo.observers_.end()); + manager->UnregisterRemoteCallback(bundleName_, pid_, tokenId_, sessionId_); + callbackInfo = manager->callbacks_.Find(tokenId_).second; + ASSERT_EQ(callbackInfo.observers_.find(prefix), callbackInfo.observers_.end()); +} + +/** +* @tc.name: registerAndUnregisterRemoteCallback002 +* @tc.desc: abnormal use cases. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, registerAndUnregisterRemoteCallback002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + sptr callback; + uint32_t tokenId = 101; + manager->RegisterRemoteCallback("", sessionId_, pid_, tokenId, callback); + manager->RegisterRemoteCallback(bundleName_, "", pid_, tokenId, callback); + manager->RegisterRemoteCallback("", "", pid_, tokenId, callback); + ASSERT_EQ(manager->callbacks_.Find(tokenId).first, false); + manager->UnregisterRemoteCallback("", pid_, tokenId, sessionId_); +} + +/** +* @tc.name: NotifyDataChanged001 +* @tc.desc: NotifyDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyDataChanged001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string bundleName1_ = "com.examples.ophm.notepad"; + std::string objectKey = bundleName1_ + sessionId_; + std::map>> data; + std::map> data1; + std::vector data1_; + data1_.push_back(RestoreStatus::DATA_READY); + data1_.push_back(RestoreStatus::ASSETS_READY); + data1_.push_back(RestoreStatus::ALL_READY); + data1 = {{ "objectKey", data1_ }}; + data = {{ objectKey, data1 }}; + std::shared_ptr executors = std::make_shared(5, 3); // executor pool + manager->SetThreadPool(executors); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).first, false); + manager->NotifyDataChanged(data, {}); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::DATA_READY); +} + +/** +* @tc.name: NotifyAssetsReady001 +* @tc.desc: NotifyAssetsReady test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyAssetsReady001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string objectKey = bundleName_ + sessionId_; + std::string srcNetworkId = "1"; + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).first, false); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::ASSETS_READY); + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_READY); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::ALL_READY); +} + +/** + * @tc.name: NotifyAssetsReady002 + * @tc.desc: NotifyAssetsReady test. + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, NotifyAssetsReady002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string objectKey="com.example.myapplicaiton123456"; + std::string srcNetworkId = "654321"; + + manager->restoreStatus_.Clear(); + manager->NotifyAssetsStart(objectKey, srcNetworkId); + auto [has0, value0] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has0); + EXPECT_EQ(value0, RestoreStatus::NONE); + + manager->restoreStatus_.Clear(); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has1, value1] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has1); + EXPECT_EQ(value1, RestoreStatus::ASSETS_READY); + + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_NOTIFIED); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has2, value2] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has2); + EXPECT_EQ(value2, RestoreStatus::ALL_READY); + + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_READY); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has3, value3] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has3); + EXPECT_EQ(value3, RestoreStatus::ALL_READY); + manager->restoreStatus_.Clear(); +} + +/** +* @tc.name: NotifyChange001 +* @tc.desc: NotifyChange test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyChange001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> data; + std::map> data1; + std::vector data1_; + data1_.push_back(RestoreStatus::DATA_READY); + data_.push_back(RestoreStatus::ALL_READY); + data = {{ "test_cloud", data_ }}; + data1 = {{ "p_###SAVEINFO###001", data1_ }}; + manager->NotifyChange(data1); + manager->NotifyChange(data); +} + +/** + * @tc.name: NotifyChange002 + * @tc.desc: NotifyChange test. + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, NotifyChange002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr executor = std::make_shared(1, 0); + manager->SetThreadPool(executor); + std::map> data{}; + std::vector value{0}; + std::string bundleName = "com.example.myapplication"; + std::string sessionId = "123456"; + std::string source = "source"; + std::string target = "target"; + std::string timestamp = "1234567890"; + ObjectStoreManager::SaveInfo saveInfo(bundleName, sessionId, source, target, timestamp); + std::string saveInfoStr = DistributedData::Serializable::Marshall(saveInfo); + auto saveInfoValue = std::vector(saveInfoStr.begin(), saveInfoStr.end()); + std::string prefix = saveInfo.ToPropertyPrefix(); + std::string assetPrefix = prefix + "p_asset"; + data.insert_or_assign(prefix + "p_###SAVEINFO###", saveInfoValue); + data.insert_or_assign(prefix + "p_data", value); + data.insert_or_assign(assetPrefix + ObjectStore::NAME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::URI_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::PATH_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::CREATE_TIME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::SIZE_SUFFIX, value); + data.insert_or_assign("testkey", value); + manager->NotifyChange(data); + EXPECT_TRUE(manager->restoreStatus_.Contains(bundleName+sessionId)); + auto [has, taskId] = manager->objectTimer_.Find(bundleName+sessionId); + EXPECT_TRUE(has); + manager->restoreStatus_.Clear(); + manager->executors_->Remove(taskId); + manager->objectTimer_.Clear(); +} + +/** + * @tc.name: ComputeStatus001 + * @tc.desc: ComputeStatus.test + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, ComputeStatus001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr executor = std::make_shared(1, 0); + manager->SetThreadPool(executor); + std::string objectKey="com.example.myapplicaiton123456"; + std::map>> data{}; + manager->restoreStatus_.Clear(); + manager->ComputeStatus(objectKey, {}, data); + auto [has0, value0] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has0); + EXPECT_EQ(value0, RestoreStatus::DATA_READY); + auto [has1, taskId1] = manager->objectTimer_.Find(objectKey); + EXPECT_TRUE(has1); + manager->executors_->Remove(taskId1); + manager->objectTimer_.Clear(); + manager->restoreStatus_.Clear(); + + manager->restoreStatus_.Insert(objectKey, RestoreStatus::ASSETS_READY); + manager->ComputeStatus(objectKey, {}, data); + auto [has2, value2] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has2); + EXPECT_EQ(value2, RestoreStatus::ALL_READY); + auto [has3, taskId3] = manager->objectTimer_.Find(objectKey); + EXPECT_FALSE(has3); + manager->restoreStatus_.Clear(); +} + +/** +* @tc.name: Open001 +* @tc.desc: Open test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Open001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->kvStoreDelegateManager_ = nullptr; + auto result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_INNER_ERROR); + std::string dataDir = "/data/app/el2/100/database"; + manager->SetData(dataDir, userId_); + manager->delegate_ = nullptr; + result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); + manager->delegate_ = manager->OpenObjectKvStore(); + result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: OnAssetChanged001 +* @tc.desc: OnAssetChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, OnAssetChanged001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr snapshot = std::make_shared(); + auto snapshotKey = appId_ + "_" + sessionId_; + auto result = manager->OnAssetChanged(tokenId_, appId_, sessionId_, deviceId_, assetValue_); + ASSERT_EQ(result, DistributedObject::OBJECT_INNER_ERROR); + manager->snapshots_.Insert(snapshotKey, snapshot); + result = manager->OnAssetChanged(tokenId_, appId_, sessionId_, deviceId_, assetValue_); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: DeleteSnapshot001 +* @tc.desc: DeleteSnapshot test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteSnapshot001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr snapshot = std::make_shared(); + auto snapshotKey = bundleName_ + "_" + sessionId_; + auto snapshots = manager->snapshots_.Find(snapshotKey).second; + ASSERT_EQ(snapshots, nullptr); + manager->DeleteSnapshot(bundleName_, sessionId_); + + manager->snapshots_.Insert(snapshotKey, snapshot); + snapshots = manager->snapshots_.Find(snapshotKey).second; + ASSERT_NE(snapshots, nullptr); + manager->DeleteSnapshot(bundleName_, sessionId_); +} + +/** +* @tc.name: OpenObjectKvStore001 +* @tc.desc: OpenObjectKvStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, OpenObjectKvStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->objectDataListener_ = nullptr; + ASSERT_EQ(manager->objectDataListener_, nullptr); + manager->OpenObjectKvStore(); + ASSERT_NE(manager->objectDataListener_, nullptr); + manager->OpenObjectKvStore(); +} + +/** +* @tc.name: FlushClosedStore001 +* @tc.desc: FlushClosedStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, FlushClosedStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->isSyncing_ = true; + manager->syncCount_ = 10; // test syncCount_ + manager->delegate_ = nullptr; + manager->FlushClosedStore(); + manager->isSyncing_ = false; + manager->FlushClosedStore(); + manager->syncCount_ = 0; // test syncCount_ + manager->FlushClosedStore(); + manager->delegate_ = manager->OpenObjectKvStore(); + manager->FlushClosedStore(); +} + +/** +* @tc.name: Close001 +* @tc.desc: Close test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Close001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->syncCount_ = 1; // test syncCount_ + manager->Close(); + ASSERT_EQ(manager->syncCount_, 1); // 1 is for testing + manager->delegate_ = manager->OpenObjectKvStore(); + manager->Close(); + ASSERT_EQ(manager->syncCount_, 0); // 0 is for testing +} + +/** +* @tc.name: SyncOnStore001 +* @tc.desc: SyncOnStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SyncOnStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + std::string prefix = "ObjectManagerTest"; + std::vector deviceList; + deviceList.push_back("local"); + deviceList.push_back("local1"); + auto result = manager->SyncOnStore(prefix, deviceList, func); + ASSERT_EQ(result, OBJECT_SUCCESS); +} + +/** +* @tc.name: RevokeSaveToStore001 +* @tc.desc: RetrieveFromStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, RevokeSaveToStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + DistributedDB::KvStoreNbDelegateMock mockDelegate; + manager->delegate_ = &mockDelegate; + std::vector id; + id.push_back(1); // for testing + id.push_back(2); // for testing + std::map> results; + results = {{ "test_cloud", id }}; + auto result = manager->RetrieveFromStore(appId_, sessionId_, results); + ASSERT_EQ(result, OBJECT_SUCCESS); +} + +/** +* @tc.name: SyncCompleted001 +* @tc.desc: SyncCompleted test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SyncCompleted001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + auto syncManager = SequenceSyncManager::GetInstance(); + std::map results; + results = {{ "test_cloud", DistributedDB::DBStatus::OK }}; + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + manager->userId_ = "99"; + std::vector userId; + userId.push_back(99); + userId.push_back(100); + manager->SyncCompleted(results, sequenceId_); + syncManager->userIdSeqIdRelations_ = {{ "test_cloud", userId }}; + manager->SyncCompleted(results, sequenceId_); + userId.clear(); + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + manager->SyncCompleted(results, sequenceId_); + userId.push_back(99); + userId.push_back(100); + manager->SyncCompleted(results, sequenceId_); +} + +/** +* @tc.name: SplitEntryKey001 +* @tc.desc: SplitEntryKey test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SplitEntryKey001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string key1 = ""; + std::string key2 = "ObjectManagerTest"; + auto result = manager->SplitEntryKey(key1); + ASSERT_EQ(result.empty(), true); + result = manager->SplitEntryKey(key2); + ASSERT_EQ(result.empty(), true); +} + +/** +* @tc.name: SplitEntryKey002 +* @tc.desc: SplitEntryKey test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, SplitEntryKey002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string key1 = "com.example.myapplication_sessionId_source_target_1234567890_p_propertyName"; + auto res = manager->SplitEntryKey(key1); + EXPECT_EQ(res[0], "com.example.myapplication"); + EXPECT_EQ(res[1], "sessionId"); + EXPECT_EQ(res[2], "source"); + EXPECT_EQ(res[3], "target"); + EXPECT_EQ(res[4], "1234567890"); + EXPECT_EQ(res[5], "p_propertyName"); + + std::string key2 = "com.example.myapplication_sessionId_source_target_000_p_propertyName"; + res = manager->SplitEntryKey(key2); + EXPECT_TRUE(res.empty()); + + std::string key3 = "com.example.myapplicationsessionIdsourcetarget_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key3); + EXPECT_TRUE(res.empty()); + + std::string key4 = "com.example.myapplicationsessionIdsource_target_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key4); + EXPECT_TRUE(res.empty()); + + std::string key5 = "com.example.myapplicationsessionId_source_target_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key5); + EXPECT_TRUE(res.empty()); +} + +/** +* @tc.name: ProcessOldEntry001 +* @tc.desc: ProcessOldEntry test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, ProcessOldEntry001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->delegate_ = manager->OpenObjectKvStore(); + std::vector entries; + auto status = manager->delegate_->GetEntries(std::vector(appId_.begin(), appId_.end()), entries); + ASSERT_EQ(status, DistributedDB::DBStatus::NOT_FOUND); + manager->ProcessOldEntry(appId_); + + DistributedDB::KvStoreNbDelegateMock mockDelegate; + manager->delegate_ = &mockDelegate; + status = manager->delegate_->GetEntries(std::vector(appId_.begin(), appId_.end()), entries); + ASSERT_EQ(status, DistributedDB::DBStatus::OK); + manager->ProcessOldEntry(appId_); +} + +/** +* @tc.name: ProcessSyncCallback001 +* @tc.desc: ProcessSyncCallback test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, ProcessSyncCallback001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map results; + manager->ProcessSyncCallback(results, appId_, sessionId_, deviceId_); + results.insert({"local", 1}); // for testing + ASSERT_EQ(results.empty(), false); + ASSERT_NE(results.find("local"), results.end()); + manager->ProcessSyncCallback(results, appId_, sessionId_, deviceId_); +} + +/** +* @tc.name: IsAssetComplete001 +* @tc.desc: IsAssetComplete test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, IsAssetComplete001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> results; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + std::string assetPrefix = "IsAssetComplete_test"; + results.insert({assetPrefix, completes}); + auto result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::NAME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::URI_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::PATH_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::CREATE_TIME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::SIZE_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: GetAssetsFromDBRecords001 +* @tc.desc: GetAssetsFromDBRecords test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, GetAssetsFromDBRecords001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> results; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + std::string assetPrefix = "IsAssetComplete_test"; + results.insert({assetPrefix, completes}); + results.insert({assetPrefix + ObjectStore::NAME_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::URI_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::SIZE_SUFFIX, completes}); + auto result = manager->GetAssetsFromDBRecords(results); + ASSERT_EQ(result.empty(), false); +} + +/** +* @tc.name: GetAssetsFromDBRecords002 +* @tc.desc: GetAssetsFromDBRecords test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, GetAssetsFromDBRecords002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> result; + + std::vector value0{0}; + std::string data0 = "[STRING]test"; + value0.insert(value0.end(), data0.begin(), data0.end()); + + std::vector value1{0}; + std::string data1 = "(string)test"; + value1.insert(value1.end(), data1.begin(), data1.end()); + + std::string prefix = "bundleName_sessionId_source_target_timestamp"; + std::string dataKey = prefix + "_p_data"; + std::string assetPrefix0 = prefix + "_p_asset0"; + std::string assetPrefix1 = prefix + "_p_asset1"; + + result.insert({dataKey, value0}); + auto assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix0 + ObjectStore::URI_SUFFIX, value0}); + assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix1 + ObjectStore::NAME_SUFFIX, value1}); + assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix0 + ObjectStore::NAME_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::URI_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::MODIFY_TIME_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::SIZE_SUFFIX, value0}); + assets = manager->GetAssetsFromDBRecords(result); + ASSERT_EQ(assets.size(), 1); + EXPECT_EQ(assets[0].name, "test"); + EXPECT_EQ(assets[0].uri, "test"); + EXPECT_EQ(assets[0].modifyTime, "test"); + EXPECT_EQ(assets[0].size, "test"); + EXPECT_EQ(assets[0].hash, "test_test"); + + result.clear(); + result.insert({assetPrefix1 + ObjectStore::NAME_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::URI_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::MODIFY_TIME_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::SIZE_SUFFIX, value1}); + assets = manager->GetAssetsFromDBRecords(result); + ASSERT_EQ(assets.size(), 1); + EXPECT_EQ(assets[0].name, "(string)test"); + EXPECT_EQ(assets[0].uri, "(string)test"); + EXPECT_EQ(assets[0].modifyTime, "(string)test"); + EXPECT_EQ(assets[0].size, "(string)test"); + EXPECT_EQ(assets[0].hash, "(string)test_(string)test"); +} + +/** +* @tc.name: RegisterAssetsLister001 +* @tc.desc: RegisterAssetsLister test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, RegisterAssetsLister001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->objectAssetsSendListener_ = nullptr; + manager->objectAssetsRecvListener_ = nullptr; + auto result = manager->RegisterAssetsLister(); + ASSERT_EQ(result, true); + manager->objectAssetsSendListener_ = new ObjectAssetsSendListener(); + manager->objectAssetsRecvListener_ = new ObjectAssetsRecvListener();; + result = manager->RegisterAssetsLister(); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: RegisterAssetsLister001 +* @tc.desc: PushAssets test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, PushAssets001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> data; + std::string assetPrefix = "PushAssets_test"; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + data.insert({assetPrefix, completes}); + auto result = manager->PushAssets(appId_, appId_, sessionId_, data, deviceId_); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: AddNotifier001 +* @tc.desc: AddNotifie and DeleteNotifier test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, AddNotifier001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto sequenceId_ = syncManager->AddNotifier(userId_, func); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); +} + +/** +* @tc.name: AddNotifier002 +* @tc.desc: AddNotifie and DeleteNotifier test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, AddNotifier002, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto sequenceId = syncManager->AddNotifier(userId_, func); + ASSERT_NE(sequenceId, sequenceId_); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); +} + +/** +* @tc.name: BindAsset 001 +* @tc.desc: BindAsset test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, BindAsset001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string bundleName = "BindAsset"; + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + auto result = manager->BindAsset(tokenId, bundleName, sessionId_, assetValue_, assetBindInfo_); + ASSERT_EQ(result, DistributedObject::OBJECT_DBSTATUS_ERROR); +} +} // namespace OHOS::Test diff --git a/services/distributeddataservice/service/test/object_snapshot_test.cpp b/services/distributeddataservice/service/test/object_snapshot_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90cdc9daf4852c6f521e6104ec59eb004b0bc2b9 --- /dev/null +++ b/services/distributeddataservice/service/test/object_snapshot_test.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectSnapshotTest" + +#include "object_snapshot.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using namespace OHOS::DistributedData; +namespace OHOS::Test { + +class ObjectSnapshotTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + AssetBindInfo AssetBindInfo_; + Asset asset_; + std::string uri_; + StoreInfo storeInfo_; +}; + +void ObjectSnapshotTest::SetUp() +{ + uri_ = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; + + VBucket vBucket{ { "11", 111 } }; + AssetBindInfo AssetBindInfo{ + .storeName = "store_test", + .tableName = "table_test", + .primaryKey = vBucket, + .field = "attachment", + .assetName = "asset1.jpg", + }; + AssetBindInfo_ = AssetBindInfo; + StoreInfo storeInfo { + .tokenId = 0, + .bundleName = "bundleName_test", + .storeName = "store_test", + .instanceId = 1, + .user = 100, + }; + storeInfo_ = storeInfo; + ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); +} + +void ObjectSnapshotTest::TearDown() {} + +/** +* @tc.name: UploadTest001 +* @tc.desc: Upload test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Upload(asset); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: UploadTest002 +* @tc.desc: Upload test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Upload(asset_); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: DownloadTest001 +* @tc.desc: Download test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Download(asset); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: DownloadTest002 +* @tc.desc: Download test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Download(asset_); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: GetAssetStatusTest001 +* @tc.desc: GetAssetStatus test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, GetAssetStatusTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->GetAssetStatus(asset); + ASSERT_EQ(upload, STATUS_BUTT); +} + +/** +* @tc.name: GetAssetStatusTest002 +* @tc.desc: GetAssetStatus test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, GetAssetStatusTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->GetAssetStatus(asset_); + ASSERT_EQ(upload, STATUS_STABLE); +} + +/** +* @tc.name: UploadedTest001 +* @tc.desc: Uploaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Uploaded(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: UploadedTest002 +* @tc.desc: Uploaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Uploaded(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: DownloadedTest001 +* @tc.desc: Downloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Downloaded(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: DownloadedTest002 +* @tc.desc: Downloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Downloaded(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: TransferredTest001 +* @tc.desc: Transferred test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, TransferredTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Transferred(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: TransferredTest002 +* @tc.desc: Transferred test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, TransferredTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Transferred(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: OnDataChangedTest001 +* @tc.desc: OnDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, OnDataChangedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + std::string deviceId = "object_snapshot_test_1"; + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->OnDataChanged(asset, deviceId); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: OnDataChangedTest002 +* @tc.desc: OnDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, OnDataChangedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + std::string deviceId = "object_snapshot_test_1"; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->OnDataChanged(asset_, deviceId); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: BindAsset001 +* @tc.desc: BindAsset test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, BindAsset001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + snapshot->BindAsset(asset, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), true); + snapshot->BindAsset(asset, AssetBindInfo_, storeInfo_); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/rdb_general_store_test.cpp b/services/distributeddataservice/service/test/rdb_general_store_test.cpp index 27c1332f2de0f84e3e9843db71696b14fc98d2fe..afb088b700cbd8830b1fa20747dbe7b1820b7e5f 100644 --- a/services/distributeddataservice/service/test/rdb_general_store_test.cpp +++ b/services/distributeddataservice/service/test/rdb_general_store_test.cpp @@ -17,6 +17,7 @@ #include "rdb_general_store.h" #include +#include #include "bootstrap.h" #include "cloud/schema_meta.h" @@ -404,6 +405,29 @@ HWTEST_F(RdbGeneralStoreTest, Close, TestSize.Level1) EXPECT_EQ(ret, GeneralError::E_BUSY); } +/** +* @tc.name: Close +* @tc.desc: RdbGeneralStore Close test +* @tc.type: FUNC +* @tc.require: +* @tc.author: shaoyuanzhao +*/ +HWTEST_F(RdbGeneralStoreTest, BusyClose, TestSize.Level1) +{ + auto store = std::make_shared(metaData_); + ASSERT_NE(store, nullptr); + std::thread thread([store]() { + std::unique_lockrwMutex_)> lock(store->rwMutex_); + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + auto ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); + thread.join(); + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_OK); +} + /** * @tc.name: Execute * @tc.desc: RdbGeneralStore Execute function test @@ -702,12 +726,12 @@ HWTEST_F(RdbGeneralStoreTest, Sync, TestSize.Level1) GeneralStore::DetailAsync async; SyncParam syncParam; auto result = store->Sync(devices, query, async, syncParam); - EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + EXPECT_EQ(result.first, GeneralError::E_ALREADY_CLOSED); MockRelationalStoreDelegate mockDelegate; store->delegate_ = &mockDelegate; result = store->Sync(devices, query, async, syncParam); - EXPECT_EQ(result, GeneralError::E_OK); + EXPECT_EQ(result.first, GeneralError::E_OK); } /** diff --git a/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp b/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp index 3275efb5ee4d10c80d49e19747071bcc265129be..7dd91221847b766977ffcc9848ca10a24bb126d3 100644 --- a/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp +++ b/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp @@ -244,7 +244,6 @@ HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl001, TestSize.Level0) EXPECT_EQ(resultSet->GetAssets(col, assets), NativeRdb::E_OK); NativeRdb::ValueObject::FloatVector vecs; size_t size = 0; - EXPECT_EQ(resultSet->GetFloat32Array(col, vecs), NativeRdb::E_NOT_SUPPORT); EXPECT_EQ(resultSet->GetSize(col, size), NativeRdb::E_OK); EXPECT_FALSE(resultSet->IsClosed()); EXPECT_EQ(resultSet->Close(), NativeRdb::E_OK); @@ -298,7 +297,6 @@ HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl002, TestSize.Level0) EXPECT_EQ(result->Close(), NativeRdb::E_OK); EXPECT_EQ(result->GetAsset(col, asset), NativeRdb::E_ALREADY_CLOSED); EXPECT_EQ(result->GetAssets(col, assets), NativeRdb::E_ALREADY_CLOSED); - EXPECT_EQ(result->GetFloat32Array(col, vecs), NativeRdb::E_ALREADY_CLOSED); EXPECT_EQ(result->Get(col, valueObject), NativeRdb::E_ALREADY_CLOSED); EXPECT_EQ(result->GetSize(col, size), NativeRdb::E_ALREADY_CLOSED); } diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index d625d654195d5454c0e7634c12ad5d0e0ff3dfd4..be8f3fce759f328732ca03b0df6a76a0363558f9 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -207,6 +207,9 @@ HWTEST_F(UdmfRunTimeStoreTest, PutEntries003, TestSize.Level1) status = store->GetEntries(KEY_PREFIX, entries); EXPECT_EQ(E_OK, status); EXPECT_EQ(0, entries.size()); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -240,11 +243,14 @@ HWTEST_F(UdmfRunTimeStoreTest, PutEntries004, TestSize.Level1) EXPECT_EQ(0, entries.size()); status = store->PutEntries(entrysMix2); - EXPECT_EQ(E_DB_ERROR, status); + EXPECT_EQ(E_OK, status); entries.clear(); status = store->GetEntries(KEY_PREFIX, entries); EXPECT_EQ(E_OK, status); - EXPECT_EQ(0, entries.size()); + EXPECT_EQ(1, entries.size()); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -284,10 +290,13 @@ HWTEST_F(UdmfRunTimeStoreTest, PutEntries005, TestSize.Level1) GetRandomValue(valueInvalid, MAX_VALUE_SIZE + 1); // 4M + 1 entrysRand[128] = { key, valueInvalid }; status = store->PutEntries(entrysRand); - EXPECT_EQ(E_DB_ERROR, status); + EXPECT_EQ(E_OK, status); status = store->GetEntries(KEY_PREFIX, entries); EXPECT_EQ(E_OK, status); - EXPECT_EQ(0, entries.size()); + EXPECT_EQ(129, entries.size()); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -326,6 +335,9 @@ HWTEST_F(UdmfRunTimeStoreTest, DeleteEntries001, TestSize.Level1) status = store->GetEntries(KEY_PREFIX, entries); EXPECT_EQ(E_OK, status); EXPECT_EQ(0, entries.size()); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -366,6 +378,9 @@ HWTEST_F(UdmfRunTimeStoreTest, DeleteEntries002, TestSize.Level1) status = store->GetEntries(KEY_PREFIX, entries); EXPECT_EQ(E_OK, status); EXPECT_EQ(0, entries.size()); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -415,6 +430,9 @@ HWTEST_F(UdmfRunTimeStoreTest, Get001, TestSize.Level1) status = store->Get(KEY_PREFIX, unifiedData); EXPECT_EQ(E_NOT_FOUND, status); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -445,6 +463,9 @@ HWTEST_F(UdmfRunTimeStoreTest, Get002, TestSize.Level1) UnifiedData data1; status = store->Get(EMPTY_DEVICE_ID, data1); EXPECT_EQ(E_NOT_FOUND, status); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -481,6 +502,9 @@ HWTEST_F(UdmfRunTimeStoreTest, GetDetailsFromUData, TestSize.Level1) EXPECT_EQ(records.size(), 0); status = store->GetDetailsFromUData(data1, details1); EXPECT_FALSE(status); + + status = store->Delete(KEY_PREFIX); + EXPECT_EQ(E_OK, status); } /** @@ -540,10 +564,9 @@ HWTEST_F(UdmfRunTimeStoreTest, GetSummary, TestSize.Level1) UnifiedData data; UDDetails details; details.insert({ "udmf_key", "udmf_value" }); - Text text; - text.SetDetails(details); - std::shared_ptr record1 = std::make_shared(text); - data.AddRecord(record1); + auto text = std::make_shared(); + text->SetDetails(details); + data.AddRecord(text); Summary summary; auto status = store->GetSummary(KEY_PREFIX, summary); diff --git a/services/distributeddataservice/service/test/water_version_manager_test.cpp b/services/distributeddataservice/service/test/water_version_manager_test.cpp index d520a57ba082315ebe02c9537dd6e822bfc2bb05..95b4847f6202692414b6662018c1495fbc46caf8 100644 --- a/services/distributeddataservice/service/test/water_version_manager_test.cpp +++ b/services/distributeddataservice/service/test/water_version_manager_test.cpp @@ -103,7 +103,7 @@ void WaterVersionManagerTest::SetUpTestCase(void) instance_.SetStatic(staticStores); } WaterVersionManager::GetInstance().Init(); - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); staticMeta_.deviceId = TEST_DEVICE; staticMeta_.version = WvManager::WaterVersionMetaData::DEFAULT_VERSION; diff --git a/services/distributeddataservice/service/udmf/BUILD.gn b/services/distributeddataservice/service/udmf/BUILD.gn old mode 100755 new mode 100644 index e64eb69f73cf5a5f4215dbc56d16fcbbf49a8f27..bd88c57d2e741bb55c978101936e4f30c1dc8b32 --- a/services/distributeddataservice/service/udmf/BUILD.gn +++ b/services/distributeddataservice/service/udmf/BUILD.gn @@ -53,25 +53,31 @@ ohos_shared_library("udmf_server") { "permission/checker_manager.cpp", "permission/data_checker.cpp", "permission/uri_permission_manager.cpp", + "preprocess/data_handler.cpp", "preprocess/preprocess_utils.cpp", + "preprocess/udmf_dialog.cpp", "store/runtime_store.cpp", "store/store_cache.cpp", "udmf_service_impl.cpp", "udmf_service_stub.cpp", - "utd/custom_utd_installer.cpp", ] configs = [ ":module_public_config" ] + cflags = [ "-D_LIBCPP_HAS_COND_CLOCKWAIT" ] + deps = [ "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service:distributeddatasvc", ] + defines = [] external_deps = [ "ability_base:zuri", + "ability_runtime:ability_manager", "ability_runtime:uri_permission_mgr", + "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "app_file_service:remote_file_share_native", @@ -80,15 +86,24 @@ ohos_shared_library("udmf_server") { "c_utils:utils", "hilog:libhilog", "hisysevent:libhisysevent", - "image_framework:image", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", "ipc:ipc_core", "kv_store:distributeddb", "safwk:system_ability_fwk", "samgr:samgr_proxy", "udmf:udmf_client", + "udmf:utd_client", ] cflags_cc = [ "-fvisibility=hidden" ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + + if (window_manager_use_sceneboard) { + external_deps += [ "window_manager:libwm_lite" ] + defines += [ "SCENE_BOARD_ENABLE" ] + } else { + external_deps += [ "window_manager:libwm" ] + } } diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp index f628847d943db71eb27b24794ed3b7cedc386a9d..c756012227678f60ae14f2055f142174bb5f862f 100644 --- a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp @@ -26,6 +26,7 @@ namespace UDMF { using CleanAfterGet = LifeCyclePolicy; std::unordered_map> LifeCycleManager::intentionPolicy_ = { { UD_INTENTION_MAP.at(UD_INTENTION_DRAG), std::make_shared() }, + { UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB), std::make_shared() } }; LifeCycleManager &LifeCycleManager::GetInstance() diff --git a/services/distributeddataservice/service/udmf/preprocess/data_handler.cpp b/services/distributeddataservice/service/udmf/preprocess/data_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..273ae73dee47cf4e2dc06a4d60c67c2b53f1adfa --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/data_handler.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "DataHandler" + +#include "data_handler.h" +#include "log_print.h" +#include "tlv_object.h" +#include "tlv_util.h" + +namespace OHOS::UDMF { +constexpr const char *UD_KEY_SEPARATOR = "/"; +constexpr const char *UD_KEY_ENTRY_SEPARATOR = "#"; + +Status DataHandler::MarshalToEntries(const UnifiedData &unifiedData, std::vector &entries) +{ + std::string unifiedKey = unifiedData.GetRuntime()->key.GetUnifiedKey(); + std::vector runtimeBytes; + auto runtimeTlv = TLVObject(runtimeBytes); + if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv, TAG::TAG_RUNTIME)) { + ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str()); + return E_WRITE_PARCEL_ERROR; + } + std::vector udKeyBytes = { unifiedKey.begin(), unifiedKey.end() }; + Entry entry = { udKeyBytes, runtimeBytes }; + entries.emplace_back(entry); + return BuildEntries(unifiedData.GetRecords(), unifiedKey, entries); +} + +Status DataHandler::UnmarshalEntries(const std::string &key, const std::vector &entries, + UnifiedData &unifiedData) +{ + std::map> records; + std::map> innerEntries; + auto status = UnmarshalEntryItem(unifiedData, entries, key, records, innerEntries); + if (status != E_OK) { + ZLOGE("UnmarshalEntryItem failed."); + return status; + } + for (auto &[entryKey, entryValue] : innerEntries) { + auto idx = entryKey.rfind(UD_KEY_ENTRY_SEPARATOR); + std::string recordKey = entryKey.substr(0, idx); + std::string entryUtdId = entryKey.substr(idx + 1); + if (records.find(recordKey) != records.end() && entryValue.find(entryUtdId) != entryValue.end()) { + records[recordKey]->AddEntry(entryUtdId, std::move(entryValue[entryUtdId])); + } + } + return E_OK; +} + +Status DataHandler::UnmarshalEntryItem(UnifiedData &unifiedData, const std::vector &entries, + const std::string &key, std::map> &records, + std::map> &innerEntries) +{ + for (const auto &entry : entries) { + std::string keyStr = { entry.key.begin(), entry.key.end() }; + auto data = TLVObject(const_cast &>(entry.value)); + if (keyStr == key) { + Runtime runtime; + if (!TLVUtil::ReadTlv(runtime, data, TAG::TAG_RUNTIME)) { + ZLOGE("Unmarshall runtime info failed."); + return E_READ_PARCEL_ERROR; + } + unifiedData.SetRuntime(runtime); + continue; + } + auto isStartWithKey = keyStr.find(key) == 0; + if (!isStartWithKey) { + continue; + } + auto isEntryItem = keyStr.rfind(UD_KEY_ENTRY_SEPARATOR) != std::string::npos; + if (isStartWithKey && !isEntryItem) { + std::shared_ptr record; + if (!TLVUtil::ReadTlv(record, data, TAG::TAG_UNIFIED_RECORD)) { + ZLOGE("Unmarshall unified record failed."); + return E_READ_PARCEL_ERROR; + } + unifiedData.AddRecord(record); + records.emplace(keyStr, record); + continue; + } + if (isStartWithKey && isEntryItem) { + std::shared_ptr> entryRead = + std::make_shared>(); + if (!TLVUtil::ReadTlv(entryRead, data, TAG::TAG_INNER_ENTRIES)) { + ZLOGE("Unmarshall inner entry failed."); + return E_READ_PARCEL_ERROR; + } + innerEntries.emplace(keyStr, std::move(*entryRead)); + } + } + return E_OK; +} + +Status DataHandler::BuildEntries(const std::vector> &records, + const std::string &unifiedKey, std::vector &entries) +{ + for (const auto &record : records) { + std::string recordKey = unifiedKey + UD_KEY_SEPARATOR + record->GetUid(); + auto recordEntries = record->GetInnerEntries(); + for (auto &recordEntry : *recordEntries) { + std::string key = recordKey + UD_KEY_ENTRY_SEPARATOR + recordEntry.first; + std::vector entryBytes; + auto entryTlv = TLVObject(entryBytes); + const std::shared_ptr> entryMap = + std::make_shared>(); + entryMap->insert_or_assign(recordEntry.first, recordEntry.second); + if (!TLVUtil::Writing(entryMap, entryTlv, TAG::TAG_INNER_ENTRIES)) { + ZLOGI("Marshall inner entry failed."); + return E_WRITE_PARCEL_ERROR; + } + std::vector keyBytes = { key.begin(), key.end() }; + Entry entry = { keyBytes, entryBytes }; + entries.emplace_back(entry); + } + recordEntries->clear(); + std::vector recordBytes; + auto recordTlv = TLVObject(recordBytes); + if (!TLVUtil::Writing(record, recordTlv, TAG::TAG_UNIFIED_RECORD)) { + ZLOGI("Marshall unified record failed."); + return E_WRITE_PARCEL_ERROR; + } + std::vector keyBytes = { recordKey.begin(), recordKey.end() }; + Entry entry = { keyBytes, recordBytes }; + entries.emplace_back(entry); + } + return E_OK; +} +} // namespace UDMF::OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/data_handler.h b/services/distributeddataservice/service/udmf/preprocess/data_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..c6b3c94e46755c8a344c0903973f9942d4af525c --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/data_handler.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATA_HANDLER_H +#define DATA_HANDLER_H + +#include "error_code.h" +#include "unified_data.h" +#include "types_export.h" + +namespace OHOS::UDMF { +using namespace DistributedDB; + +class DataHandler { +public: + static Status MarshalToEntries(const UnifiedData &unifiedData, std::vector &entries); + static Status UnmarshalEntries(const std::string &key, const std::vector &entries, + UnifiedData &unifiedData); + +private: + static Status BuildEntries(const std::vector> &records, + const std::string &unifiedKey, std::vector &entries); + static Status UnmarshalEntryItem(UnifiedData &unifiedData, const std::vector &entries, + const std::string &key, std::map> &records, + std::map> &innerEntries); +}; +} // namespace UDMF::OHOS +#endif // DATA_HANDLER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp index 3da10584d524009f870ee314ab23fa5c14f9db87..4ce5d1755eaf907cfa9a8599a766282220af4922 100644 --- a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -19,14 +19,16 @@ #include #include +#include "dds_trace.h" +#include "udmf_radar_reporter.h" #include "accesstoken_kit.h" #include "bundlemgr/bundle_mgr_client_impl.h" #include "device_manager_adapter.h" #include "error_code.h" -#include "file.h" #include "ipc_skeleton.h" #include "log_print.h" #include "udmf_radar_reporter.h" +#include "udmf_utils.h" #include "remote_file_share.h" #include "uri.h" #include "utils/crypto.h" @@ -38,7 +40,10 @@ static constexpr int ID_LEN = 32; static constexpr int MINIMUM = 48; static constexpr int MAXIMUM = 121; constexpr char SPECIAL = '^'; +constexpr const char *FILE_SCHEME = "file"; +constexpr const char *TAG = "PreProcessUtils::"; static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500; +using namespace OHOS::DistributedDataDfx; using namespace Security::AccessToken; using namespace OHOS::AppFileService::ModuleRemoteFileShare; using namespace RadarReporter; @@ -88,7 +93,7 @@ time_t PreProcessUtils::GetTimestamp() return timestamp; } -int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId) +int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId) { Security::AccessToken::HapTokenInfo tokenInfo; auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); @@ -96,18 +101,28 @@ int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId) ZLOGE("GetHapUidByToken failed, result = %{public}d.", result); return E_ERROR; } - return tokenInfo.userID; + userId = tokenInfo.userID; + return E_OK; } bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) { Security::AccessToken::HapTokenInfo hapInfo; if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) - != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { - return false; + == Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + bundleName = hapInfo.bundleName; + return true; } - bundleName = hapInfo.bundleName; - return true; + if (UTILS::IsTokenNative()) { + ZLOGD("TypeATokenTypeEnum is TOKEN_HAP"); + std::string processName; + if (GetNativeProcessNameByToken(tokenId, processName)) { + bundleName = processName; + return true; + } + } + ZLOGE("GetHapBundleNameByToken faild"); + return false; } bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) @@ -141,43 +156,54 @@ void PreProcessUtils::SetRemoteData(UnifiedData &data) } ZLOGD("is remote data."); auto records = data.GetRecords(); - for (auto record : records) { - auto type = record->GetType(); - if (IsFileType(type)) { - auto file = static_cast(record.get()); - UDDetails details = file->GetDetails(); - details.insert({ "isRemote", "true" }); - file->SetDetails(details); + ProcessFileType(records, [] (std::shared_ptr obj) { + std::shared_ptr detailObj; + obj->GetValue(DETAILS, detailObj); + if (detailObj == nullptr) { + ZLOGE("Not contain details for object!"); + return false; } - } + UDDetails details = ObjectUtils::ConvertToUDDetails(detailObj); + details.insert({ "isRemote", "true" }); + obj->value_[DETAILS] = ObjectUtils::ConvertToObject(details); + return true; + }); } -bool PreProcessUtils::IsFileType(UDType udType) +bool PreProcessUtils::IsFileType(std::shared_ptr record) { - return (udType == UDType::FILE || udType == UDType::IMAGE || udType == UDType::VIDEO || udType == UDType::AUDIO - || udType == UDType::FOLDER); + if (record == nullptr) { + return false; + } + if (!std::holds_alternative>(record->GetOriginValue())) { + return false; + } + auto obj = std::get>(record->GetOriginValue()); + return obj->value_.find(ORI_URI) != obj->value_.end(); } int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) { - int32_t userId = GetHapUidByToken(tokenId); std::vector uris; - for (const auto &record : data.GetRecords()) { - if (record != nullptr && IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - if (file->GetUri().empty()) { - ZLOGW("Get uri empty, plase check the uri."); - continue; - } - Uri uri(file->GetUri()); - if (uri.GetAuthority().empty()) { - ZLOGW("Get uri authority empty."); - continue; - } - uris.push_back(file->GetUri()); + ProcessFileType(data.GetRecords(), [&uris](std::shared_ptr obj) { + std::string oriUri; + obj->GetValue(ORI_URI, oriUri); + if (oriUri.empty()) { + ZLOGW("Get uri empty, plase check the uri."); + return false; } - } + Uri uri(oriUri); + std::string scheme = uri.GetScheme(); + std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower); + if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) { + ZLOGW("Get uri authority empty or uri scheme not equals to file."); + return false; + } + uris.push_back(oriUri); + return true; + }); if (!uris.empty()) { + ZLOGI("Read to check uri authorization"); if (!CheckUriAuthorization(uris, tokenId)) { ZLOGE("CheckUriAuthorization failed, bundleName:%{public}s, tokenId: %{public}d, uris size:%{public}zu.", data.GetRuntime()->createPackage.c_str(), tokenId, uris.size()); @@ -185,13 +211,12 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, E_NO_PERMISSION); return E_NO_PERMISSION; } - int ret = GetDfsUrisFromLocal(uris, userId, data); - if (ret != E_OK) { - RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), - BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, E_FS_ERROR); - ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.", - ret, userId, uris.size()); - return E_FS_ERROR; + if (!IsNetworkingEnabled()) { + return E_OK; + } + int32_t userId; + if (GetHapUidByToken(tokenId, userId) == E_OK) { + GetDfsUrisFromLocal(uris, userId, data); } } return E_OK; @@ -199,22 +224,32 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) int32_t PreProcessUtils::GetDfsUrisFromLocal(const std::vector &uris, int32_t userId, UnifiedData &data) { + DdsTrace trace( + std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::IDLE, BizState::DFX_BEGIN); std::unordered_map dfsUris; int ret = RemoteFileShare::GetDfsUrisFromLocal(uris, userId, dfsUris); if (ret != 0 || dfsUris.empty()) { + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, E_FS_ERROR, BizState::DFX_END); ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.", ret, userId, uris.size()); return E_FS_ERROR; } - for (const auto &record : data.GetRecords()) { - if (record != nullptr && IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - auto iter = dfsUris.find(file->GetUri()); - if (iter != dfsUris.end()) { - file->SetRemoteUri((iter->second).uriStr); - } + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::SUCCESS); + ProcessFileType(data.GetRecords(), [&dfsUris] (std::shared_ptr obj) { + std::string oriUri; + obj->GetValue(ORI_URI, oriUri); + auto iter = dfsUris.find(oriUri); + if (iter != dfsUris.end()) { + obj->value_[REMOTE_URI] = (iter->second).uriStr; } - } + return true; + }); + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::SUCCESS, BizState::DFX_END); return E_OK; } @@ -248,5 +283,37 @@ bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) instIndex = tokenInfo.instIndex; return true; } + +bool PreProcessUtils::IsNetworkingEnabled() +{ + std::vector devInfos = + DistributedData::DeviceManagerAdapter::GetInstance().GetRemoteDevices(); + ZLOGI("DM remote devices count is %{public}u.", static_cast(devInfos.size())); + if (devInfos.empty()) { + return false; + } + return true; +} + +void PreProcessUtils::ProcessFileType(std::vector> records, + std::function)> callback) +{ + for (auto record : records) { + if (record == nullptr) { + continue; + } + if (!PreProcessUtils::IsFileType(record)) { + continue; + } + auto obj = std::get>(record->GetOriginValue()); + if (obj == nullptr) { + ZLOGE("ValueType is not Object, Not convert to remote uri!"); + continue; + } + if (!callback(obj)) { + continue; + } + } +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h index 70e9c6ee07775d7a20ae6e23e2ef385111e0c6fe..9d3770b6502ae250c68cc9b41019fe1715db9dfb 100644 --- a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -30,17 +30,20 @@ public: static int32_t RuntimeDataImputation(UnifiedData &data, CustomOption &option); static std::string GenerateId(); static time_t GetTimestamp(); - static int32_t GetHapUidByToken(uint32_t tokenId); + static int32_t GetHapUidByToken(uint32_t tokenId, int &userId); static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); static std::string GetLocalDeviceId(); static void SetRemoteData(UnifiedData &data); - static bool IsFileType(UDType udType); static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); + static bool IsNetworkingEnabled(); + static void ProcessFileType(std::vector> records, + std::function)> callback); private: static bool CheckUriAuthorization(const std::vector& uris, uint32_t tokenId); static int32_t GetDfsUrisFromLocal(const std::vector &uris, int32_t userId, UnifiedData &data); + static bool IsFileType(std::shared_ptr record); }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.cpp b/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52b99b817529ca2cc3ff1bc54ccd1dd311dce908 --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "UdmfDialog" + +#include "udmf_dialog.h" + +#include "ability_connect_callback_stub.h" +#include "ability_manager_proxy.h" +#include "error_code.h" +#include "in_process_call_wrapper.h" +#include "iservice_registry.h" +#include "log_print.h" +#include "system_ability_definition.h" +#ifdef SCENE_BOARD_ENABLE +#include "window_manager_lite.h" +#else +#include "window_manager.h" +#endif + +namespace OHOS::UDMF { +using namespace OHOS::AAFwk; + +ProgressDialog &ProgressDialog::GetInstance() +{ + static ProgressDialog instance; + return instance; +} + +ProgressDialog::FocusedAppInfo ProgressDialog::GetFocusedAppInfo(void) const +{ + FocusedAppInfo appInfo = { 0 }; + Rosen::FocusChangeInfo info; +#ifdef SCENE_BOARD_ENABLE + Rosen::WindowManagerLite::GetInstance().GetFocusWindowInfo(info); +#else + Rosen::WindowManager::GetInstance().GetFocusWindowInfo(info); +#endif + appInfo.windowId = info.windowId_; + appInfo.abilityToken = info.abilityToken_; + return appInfo; +} + +sptr ProgressDialog::GetAbilityManagerService() +{ + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + ZLOGE("Failed to get ability manager."); + return nullptr; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (!remoteObject) { + ZLOGE("Failed to get ability manager service."); + return nullptr; + } + return iface_cast(remoteObject); +} + +int32_t ProgressDialog::ShowProgress(const ProgressMessageInfo &message) +{ + ZLOGD("Begin."); + auto abilityManager = GetAbilityManagerService(); + if (abilityManager == nullptr) { + ZLOGE("Get ability manager failed."); + return E_ERROR; + } + + Want want; + want.SetElementName(PASTEBOARD_DIALOG_APP, PASTEBOARD_PROGRESS_ABILITY); + want.SetAction(PASTEBOARD_PROGRESS_ABILITY); + want.SetParam("promptText", message.promptText); + want.SetParam("remoteDeviceName", message.remoteDeviceName); + want.SetParam("progressKey", message.progressKey); + want.SetParam("isRemote", message.isRemote); + want.SetParam("windowId", message.windowId); + want.SetParam("ipcCallback", message.clientCallback); + if (message.callerToken != nullptr) { + want.SetParam("tokenKey", message.callerToken); + } else { + ZLOGW("CallerToken is nullptr."); + } + + int32_t status = IN_PROCESS_CALL(abilityManager->StartAbility(want)); + if (status != 0) { + ZLOGE("Start progress failed, status:%{public}d.", status); + } + return status; +} +} // namespace OHOS::UDMF \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.h b/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.h new file mode 100644 index 0000000000000000000000000000000000000000..94a302fe9c7a8e9b5ef48b31a959960ae40c38dd --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/udmf_dialog.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_DIALOG_H +#define UDMF_DIALOG_H + +#include "error_code.h" +#include "ability_manager_interface.h" +#include "refbase.h" + +namespace OHOS::UDMF { + +class ProgressDialog { +public: + struct FocusedAppInfo { + int32_t windowId = 0; + sptr abilityToken = nullptr; + }; + struct ProgressMessageInfo { + std::string promptText { DEFAULT_LABEL }; + std::string remoteDeviceName { DEFAULT_LABEL }; + std::string progressKey { DEFAULT_LABEL }; + bool isRemote { false }; + int32_t windowId { 0 }; + sptr callerToken { nullptr }; + sptr clientCallback { nullptr }; + }; + + static ProgressDialog &GetInstance(); + int32_t ShowProgress(const ProgressMessageInfo &message); + FocusedAppInfo GetFocusedAppInfo(void) const; + +private: + static sptr GetAbilityManagerService(); + + static constexpr const char *DEFAULT_LABEL = "unknown"; + static constexpr const char *PASTEBOARD_DIALOG_APP = "com.ohos.pasteboarddialog"; + static constexpr const char *PASTEBOARD_PROGRESS_ABILITY = "PasteboardProgressAbility"; +}; +} // namespace UDMF::OHOS +#endif // UDMF_DIALOG_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 35fff502a4816161fdd7a5ade1d38f69e9e065e6..095c0ca744bcf78b335d7c518d0de9705693f318 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -18,11 +18,15 @@ #include #include -#include +#include #include +#include "data_handler.h" #include "log_print.h" #include "ipc_skeleton.h" +#include "unified_data_helper.h" +#include "udmf_radar_reporter.h" +#include "unified_meta.h" #include "tlv_util.h" #include "account/account_delegate.h" #include "metadata/store_meta_data.h" @@ -32,7 +36,7 @@ #include "bootstrap.h" #include "directory/directory_manager.h" #include "utils/anonymous.h" -#include "udmf_radar_reporter.h" + namespace OHOS { namespace UDMF { using namespace RadarReporter; @@ -103,33 +107,11 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) { UpdateTime(); std::vector entries; - std::string unifiedKey = unifiedData.GetRuntime()->key.GetUnifiedKey(); - // add runtime info - std::vector runtimeBytes; - auto runtimeTlv = TLVObject(runtimeBytes); - if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv)) { - ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str()); - return E_WRITE_PARCEL_ERROR; - } - std::vector udKeyBytes = {unifiedKey.begin(), unifiedKey.end()}; - Entry entry = {udKeyBytes, runtimeBytes}; - entries.push_back(entry); - - // add unified record - for (const auto &record : unifiedData.GetRecords()) { - std::vector recordBytes; - auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Writing(record, recordTlv)) { - ZLOGI("Marshall unified record failed."); - return E_WRITE_PARCEL_ERROR; - } - std::string recordKey = unifiedKey + "/" + record->GetUid(); - std::vector keyBytes = {recordKey.begin(), recordKey.end() }; - Entry entry = { keyBytes, recordBytes }; - entries.push_back(entry); + auto status = DataHandler::MarshalToEntries(unifiedData, entries); + if (status != E_OK) { + return status; } - auto status = PutEntries(entries); - return status; + return PutEntries(entries); } Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) @@ -144,7 +126,7 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); return E_NOT_FOUND; } - return UnmarshalEntries(key, entries, unifiedData); + return DataHandler::UnmarshalEntries(key, entries, unifiedData); } bool RuntimeStore::GetDetailsFromUData(UnifiedData &data, UDDetails &details) @@ -156,11 +138,18 @@ bool RuntimeStore::GetDetailsFromUData(UnifiedData &data, UDDetails &details) if (records[0] == nullptr || records[0]->GetType() != UDType::FILE) { return false; } - auto file = static_cast(records[0].get()); - if (file == nullptr) { + auto obj = std::get>(records[0]->GetOriginValue()); + if (obj == nullptr) { + ZLOGE("ValueType is not Object!"); return false; } - auto result = file->GetDetails(); + std::shared_ptr detailObj; + obj->GetValue(DETAILS, detailObj); + if (detailObj == nullptr) { + ZLOGE("Not contain details for object!"); + return false; + } + auto result = ObjectUtils::ConvertToUDDetails(detailObj); if (result.find(TEMP_UNIFIED_DATA_FLAG) == result.end()) { return false; } @@ -196,17 +185,7 @@ Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) if (GetDetailsFromUData(unifiedData, details)) { return GetSummaryFromDetails(details, summary); } - for (const auto &record : unifiedData.GetRecords()) { - int64_t recordSize = record->GetSize(); - auto udType = UtdUtils::GetUtdIdFromUtdEnum(record->GetType()); - auto it = summary.summary.find(udType); - if (it == summary.summary.end()) { - summary.summary[udType] = recordSize; - } else { - summary.summary[udType] += recordSize; - } - summary.totalSize += recordSize; - } + UnifiedDataHelper::GetSummary(unifiedData, summary); return E_OK; } @@ -281,7 +260,7 @@ Status RuntimeStore::Sync(const std::vector &devices) BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, dbStatus); } else { RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), - BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END); + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_END); } ZLOGI("sync complete, %{public}s, status:%{public}d.", Anonymous::Change(storeId_).c_str(), dbStatus); @@ -296,6 +275,61 @@ Status RuntimeStore::Sync(const std::vector &devices) return E_OK; } +Status RuntimeStore::Sync(const std::vector &devices, ProcessCallback callback) +{ + UpdateTime(); + if (devices.empty()) { + ZLOGE("devices empty, no need sync."); + return E_INVALID_PARAMETERS; + } + std::vector syncDevices = DmAdapter::ToUUID(devices); + DevNameMap deviceNameMap; + for (const auto &device : devices) { + std::string deviceUuid = DmAdapter::GetInstance().ToUUID(device); + std::string deviceName = DmAdapter::GetInstance().GetDeviceInfo(device).deviceName; + deviceNameMap.emplace(deviceUuid, deviceName); + } + auto progressCallback = [this, callback, deviceNameMap](const DevSyncProcessMap &processMap) { + this->NotifySyncProcss(processMap, callback, deviceNameMap); + }; + + DistributedDB::DeviceSyncOption option; + option.devices = syncDevices; + option.isWait = false; + DBStatus status = kvStore_->Sync(option, progressCallback); + if (status != DBStatus::OK) { + ZLOGE("Sync kvStore failed, status: %{public}d.", status); + return E_DB_ERROR; + } + return E_OK; +} + +void RuntimeStore::NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, + const DevNameMap &deviceNameMap) +{ + AsyncProcessInfo processInfo; + for (const auto &[originDeviceId, syncProcess] : processMap) { // only one device + processInfo.srcDevName = deviceNameMap.at(originDeviceId); + processInfo.syncId = syncProcess.syncId; + processInfo.syncFinished = syncProcess.pullInfo.finishedCount; + processInfo.syncTotal = syncProcess.pullInfo.total; + if (syncProcess.process != DistributedDB::ProcessStatus::FINISHED) { + processInfo.syncStatus = ASYNC_RUNNING; + continue; + } + if (syncProcess.errCode == DBStatus::OK) { + processInfo.syncStatus = ASYNC_SUCCESS; + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_END); + } else { + processInfo.syncStatus = ASYNC_FAILURE; + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, syncProcess.errCode, BizState::DFX_END); + } + } + callback(processInfo); +} + Status RuntimeStore::Clear() { UpdateTime(); @@ -325,7 +359,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector(delegate, release); + uint32_t pragmData = 16 * 1024 * 1024; + PragmaData input = static_cast(&pragmData); + kvStore_->Pragma(SET_MAX_VALUE_SIZE, input); return true; } @@ -526,29 +563,5 @@ Status RuntimeStore::DeleteEntries(const std::vector &keys) return E_OK; } -Status RuntimeStore::UnmarshalEntries(const std::string &key, std::vector &entries, UnifiedData &unifiedData) -{ - for (const auto &entry : entries) { - std::string keyStr = {entry.key.begin(), entry.key.end()}; - if (keyStr == key) { - Runtime runtime; - auto runtimeTlv = TLVObject(const_cast &>(entry.value)); - if (!TLVUtil::Reading(runtime, runtimeTlv)) { - ZLOGE("Unmarshall runtime info failed."); - return E_READ_PARCEL_ERROR; - } - unifiedData.SetRuntime(runtime); - } else if (keyStr.find(key) == 0) { - std::shared_ptr record; - auto recordTlv = TLVObject(const_cast &>(entry.value)); - if (!TLVUtil::Reading(record, recordTlv)) { - ZLOGE("Unmarshall unified record failed."); - return E_READ_PARCEL_ERROR; - } - unifiedData.AddRecord(record); - } - } - return E_OK; -} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index 689affd4c66d7d0ca61dcb9d3ed9eb1e66bba7dd..d172120dbb4d87c470000e65c04169da5043d39e 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -23,6 +23,8 @@ namespace OHOS { namespace UDMF { +using DevNameMap = std::map; +using DevSyncProcessMap = std::map; class API_EXPORT RuntimeStore final : public Store { public: explicit RuntimeStore(const std::string &storeId); @@ -34,6 +36,7 @@ public: Status Delete(const std::string &key) override; Status DeleteBatch(const std::vector &unifiedKeys) override; Status Sync(const std::vector &devices) override; + Status Sync(const std::vector &devices, ProcessCallback callback) override; Status Clear() override; Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) override; Status PutLocal(const std::string &key, const std::string &value) override; @@ -60,6 +63,8 @@ private: bool GetDetailsFromUData(UnifiedData &data, UDDetails &details); Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); bool BuildMetaDataParam(DistributedData::StoreMetaData &metaData); + void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, + const DevNameMap &deviceNameMap); }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/store/store.h b/services/distributeddataservice/service/udmf/store/store.h index f9960756303bb922a29182b78e25eff92c5bba00..0de10afbc4d2345cd3dc9de3dcb9659b54646ef8 100644 --- a/services/distributeddataservice/service/udmf/store/store.h +++ b/services/distributeddataservice/service/udmf/store/store.h @@ -27,6 +27,7 @@ namespace OHOS { namespace UDMF { +using ProcessCallback = std::function; class Store { public: using Time = std::chrono::steady_clock::time_point; @@ -37,6 +38,7 @@ public: virtual Status Delete(const std::string &key) = 0; virtual Status DeleteBatch(const std::vector &unifiedKeys) = 0; virtual Status Sync(const std::vector &devices) = 0; + virtual Status Sync(const std::vector &devices, ProcessCallback callback) = 0; virtual Status Clear() = 0; virtual Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) = 0; virtual Status PutLocal(const std::string &key, const std::string &value) = 0; diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 4f52855b09695600e04320d67c4ca96236b697f6..dbdac8110a715d3648ae152c80eea61f66e072e3 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "UdmfServiceImpl" #include "udmf_service_impl.h" @@ -24,15 +25,19 @@ #include "checker_manager.h" #include "dfx_types.h" #include "distributed_kv_data_manager.h" -#include "file.h" #include "lifecycle/lifecycle_manager.h" #include "log_print.h" #include "preprocess_utils.h" #include "reporter.h" #include "uri_permission_manager.h" #include "uri.h" -#include "utd/custom_utd_installer.h" +#include "udmf_conversion.h" #include "udmf_radar_reporter.h" +#include "utils/anonymous.h" +#include "bootstrap.h" +#include "metadata/store_meta_data.h" +#include "metadata/meta_data_manager.h" +#include "device_manager_adapter.h" namespace OHOS { namespace UDMF { @@ -40,10 +45,15 @@ using namespace Security::AccessToken; using FeatureSystem = DistributedData::FeatureSystem; using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; using Reporter = OHOS::DistributedDataDfx::Reporter; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using StoreMetaData = OHOS::DistributedData::StoreMetaData; using namespace RadarReporter; constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"}; constexpr const char *DATA_PREFIX = "udmf://"; +constexpr const char *FILE_SCHEME = "file"; constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep"; +constexpr const char *MANAGE_UDMF_APP_SHARE_OPTION = "ohos.permission.MANAGE_UDMF_APP_SHARE_OPTION"; +constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"}; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -54,8 +64,6 @@ UdmfServiceImpl::Factory::Factory() } return product_; }, FeatureSystem::BIND_NOW); - staticActs_ = std::make_shared(); - FeatureSystem::GetInstance().RegisterStaticActs("udmf", staticActs_); } UdmfServiceImpl::Factory::~Factory() @@ -73,6 +81,7 @@ int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, ZLOGD("start"); int32_t res = E_OK; UdmfBehaviourMsg msg; + std::string types; auto find = UD_INTENTION_MAP.find(option.intention); msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; msg.operation = "insert"; @@ -86,7 +95,12 @@ int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, } auto errFind = ERROR_MAP.find(res); msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; - msg.dataType = unifiedData.GetTypes(); + for (const auto &record : unifiedData.GetRecords()) { + for (const auto &type : record->GetUtdIds()) { + types.append("-").append(type); + } + } + msg.dataType = types; msg.dataSize = unifiedData.GetSize(); Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); return res; @@ -130,11 +144,6 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData return E_DB_ERROR; } - if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) { - ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str()); - return E_DB_ERROR; - } - if (store->Put(unifiedData) != E_OK) { ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; @@ -149,6 +158,7 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD ZLOGD("start"); int32_t res = E_OK; UdmfBehaviourMsg msg; + std::string types; auto find = UD_INTENTION_MAP.find(query.intention); msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; msg.operation = "insert"; @@ -162,17 +172,34 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD } auto errFind = ERROR_MAP.find(res); msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; - msg.dataType = unifiedData.GetTypes(); + for (const auto &record : unifiedData.GetRecords()) { + for (const auto &type : record->GetUtdIds()) { + types.append("-").append(type); + } + } + msg.dataType = types; msg.dataSize = unifiedData.GetSize(); Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); return res; } -int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) +bool UdmfServiceImpl::CheckDragParams(UnifiedKey &key, const QueryOption &query) { - UnifiedKey key(query.key); if (!key.IsValid()) { ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return false; + } + if (key.intention != UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + ZLOGE("Invalid intention:%{public}s", key.intention.c_str()); + return false; + } + return true; +} + +int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) +{ + UnifiedKey key(query.key); + if (!CheckDragParams(key, query)) { return E_INVALID_PARAMETERS; } auto store = StoreCache::GetInstance().GetStore(key.intention); @@ -251,62 +278,76 @@ bool UdmfServiceImpl::IsReadAndKeep(const std::vector &privileges, co int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData) { std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); - auto records = unifiedData.GetRecords(); - if (unifiedData.GetRuntime() == nullptr) { - return E_DB_ERROR; - } - std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; - if (localDeviceId != sourceDeviceId) { - SetRemoteUri(query, records); + std::vector allUri; + int32_t verifyRes = ProcessCrossDeviceData(unifiedData, allUri); + if (verifyRes != E_OK) { + ZLOGE("verify unifieddata fail, key=%{public}s, stauts=%{public}d", query.key.c_str(), verifyRes); + return verifyRes; } std::string bundleName; if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId); return E_ERROR; } + std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) { ZLOGW("No need to grant uri permissions, queryKey=%{public}s.", query.key.c_str()); return E_OK; } - std::vector allUri; - for (auto record : records) { - if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - if (file->GetUri().empty()) { - ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str()); - continue; - } - Uri uri(file->GetUri()); - if (uri.GetAuthority().empty()) { - ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str()); - continue; - } - allUri.push_back(uri); - } - } if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) { - RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), - BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, E_NO_PERMISSION); ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.", - bundleName.c_str(), query.key.c_str()); + bundleName.c_str(), query.key.c_str()); return E_NO_PERMISSION; } return E_OK; } -void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector> &records) +int32_t UdmfServiceImpl::ProcessCrossDeviceData(UnifiedData &unifiedData, std::vector &uris) { - for (auto record : records) { - if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - std::string remoteUri = file->GetRemoteUri(); - if (remoteUri.empty()) { - ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str()); - continue; + if (unifiedData.GetRuntime() == nullptr) { + ZLOGE("Get runtime empty!"); + return E_DB_ERROR; + } + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; + auto records = unifiedData.GetRecords(); + bool hasError = false; + PreProcessUtils::ProcessFileType(records, [&] (std::shared_ptr obj) { + if (hasError) { + return false; + } + std::string oriUri; + obj->GetValue(ORI_URI, oriUri); + if (oriUri.empty()) { + ZLOGW("Get uri is empty."); + return false; + } + Uri uri(oriUri); + std::string scheme = uri.GetScheme(); + std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower); + if (localDeviceId != sourceDeviceId) { + std::string remoteUri; + obj->GetValue(REMOTE_URI, remoteUri); + if (remoteUri.empty() && scheme == FILE_SCHEME) { + ZLOGE("when cross devices, remote uri is required!"); + hasError = true; + return false; + } + if (!remoteUri.empty()) { + obj->value_.insert_or_assign(ORI_URI, remoteUri); // cross dev, need dis path. + uri = Uri(remoteUri); + scheme = uri.GetScheme(); + std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower); } - file->SetUri(remoteUri); // cross dev, need dis path. } - } + if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) { + ZLOGW("Get authority is empty or uri scheme not equals to file."); + return false; + } + uris.push_back(uri); + return true; + }); + return hasError ? E_ERROR : E_OK; } int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) @@ -332,15 +373,15 @@ int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vectorGet(query.key, data); if (res != E_OK) { @@ -363,6 +403,10 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi if (runtime == nullptr) { return E_DB_ERROR; } + if (runtime->tokenId != query.tokenId && !HasDatahubPriviledge(bundleName)) { + ZLOGE("update data failed, query option tokenId not equals data's tokenId"); + return E_INVALID_PARAMETERS; + } runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); unifiedData.SetRuntime(*runtime); for (auto &record : unifiedData.GetRecords()) { @@ -396,9 +440,16 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorkey.key); + if (runtime->tokenId == query.tokenId) { + unifiedDataSet.push_back(data); + deleteKeys.push_back(runtime->key.key); + } + } + if (deleteKeys.empty()) { + ZLOGE("Delete nothing. There is no data belonging to this application"); + return E_OK; } + ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size()); if (store->DeleteBatch(deleteKeys) != E_OK) { ZLOGE("Remove data failed."); return E_DB_ERROR; @@ -488,24 +539,38 @@ int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vectorSync(devices) != E_OK) { + auto callback = [this, query](AsyncProcessInfo &syncInfo) { + if (query.key.empty()) { + return; + } + syncInfo.businessUdKey = query.key; + std::lock_guard lock(mutex_); + asyncProcessInfoMap_.insert_or_assign(syncInfo.businessUdKey, syncInfo); + ZLOGD("store.Sync: name=%{public}s, id=%{public}u, status=%{public}u, total=%{public}u, finish=%{public}u", + syncInfo.srcDevName.c_str(), syncInfo.syncId, syncInfo.syncStatus, + syncInfo.syncTotal, syncInfo.syncFinished); + }; + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::SUCCESS); + if (store->Sync(devices, callback) != E_OK) { ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), - BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_ABNORMAL_END); + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END); return E_DB_ERROR; } - RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), - BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END); return E_OK; } @@ -551,8 +616,9 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx); - if (!isSystemApp) { - ZLOGE("no system permission, intention: %{public}s.", intention.c_str()); + bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID()); + if (!isSystemApp && !hasSharePermission) { + ZLOGE("No system permission and no shareOption permission, intention: %{public}s.", intention.c_str()); return E_NO_PERMISSION; } auto store = StoreCache::GetInstance().GetStore(intention); @@ -589,7 +655,7 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t std::string appShareOption; int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); if (ret != E_OK) { - ZLOGE("GetAppShareOption empty, intention: %{public}s.", intention.c_str()); + ZLOGW("GetAppShareOption empty, intention: %{public}s.", intention.c_str()); return ret; } ZLOGI("GetAppShareOption, intention: %{public}s, appShareOption:%{public}s.", @@ -606,8 +672,9 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) } uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx); - if (!isSystemApp) { - ZLOGE("no system permission, intention: %{public}s.", intention.c_str()); + bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID()); + if (!isSystemApp && !hasSharePermission) { + ZLOGE("No system permission and no shareOption permission, intention: %{public}s.", intention.c_str()); return E_NO_PERMISSION; } auto store = StoreCache::GetInstance().GetStore(intention); @@ -643,15 +710,16 @@ int32_t UdmfServiceImpl::QueryDataCommon( { auto find = UD_INTENTION_MAP.find(query.intention); std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; - if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + UnifiedKey key(query.key); + if (!UnifiedDataUtils::IsValidOptions(key, intention, UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB))) { ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); return E_INVALID_PARAMETERS; } - std::string dataPrefix = DATA_PREFIX + intention; - UnifiedKey key(query.key); - key.IsValid(); - if (intention.empty()) { - dataPrefix = key.key; + std::string dataPrefix; + if (key.key.empty()) { + dataPrefix = DATA_PREFIX + intention; + } else { + dataPrefix = UnifiedKey(key.key).GetKeyCommonPrefix(); intention = key.intention; } ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str()); @@ -676,42 +744,104 @@ int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo) return 0; } -int32_t UdmfServiceImpl::UdmfStatic::OnAppInstall(const std::string &bundleName, int32_t user, - int32_t index) +int32_t UdmfServiceImpl::ObtainAsynProcess(AsyncProcessInfo &processInfo) { - ZLOGD("Bundle: %{public}s installed.", bundleName.c_str()); - auto status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); - if (status != E_OK) { - ZLOGE("Install Utd failed, bundleName: %{public}s, status: %{public}d", bundleName.c_str(), status); + if (processInfo.businessUdKey.empty()) { + return E_INVALID_PARAMETERS; } - return status; + std::lock_guard lock(mutex_); + if (asyncProcessInfoMap_.empty()) { + processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS; + processInfo.srcDevName = "Local"; + return E_OK; + } + auto it = asyncProcessInfoMap_.find(processInfo.businessUdKey); + if (it == asyncProcessInfoMap_.end()) { + processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS; + processInfo.srcDevName = "Local"; + return E_OK; + } + auto asyncProcessInfo = asyncProcessInfoMap_.at(processInfo.businessUdKey); + processInfo.syncStatus = asyncProcessInfo.syncStatus; + processInfo.srcDevName = asyncProcessInfo.srcDevName; + return E_OK; } -int32_t UdmfServiceImpl::UdmfStatic::OnAppUpdate(const std::string &bundleName, int32_t user, - int32_t index) +int32_t UdmfServiceImpl::ClearAsynProcessByKey(const std::string & businessUdKey) { - ZLOGD("Bundle: %{public}s Update.", bundleName.c_str()); - auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); - if (status != E_OK) { - ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); - return status; + ZLOGI("ClearAsynProcessByKey begin."); + std::lock_guard lock(mutex_); + if (asyncProcessInfoMap_.find(businessUdKey) == asyncProcessInfoMap_.end()) { + return E_OK; } - status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); - if (status != E_OK) { - ZLOGE("Install utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); + asyncProcessInfoMap_.erase(businessUdKey); + return E_OK; +} + +int32_t UdmfServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) +{ + ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), + param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(), + DistributedData::Anonymous::Change(identifier).c_str()); + + std::vector metaData; + auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid }); + if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { + ZLOGE("no meta data appId:%{public}s", param.appId.c_str()); + return E_NOT_FOUND; + } + + for (const auto &storeMeta : metaData) { + if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN || + storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END || + storeMeta.appId != DistributedData::Bootstrap::GetInstance().GetProcessLabel()) { + continue; + } + auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, + storeMeta.storeId, true); + if (identifier != identifierTag) { + continue; + } + auto store = StoreCache::GetInstance().GetStore(storeMeta.storeId); + if (store == nullptr) { + ZLOGE("GetStore fail, storeId:%{public}s", DistributedData::Anonymous::Change(storeMeta.storeId).c_str()); + continue; + } + ZLOGI("storeId:%{public}s,appId:%{public}s,user:%{public}s", + DistributedData::Anonymous::Change(storeMeta.storeId).c_str(), + storeMeta.appId.c_str(), storeMeta.user.c_str()); + return E_OK; } - return status; + return E_OK; } -int32_t UdmfServiceImpl::UdmfStatic::OnAppUninstall(const std::string &bundleName, int32_t user, - int32_t index) +bool UdmfServiceImpl::VerifyPermission(const std::string &permission, uint32_t callerTokenId) { - ZLOGD("Bundle: %{public}s uninstalled.", bundleName.c_str()); - auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); - if (status != E_OK) { - ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); + if (permission.empty()) { + return true; + } + int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission); + if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + ZLOGE("Permission denied. status:%{public}d, token:0x%{public}x, permission:%{public}s", + status, callerTokenId, permission.c_str()); + return false; } - return status; + return true; } + +bool UdmfServiceImpl::HasDatahubPriviledge(const std::string &bundleName) +{ + uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); + bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx); + return std::find(std::begin(HAP_LIST), std::end(HAP_LIST), bundleName) != std::end(HAP_LIST) && isSystemApp; +} + +void UdmfServiceImpl::RegisterAsyncProcessInfo(const std::string &businessUdKey) +{ + AsyncProcessInfo info; + std::lock_guard lock(mutex_); + asyncProcessInfoMap_.insert_or_assign(businessUdKey, std::move(info)); +} + } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index e172fe22e55c5b3bf411a765aa7f13112f6b1c69..3b557e09b85f73f03918d9a0047b2665a68a76e9 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -27,6 +27,7 @@ #include "unified_data.h" #include "unified_types.h" #include "visibility.h" +#include "kv_store_delegate_manager.h" namespace OHOS { namespace UDMF { /* @@ -37,6 +38,7 @@ public: UdmfServiceImpl(); ~UdmfServiceImpl() = default; + using DBLaunchParam = DistributedDB::AutoLaunchParam; int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) override; int32_t GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) override; @@ -51,24 +53,22 @@ public: int32_t RemoveAppShareOption(const std::string &intention) override; int32_t OnInitialize() override; int32_t OnBind(const BindInfo &bindInfo) override; - + int32_t ObtainAsynProcess(AsyncProcessInfo &processInfo) override; + int32_t ClearAsynProcessByKey(const std::string &businessUdKey) override; + int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; private: int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); int32_t QueryDataCommon(const QueryOption &query, std::vector &dataSet, std::shared_ptr &store); int32_t ProcessUri(const QueryOption &query, UnifiedData &unifiedData); - void SetRemoteUri(const QueryOption &query, std::vector> &records); bool IsPermissionInCache(const QueryOption &query); bool IsReadAndKeep(const std::vector &privileges, const QueryOption &query); + bool VerifyPermission(const std::string &permission, uint32_t callerTokenId); + bool HasDatahubPriviledge(const std::string &bundleName); + void RegisterAsyncProcessInfo(const std::string &businessUdKey); + int32_t ProcessCrossDeviceData(UnifiedData &unifiedData, std::vector &uris); + bool CheckDragParams(UnifiedKey &key, const QueryOption &query); - using StaticActs = DistributedData::StaticActs; - class UdmfStatic : public StaticActs { - public: - ~UdmfStatic() override {}; - int32_t OnAppInstall(const std::string &bundleName, int32_t user, int32_t index) override; - int32_t OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index) override; - int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) override; - }; class Factory { public: Factory(); @@ -76,11 +76,13 @@ private: private: std::shared_ptr product_; - std::shared_ptr staticActs_; }; static Factory factory_; std::map privilegeCache_; std::shared_ptr executors_; + + std::mutex mutex_; + std::unordered_map asyncProcessInfoMap_; }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index c71b3572c0854d5f9ce1929933b64240cc053c2d..553d770e35ca7096d126656aa8d522f6d2798dbe 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "UdmfServiceStub" #include "udmf_service_stub.h" @@ -22,6 +23,7 @@ #include "accesstoken_kit.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "udmf_conversion.h" #include "udmf_types_util.h" #include "unified_data.h" #include "unified_meta.h" @@ -263,5 +265,37 @@ int32_t UdmfServiceStub::OnRemoveAppShareOption(MessageParcel &data, MessageParc } return E_OK; } + +int32_t UdmfServiceStub::OnObtainAsynProcess(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + AsyncProcessInfo processInfo; + if (!ITypesUtil::Unmarshal(data, processInfo)) { + ZLOGE("Unmarshal processInfo failed"); + return E_READ_PARCEL_ERROR; + } + int32_t status = ObtainAsynProcess(processInfo); + if (!ITypesUtil::Marshal(reply, status, processInfo)) { + ZLOGE("Marshal status or processInfo failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnClearAsynProcessByKey(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + std::string businessUdKey; + if (!ITypesUtil::Unmarshal(data, businessUdKey)) { + ZLOGE("Unmarshal businessUdKey failed!"); + return E_READ_PARCEL_ERROR; + } + int32_t status = ClearAsynProcessByKey(businessUdKey); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.h b/services/distributeddataservice/service/udmf/udmf_service_stub.h index 0cd2879f72d4c48927c70e0e74ebd0fbdef855f7..b027b11843dd0cc7a2d3bfefd782b2372bd2701c 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -48,6 +48,8 @@ private: int32_t OnSetAppShareOption(MessageParcel &data, MessageParcel &reply); int32_t OnGetAppShareOption(MessageParcel &data, MessageParcel &reply); int32_t OnRemoveAppShareOption(MessageParcel &data, MessageParcel &reply); + int32_t OnObtainAsynProcess(MessageParcel &data, MessageParcel &reply); + int32_t OnClearAsynProcessByKey(MessageParcel &data, MessageParcel &reply); using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { @@ -62,7 +64,9 @@ private: &UdmfServiceStub::OnIsRemoteData, &UdmfServiceStub::OnSetAppShareOption, &UdmfServiceStub::OnGetAppShareOption, - &UdmfServiceStub::OnRemoveAppShareOption + &UdmfServiceStub::OnRemoveAppShareOption, + &UdmfServiceStub::OnObtainAsynProcess, + &UdmfServiceStub::OnClearAsynProcessByKey }; }; } // namespace UDMF diff --git a/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp b/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp deleted file mode 100644 index 548472b9c76a28421626b9319444bd6016a84a28..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "CustomUtdInstaller" - -#include -#include -#include - -#include "error_code.h" -#include "log_print.h" -#include "if_system_ability_manager.h" -#include "iservice_registry.h" -#include "system_ability_definition.h" -#include "utd_graph.h" -#include "custom_utd_json_parser.h" -#include "custom_utd_store.h" -#include "preset_type_descriptors.h" -#include "custom_utd_installer.h" - -namespace OHOS { -namespace UDMF { -constexpr const char *CUSTOM_UTD_PATH = "/data/service/el1/"; -constexpr const char *CUSTOM_UTD_FILE = "/distributeddata/utd/utd-adt.json"; -CustomUtdInstaller::CustomUtdInstaller() -{ -} - -CustomUtdInstaller::~CustomUtdInstaller() -{ -} - -CustomUtdInstaller &CustomUtdInstaller::GetInstance() -{ - static CustomUtdInstaller instance; - return instance; -} - -sptr CustomUtdInstaller::GetBundleManager() -{ - auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (samgrProxy == nullptr) { - ZLOGE("samgrProxy is null."); - return nullptr; - } - auto bmsProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); - if (bmsProxy == nullptr) { - ZLOGE("failed to get bms from samgrProxy."); - return nullptr; - } - return iface_cast(bmsProxy); -} - -int32_t CustomUtdInstaller::InstallUtd(const std::string &bundleName, int32_t user) -{ - std::string path = CUSTOM_UTD_PATH + std::to_string(user) + CUSTOM_UTD_FILE; - std::vector customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(path); - std::vector presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes(); - std::vector modules = GetHapModules(bundleName, user); - bool isSucc = true; - for (std::string module : modules) { - auto utdTypes = GetModuleCustomUtdTypes(bundleName, module, user); - if (utdTypes.first.empty() && utdTypes.second.empty()) { - ZLOGD("Module custom utd types is empty."); - continue; - } - if (!UtdCfgsChecker::GetInstance().CheckTypeDescriptors(utdTypes, presetTypes, customTyepCfgs, bundleName)) { - ZLOGE("Parse json failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(), - bundleName.c_str()); - isSucc = false; - continue; - } - if (SaveCustomUtds(utdTypes, customTyepCfgs, bundleName, path) != E_OK) { - ZLOGE("Install save custom utds failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(), - bundleName.c_str()); - isSucc = false; - continue; - } - } - if (!isSucc) { - return E_ERROR; - } - return E_OK; -} - -int32_t CustomUtdInstaller::UninstallUtd(const std::string &bundleName, int32_t user) -{ - std::string path = CUSTOM_UTD_PATH + std::to_string(user) + CUSTOM_UTD_FILE; - std::vector customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(path); - std::vector deletionMock; - if (!customTyepCfgs.empty()) { - deletionMock.insert(deletionMock.end(), customTyepCfgs.begin(), customTyepCfgs.end()); - } - for (auto iter = deletionMock.begin(); iter != deletionMock.end();) { - auto it = find (iter->installerBundles.begin(), iter->installerBundles.end(), bundleName); - if (it != iter->installerBundles.end()) { - iter->installerBundles.erase(it); - } - if (iter->installerBundles.empty()) { - iter = deletionMock.erase(iter); - } else { - iter++; - } - } - std::vector presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes(); - if (!UtdCfgsChecker::GetInstance().CheckBelongingToTypes(deletionMock, presetTypes)) { - ZLOGW("Uninstall error, because of belongingToTypes check failed."); - return E_ERROR; - } - for (auto customIter = customTyepCfgs.begin(); customIter != customTyepCfgs.end();) { - auto InstallerIter = find (customIter->installerBundles.begin(), customIter->installerBundles.end(), - bundleName); - if (InstallerIter != customIter->installerBundles.end()) { - customIter->installerBundles.erase(InstallerIter); - } - if (customIter->installerBundles.empty()) { - customIter = customTyepCfgs.erase(customIter); - } else { - customIter++; - } - } - if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) { - ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str()); - return E_ERROR; - } - return E_OK; -} - -std::vector CustomUtdInstaller::GetHapModules(const std::string &bundleName, int32_t user) -{ - auto bundlemgr = GetBundleManager(); - if (bundlemgr == nullptr) { - ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str()); - return {}; - } - AppExecFwk::BundleInfo bundleInfo; - if (!bundlemgr->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, user)) { - ZLOGE("Get local bundle info failed, bundleName: %{public}s.", bundleName.c_str()); - } - return bundleInfo.hapModuleNames; -} - -CustomUtdCfgs CustomUtdInstaller::GetModuleCustomUtdTypes(const std::string &bundleName, - const std::string &moduleName, int32_t user) -{ - auto bundlemgr = GetBundleManager(); - std::string jsonStr; - CustomUtdCfgs typeCfgs; - if (bundlemgr == nullptr) { - ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str()); - return typeCfgs; - } - auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, moduleName, jsonStr, - user); - if (status != NO_ERROR) { - ZLOGD("get json profile failed, bundleName: %{public}s.", bundleName.c_str()); - return typeCfgs; - } - if (jsonStr.empty()) { - ZLOGE("JsonStr is empty, bundleName: %{public}s.", bundleName.c_str()); - return typeCfgs; - } - std::vector declarationType; - std::vector referenceType; - - CustomUtdJsonParser customUtdJsonParser_; - bool res = customUtdJsonParser_.ParseUserCustomUtdJson(jsonStr, declarationType, referenceType); - if (!jsonStr.empty() && res) { - typeCfgs.first = declarationType; - typeCfgs.second = referenceType; - } - return typeCfgs; -} - -int32_t CustomUtdInstaller::SaveCustomUtds(const CustomUtdCfgs &utdTypes, std::vector customTyepCfgs, - const std::string &bundleName, const std::string &path) -{ - for (TypeDescriptorCfg declarationType : utdTypes.first) { - for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) { - if (iter->typeId == declarationType.typeId) { - declarationType.installerBundles = iter->installerBundles; - iter = customTyepCfgs.erase(iter); - } else { - iter ++; - } - } - declarationType.installerBundles.emplace(bundleName); - declarationType.ownerBundle = bundleName; - customTyepCfgs.push_back(declarationType); - } - for (TypeDescriptorCfg referenceType : utdTypes.second) { - bool found = false; - for (auto &typeCfg : customTyepCfgs) { - if (typeCfg.typeId == referenceType.typeId) { - typeCfg.installerBundles.emplace(bundleName); - found = true; - break; - } - } - if (!found) { - referenceType.installerBundles.emplace(bundleName); - customTyepCfgs.push_back(referenceType); - } - } - if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) { - ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str()); - return E_ERROR; - } - return E_OK; -} -} -} \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h b/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h deleted file mode 100644 index 2b3d20f3b2a08bb854c89e58d118925cc3fa12e0..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DATAMGR_SERVICE_UTD_MANAGER_H -#define DATAMGR_SERVICE_UTD_MANAGER_H - -#include -#include - -#include "bundlemgr/bundle_mgr_proxy.h" -#include "utd_common.h" -#include "utd_cfgs_checker.h" -#include "system_ability.h" - -namespace OHOS { -namespace UDMF { -class CustomUtdInstaller { -public: - static CustomUtdInstaller &GetInstance(); - int32_t InstallUtd(const std::string &bundleName, int32_t user); - int32_t UninstallUtd(const std::string &bundleName, int32_t user); - -private: - CustomUtdInstaller(); - ~CustomUtdInstaller(); - CustomUtdInstaller(const CustomUtdInstaller &obj) = delete; - CustomUtdInstaller &operator=(const CustomUtdInstaller &obj) = delete; - sptr GetBundleManager(); - std::vector GetHapModules(const std::string &bundleName, int32_t user); - CustomUtdCfgs GetModuleCustomUtdTypes(const std::string &bundleName, const std::string &moduleName, int32_t user); - int32_t SaveCustomUtds(const CustomUtdCfgs &utdTypes, std::vector customTyepCfgs, - const std::string &bundleName, const std::string &path); -}; -} // namespace UDMF -} // namespace OHOS -#endif // DATAMGR_SERVICE_UTD_MANAGER_H diff --git a/services/distributeddataservice/service/waterversion/water_version_manager.cpp b/services/distributeddataservice/service/waterversion/water_version_manager.cpp index 3a41a383dda087bdadd1b07b8380508a5830414f..4101a168ffeadef294eaf7bc4ae3a885fc9f0550 100644 --- a/services/distributeddataservice/service/waterversion/water_version_manager.cpp +++ b/services/distributeddataservice/service/waterversion/water_version_manager.cpp @@ -17,14 +17,14 @@ #include "checker/checker_manager.h" #include "cloud/cloud_sync_finished_event.h" -#include "device_matrix.h" -#include "store/auto_cache.h" #include "device_manager_adapter.h" +#include "device_matrix.h" #include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/matrix_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" +#include "store/auto_cache.h" #include "utils/anonymous.h" #include "utils/constant.h" @@ -39,7 +39,7 @@ WaterVersionManager &WaterVersionManager::GetInstance() } WaterVersionManager::WaterVersionManager() : waterVersions_(BUTT) { - for (int i = 0; i < BUTT; ++i) { + for (int i = 0; i < static_cast(BUTT); ++i) { waterVersions_[i].SetType(static_cast(i)); } } @@ -58,7 +58,7 @@ void WaterVersionManager::Init() } MetaDataManager::GetInstance().LoadMeta(WaterVersionMetaData::GetPrefix(), metas, true); for (auto &meta : metas) { - if (meta.type < 0 || meta.type > BUTT) { + if (meta.type < BEGIN || meta.type > BUTT) { ZLOGW("error meta:%{public}s", meta.ToAnonymousString().c_str()); continue; } @@ -90,7 +90,7 @@ std::string WaterVersionManager::GenerateWaterVersion(const std::string &bundleN if (CheckerManager::GetInstance().IsStatic(info)) { type = STATIC; } - if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { + if (type < BEGIN || type >= BUTT || bundleName.empty() || storeName.empty()) { ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), Anonymous::Change(storeName).c_str(), type); return ""; @@ -111,7 +111,7 @@ std::string WaterVersionManager::GetWaterVersion(const std::string &bundleName, if (CheckerManager::GetInstance().IsStatic(info)) { type = STATIC; } - if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { + if (type < BEGIN || type >= BUTT || bundleName.empty() || storeName.empty()) { ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), Anonymous::Change(storeName).c_str(), type); return ""; @@ -137,7 +137,7 @@ std::string WaterVersionManager::GetWaterVersion(const std::string &bundleName, std::pair WaterVersionManager::GetVersion(const std::string &deviceId, WaterVersionManager::Type type) { - if (type < 0 || type >= BUTT || deviceId.empty()) { + if (type < BEGIN || type >= BUTT || deviceId.empty()) { ZLOGE("invalid args, type:%{public}d", type); return { false, 0 }; } @@ -147,7 +147,7 @@ std::pair WaterVersionManager::GetVersion(const std::string &dev std::string WaterVersionManager::GetWaterVersion(const std::string &deviceId, WaterVersionManager::Type type) { - if (type < 0 || type >= BUTT || deviceId.empty()) { + if (type < BEGIN || type >= BUTT || deviceId.empty()) { ZLOGE("invalid args, type:%{public}d", type); return { false, 0 }; } @@ -181,7 +181,7 @@ bool WaterVersionManager::DelWaterVersion(const std::string &deviceId) bool WaterVersionManager::InitMeta(WaterVersionMetaData &metaData) { - metaData.waterVersion = 0; + metaData.waterVersion = WaterVersionMetaData::DEFAULT_VERSION; std::string uuid = DMAdapter::GetInstance().GetLocalDevice().uuid; for (size_t i = 0; i < metaData.keys.size(); ++i) { auto key = metaData.keys[i]; @@ -326,7 +326,7 @@ bool WaterVersionMetaData::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(waterVersion), waterVersion); int32_t tmp = -1; GetValue(node, GET_NAME(type), tmp); - if (tmp < 0 || tmp >= BUTT) { + if (tmp < BEGIN || tmp >= BUTT) { return false; } type = static_cast(tmp); @@ -360,7 +360,7 @@ std::string WaterVersionMetaData::GetPrefix() bool WaterVersionMetaData::IsValid() { - if (type < 0 || type >= BUTT) { + if (type < BEGIN || type >= BUTT) { return false; } if (keys.size() != infos.size()) { diff --git a/services/distributeddataservice/service/waterversion/water_version_manager.h b/services/distributeddataservice/service/waterversion/water_version_manager.h index bdf83e9fdc99973ca65607c9fa51c57a3b36907d..7e77513fa9978e529372d4a589fa32a880b7a201 100644 --- a/services/distributeddataservice/service/waterversion/water_version_manager.h +++ b/services/distributeddataservice/service/waterversion/water_version_manager.h @@ -25,7 +25,8 @@ namespace DistributedData { class WaterVersionManager { public: enum Type { - DYNAMIC, + BEGIN, + DYNAMIC = BEGIN, STATIC, BUTT };