diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h b/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h index ce1012f3a7b904d8a17d59e3294d3b421df3dd39..94f73271911c1558c14496a1ad533d8692049546 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h @@ -26,11 +26,20 @@ public: static sptr GetObjectService(); static uint32_t RegisterClientDeathListener(const std::string &appId, sptr remoteObject); private: + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + ServiceDeathRecipient(); + virtual ~ServiceDeathRecipient(); + + void OnRemoteDied(const wptr &remote) override; + }; + static constexpr int32_t DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID = 1301; static constexpr int32_t GET_SA_RETRY_TIMES = 3; static constexpr int32_t RETRY_INTERVAL = 1; static std::shared_ptr distributedDataMgr_; static std::shared_ptr GetDistributedDataManager(); + static std::mutex mutex_; }; class ObjectStoreDataServiceProxy : public IRemoteProxy { diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h b/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h index 8f8ddaa7f159d03ca7048eae2e529af7e52d7c65..4cb752f30eda3f108cd8257e25c1dde4e94cfc72 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h @@ -61,9 +61,6 @@ private: mutable std::mutex onDataReceiveMutex_; static constexpr uint32_t MTU_SIZE = 4096 * 1024; // the max transmission unit size(4M - 80B) - static constexpr uint32_t MTU_SIZE_WATCH = 81920; // the max transmission unit size(80K) - static constexpr const char *SMART_WATCH_TYPE = "SMART_WATCH"; - static constexpr const char *CHILDREN_WATCH_TYPE = "CHILDREN_WATCH"; }; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp index 0398e44b9a0a5433fd5ce4f648cec1d65a8fa376..c2ebec12aa15e53a8cbef38d216ad228d36616dc 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp @@ -17,18 +17,20 @@ #include -#include "logger.h" #include "iservice_registry.h" #include "itypes_util.h" +#include "logger.h" #include "objectstore_errors.h" namespace OHOS::ObjectStore { std::shared_ptr ClientAdaptor::distributedDataMgr_ = nullptr; +std::mutex ClientAdaptor::mutex_; using KvStoreCode = OHOS::DistributedObject::ObjectStoreService::KvStoreServiceInterfaceCode; sptr ClientAdaptor::GetObjectService() { + std::lock_guard lockGuard(mutex_); if (distributedDataMgr_ == nullptr) { distributedDataMgr_ = GetDistributedDataManager(); } @@ -66,6 +68,14 @@ std::shared_ptr ClientAdaptor::GetDistributedDataMa LOG_ERROR("new ObjectStoreDataServiceProxy fail."); return nullptr; } + sptr deathRecipientPtr = new (std::nothrow)ServiceDeathRecipient(); + if (deathRecipientPtr == nullptr) { + LOG_ERROR("new deathRecipientPtr fail!"); + return nullptr; + } + if (!remoteObject->AddDeathRecipient(deathRecipientPtr)) { + LOG_ERROR("Add death recipient fail!"); + } return std::shared_ptr(proxy.GetRefPtr(), [holder = proxy](const auto *) {}); } @@ -73,8 +83,24 @@ std::shared_ptr ClientAdaptor::GetDistributedDataMa return nullptr; } +ClientAdaptor::ServiceDeathRecipient::ServiceDeathRecipient() +{ +} + +ClientAdaptor::ServiceDeathRecipient::~ServiceDeathRecipient() +{ +} + +void ClientAdaptor::ServiceDeathRecipient::OnRemoteDied(const wptr &remote) +{ + LOG_WARN("DistributedDataService die!"); + std::lock_guard lockGuard(mutex_); + distributedDataMgr_ = nullptr; +} + uint32_t ClientAdaptor::RegisterClientDeathListener(const std::string &appId, sptr remoteObject) { + std::lock_guard lockGuard(mutex_); if (distributedDataMgr_ == nullptr) { distributedDataMgr_ = GetDistributedDataManager(); } diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp index d862c4e31655a1431b5b0bc91c816dc53f071739..380dd7f68da1364fd59f7800a4a82dad486ad13a 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp @@ -149,14 +149,14 @@ uint32_t FlatObjectStorageEngine::GetTable(const std::string &key, std::mapGetEntries(emptyKey, resultSet); if (status != DistributedDB::DBStatus::OK || resultSet == nullptr) { LOG_INFO("FlatObjectStorageEngine::GetTable %{public}s GetEntries fail", key.c_str()); return ERR_DB_GET_FAIL; } - LOG_INFO("end GetEntries"); + LOG_DEBUG("end GetEntries"); while (resultSet->IsAfterLast()) { DistributedDB::Entry entry; status = resultSet->GetEntry(entry); @@ -191,13 +191,13 @@ uint32_t FlatObjectStorageEngine::UpdateItem(const std::string &key, const std:: return ERR_DB_NOT_EXIST; } auto delegate = delegates_.at(key); - LOG_INFO("start Put"); + LOG_DEBUG("start Put"); auto status = delegate->Put(StringUtils::StrToBytes(itemKey), value); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("%{public}s Put fail[%{public}d]", key.c_str(), status); return ERR_CLOSE_STORAGE; } - LOG_INFO("put success"); + LOG_DEBUG("put success"); return SUCCESS; } @@ -219,13 +219,13 @@ uint32_t FlatObjectStorageEngine::UpdateItems( entries.emplace_back(entry); } auto delegate = delegates_.at(key); - LOG_INFO("start PutBatch"); + LOG_DEBUG("start PutBatch"); auto status = delegate->PutBatch(entries); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("%{public}s PutBatch fail[%{public}d]", key.c_str(), status); return ERR_CLOSE_STORAGE; } - LOG_INFO("put success"); + LOG_DEBUG("put success"); return SUCCESS; } @@ -239,14 +239,14 @@ uint32_t FlatObjectStorageEngine::DeleteTable(const std::string &key) LOG_INFO("FlatObjectStorageEngine::GetTable %{public}s not exist", key.c_str()); return ERR_DB_NOT_EXIST; } - LOG_INFO("start DeleteTable %{public}s", key.c_str()); + LOG_DEBUG("start DeleteTable %{public}s", key.c_str()); auto status = storeManager_->CloseKvStore(delegates_.at(key)); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR( "FlatObjectStorageEngine::CloseKvStore %{public}s CloseKvStore fail[%{public}d]", key.c_str(), status); return ERR_CLOSE_STORAGE; } - LOG_INFO("DeleteTable success"); + LOG_DEBUG("DeleteTable success"); delegates_.erase(key); return SUCCESS; } @@ -261,13 +261,13 @@ uint32_t FlatObjectStorageEngine::GetItem(const std::string &key, const std::str LOG_ERROR("FlatObjectStorageEngine::GetItem %{public}s not exist", key.c_str()); return ERR_DB_NOT_EXIST; } - LOG_INFO("start Get %{public}s", key.c_str()); + LOG_DEBUG("start Get %{public}s", key.c_str()); DistributedDB::DBStatus status = delegates_.at(key)->Get(StringUtils::StrToBytes(itemKey), value); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("FlatObjectStorageEngine::GetItem %{public}s item fail %{public}d", itemKey.c_str(), status); return status; } - LOG_INFO("end Get %{public}s", key.c_str()); + LOG_DEBUG("end Get %{public}s", key.c_str()); return SUCCESS; } @@ -288,14 +288,14 @@ uint32_t FlatObjectStorageEngine::RegisterObserver(const std::string &key, std:: } auto delegate = delegates_.at(key); std::vector tmpKey; - LOG_INFO("start RegisterObserver %{public}s", key.c_str()); + LOG_DEBUG("start RegisterObserver %{public}s", key.c_str()); DistributedDB::DBStatus status = delegate->RegisterObserver(tmpKey, DistributedDB::ObserverMode::OBSERVER_CHANGES_FOREIGN, watcher.get()); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("FlatObjectStorageEngine::RegisterObserver watch err %{public}d", status); return ERR_REGISTER; } - LOG_INFO("end RegisterObserver %{public}s", key.c_str()); + LOG_DEBUG("end RegisterObserver %{public}s", key.c_str()); observerMap_.insert_or_assign(key, watcher); return SUCCESS; } @@ -318,13 +318,13 @@ uint32_t FlatObjectStorageEngine::UnRegisterObserver(const std::string &key) } auto delegate = delegates_.at(key); std::shared_ptr watcher = iter->second; - LOG_INFO("start UnRegisterObserver %{public}s", key.c_str()); + LOG_DEBUG("start UnRegisterObserver %{public}s", key.c_str()); DistributedDB::DBStatus status = delegate->UnRegisterObserver(watcher.get()); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("FlatObjectStorageEngine::UnRegisterObserver unRegister err %{public}d", status); return ERR_UNRIGSTER; } - LOG_INFO("end UnRegisterObserver %{public}s", key.c_str()); + LOG_DEBUG("end UnRegisterObserver %{public}s", key.c_str()); observerMap_.erase(key); return SUCCESS; } diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp index 26f6e5c72df70dbd8e6170a8a81e940439b4da2a..b9aaf0b1a49af40d18603d85a2b47cf3e645b9af 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -71,6 +71,7 @@ uint32_t FlatObjectStore::CreateObject(const std::string &sessionId) } } auto result = storageEngine_->UpdateItems(sessionId, data); + storageEngine_->NotifyStatus(sessionId, "local", "restored"); if (result != SUCCESS) { LOG_ERROR("UpdateItems failed, status = %{public}d", result); } @@ -376,7 +377,7 @@ uint32_t CacheManager::Save(const std::string &bundleName, const std::string &se std::unique_lock lck(mutex_); auto block = std::make_shared>>(WAIT_TIME, std::tuple{ true, ERR_DB_GET_FAIL }); int32_t status = SaveObject(bundleName, sessionId, deviceId, objectData, - [&deviceId, block](const std::map &results) { + [deviceId, block](const std::map &results) { LOG_INFO("CacheManager::task callback"); if (results.count(deviceId) != 0) { block->SetValue({ false, results.at(deviceId) }); diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp index 3139edaa46a4e03bc885ebfce550f0cad2b04980..892c368d4d566e76925590a65771fa025f084f4a 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp @@ -131,13 +131,6 @@ uint32_t ProcessCommunicatorImpl::GetMtuSize() uint32_t ProcessCommunicatorImpl::GetMtuSize(const DeviceInfos &devInfo) { - std::vector devInfos = CommunicationProvider::GetInstance().GetDeviceList(); - for (auto const &entry : devInfos) { - bool isWatch = (entry.deviceType == SMART_WATCH_TYPE || entry.deviceType == CHILDREN_WATCH_TYPE); - if (entry.deviceId == devInfo.identifier && isWatch) { - return MTU_SIZE_WATCH; - } - } return MTU_SIZE; } diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp index f76fa7e3cf78c78adadcb04fd1a8bb5a44db8191..854208a76fc91c1cffb83ad73567060e95018a82 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp @@ -633,7 +633,7 @@ void AppDataListenerWrap::SetDataHandler(SoftBusAdapter *handler) int AppDataListenerWrap::OnSessionOpened(int sessionId, int result) { - LOG_INFO("[SessionOpen] sessionId:%{public}d, result:%{public}d", sessionId, result); + LOG_DEBUG("[SessionOpen] sessionId:%{public}d, result:%{public}d", sessionId, result); char mySessionName[SESSION_NAME_SIZE_MAX] = ""; char peerSessionName[SESSION_NAME_SIZE_MAX] = ""; char peerDevId[DEVICE_ID_SIZE_MAX] = ""; diff --git a/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp b/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp index 2b699f54de9ff9f35f4843d26cd25449a6dd2d78..c94d037c147dc166fa4205559bc0daa5cca79415 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp @@ -662,11 +662,7 @@ bool DataShareJSUtils::UnwrapStringByPropertyName( { napi_value jsResult = nullptr; auto status = napi_get_named_property(env, jsObject, propertyName, &jsResult); - if (status != napi_ok) { - LOG_ERROR("Convert bundleNameOfOwner failed"); - return false; - } - if (jsResult == nullptr) { + if ((status != napi_ok) || (jsResult == nullptr)) { LOG_ERROR("Convert bundleNameOfOwner failed"); return false; } diff --git a/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp b/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp index f172543a4f2236188e6e5ca2f91fb2fb1e9d4f07..9b3db78ef9fe0179965ffe5c03fc03a85884b5ae 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp @@ -16,6 +16,8 @@ #include "datashare_result_set_proxy.h" #include +#include +#include #include "datashare_result_set.h" #include "datashare_js_utils.h" @@ -24,6 +26,7 @@ namespace OHOS { namespace DataShare { +using namespace std::chrono; constexpr int MAX_INPUT_COUNT = 10; static napi_ref __thread ctorRef_ = nullptr; napi_value DataShareResultSetProxy::NewInstance(napi_env env, std::shared_ptr resultSet) @@ -74,7 +77,7 @@ napi_value DataShareResultSetProxy::GetConstructor(napi_env env) NAPI_CALL(env, napi_get_reference_value(env, ctorRef_, &cons)); return cons; } - LOG_INFO("Get DataShareResultSet constructor"); + LOG_DEBUG("Get DataShareResultSet constructor"); napi_property_descriptor clzDes[] = { DECLARE_NAPI_FUNCTION("goToFirstRow", GoToFirstRow), DECLARE_NAPI_FUNCTION("goToLastRow", GoToLastRow), @@ -272,6 +275,9 @@ napi_value DataShareResultSetProxy::GetBlob(napi_env env, napi_callback_info inf napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); NAPI_ASSERT(env, argc > 0, "Invalid argvs!"); NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex)); + if (columnIndex == -1) { + return DataShareJSUtils::Convert2JSValue(env, blob); + } std::shared_ptr innerResultSet = GetInnerResultSet(env, info); if (innerResultSet != nullptr) { int errCode = innerResultSet->GetBlob(columnIndex, blob); @@ -293,12 +299,12 @@ napi_value DataShareResultSetProxy::GetString(napi_env env, napi_callback_info i napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); NAPI_ASSERT(env, argc > 0, "Invalid argvs!"); NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex)); + if (columnIndex == -1) { + return DataShareJSUtils::Convert2JSValue(env, value); + } std::shared_ptr innerResultSet = GetInnerResultSet(env, info); if (innerResultSet != nullptr) { - int errCode = innerResultSet->GetString(columnIndex, value); - if (errCode != E_OK) { - LOG_ERROR("failed code:%{public}d", errCode); - } + innerResultSet->GetString(columnIndex, value); } else { LOG_ERROR("GetInnerResultSet failed."); } @@ -314,6 +320,9 @@ napi_value DataShareResultSetProxy::GetLong(napi_env env, napi_callback_info inf napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); NAPI_ASSERT(env, argc > 0, "Invalid argvs!"); NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex)); + if (columnIndex == -1) { + return DataShareJSUtils::Convert2JSValue(env, value); + } std::shared_ptr innerResultSet = GetInnerResultSet(env, info); if (innerResultSet != nullptr) { int errCode = innerResultSet->GetLong(columnIndex, value); @@ -335,6 +344,9 @@ napi_value DataShareResultSetProxy::GetDouble(napi_env env, napi_callback_info i napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); NAPI_ASSERT(env, argc > 0, "Invalid argvs!"); NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex)); + if (columnIndex == -1) { + return DataShareJSUtils::Convert2JSValue(env, value); + } std::shared_ptr innerResultSet = GetInnerResultSet(env, info); if (innerResultSet != nullptr) { int errCode = innerResultSet->GetDouble(columnIndex, value); @@ -382,7 +394,10 @@ napi_value DataShareResultSetProxy::GetColumnIndex(napi_env env, napi_callback_i if (innerResultSet != nullptr) { int errCode = innerResultSet->GetColumnIndex(columnName, columnIndex); if (errCode != E_OK) { - LOG_ERROR("failed code:%{public}d", errCode); + auto time = static_cast(duration_cast( + system_clock::now().time_since_epoch()).count()); + LOG_ERROR("failed code:%{public}d columnIndex: %{public}d. times %{public}" PRIu64 ".", + errCode, columnIndex, time); } } else { LOG_ERROR("GetInnerResultSet failed."); @@ -420,6 +435,9 @@ napi_value DataShareResultSetProxy::GetDataType(napi_env env, napi_callback_info napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); NAPI_ASSERT(env, argc > 0, "Invalid argvs!"); NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex)); + if (columnIndex == -1) { + return DataShareJSUtils::Convert2JSValue(env, int32_t(dataType)); + } std::shared_ptr innerResultSet = GetInnerResultSet(env, info); if (innerResultSet != nullptr) { int errCode = innerResultSet->GetDataType(columnIndex, dataType); diff --git a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp index 471c686a431b033600eafbd455719607cc70a875..2a6baba9a9a23e265c6258c1024826fac667981a 100644 --- a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp @@ -68,7 +68,7 @@ napi_value AsyncCall::Call(napi_env env, Context::ExecAction exec) napi_create_async_work(env, nullptr, resource, AsyncCall::OnExecute, AsyncCall::OnComplete, context_, &work); context_->work = work; context_ = nullptr; - napi_queue_async_work(env, work); + napi_queue_async_work_with_qos(env, work, napi_qos_user_initiated); return promise; } diff --git a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp index 31e074c2d5f8983ab7f86ad8938a4b5f73400e57..068d33300b49597ac18456a5883b955d33bf74cd 100644 --- a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp @@ -16,10 +16,13 @@ #include "napi_datashare_observer.h" #include +#include +#include #include "datashare_log.h" namespace OHOS { namespace DataShare { +using namespace std::chrono; NAPIInnerObserver::NAPIInnerObserver(napi_env env, napi_value callback) : env_(env) { @@ -59,7 +62,9 @@ void NAPIInnerObserver::OnComplete(uv_work_t *work, int status) void NAPIInnerObserver::OnChange() { - LOG_DEBUG("NAPIInnerObserver Start"); + auto time = + static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + LOG_INFO("NAPIInnerObserver datashare callback start, times %{public}" PRIu64 ".", time); if (ref_ == nullptr) { LOG_ERROR("ref_ is nullptr"); return; @@ -76,7 +81,8 @@ void NAPIInnerObserver::OnChange() return; } work->data = observerWorker; - int ret = uv_queue_work(loop_, work, [](uv_work_t *work) {}, NAPIInnerObserver::OnComplete); + int ret = uv_queue_work_with_qos(loop_, work, [](uv_work_t *work) {}, + NAPIInnerObserver::OnComplete, uv_qos_user_initiated); if (ret != 0) { LOG_ERROR("uv_queue_work failed"); delete observerWorker; diff --git a/data_share/frameworks/native/common/include/datashare_string_utils.h b/data_share/frameworks/native/common/include/datashare_string_utils.h index 82b377282255798c769504cfcd8a9ced0723c3d9..c7bb1d932c04be61a15ce00a3672bf69e3854ca2 100644 --- a/data_share/frameworks/native/common/include/datashare_string_utils.h +++ b/data_share/frameworks/native/common/include/datashare_string_utils.h @@ -24,9 +24,7 @@ namespace OHOS { namespace DataShare { class DataShareStringUtils { public: - static std::string SurroundWithQuote(std::string value, std::string quote); - static std::string SurroundWithFunction(std::string function, std::string separator, - std::vector array); + static std::string Anonymous(const std::string &name); private: DataShareStringUtils(); diff --git a/data_share/frameworks/native/common/src/datashare_result_set.cpp b/data_share/frameworks/native/common/src/datashare_result_set.cpp index f4d425ef6b7dbd27e4a1777c4dfa42dc90adb237..d65ecd83050c88ca6a4bba41a047bccf11955e5e 100644 --- a/data_share/frameworks/native/common/src/datashare_result_set.cpp +++ b/data_share/frameworks/native/common/src/datashare_result_set.cpp @@ -114,7 +114,6 @@ int DataShareResultSet::GetDataType(int columnIndex, DataType &dataType) AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(static_cast(rowPos_) - startRowPos_, static_cast(columnIndex)); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } dataType = (DataType)cellUnit->type; @@ -170,7 +169,6 @@ int DataShareResultSet::GetBlob(int columnIndex, std::vector &value) AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } @@ -207,7 +205,6 @@ int DataShareResultSet::GetString(int columnIndex, std::string &value) } AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } int type = cellUnit->type; @@ -244,7 +241,6 @@ int DataShareResultSet::GetInt(int columnIndex, int &value) } AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } value = (int)cellUnit->cell.longValue; @@ -259,7 +255,6 @@ int DataShareResultSet::GetLong(int columnIndex, int64_t &value) } AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } @@ -296,7 +291,6 @@ int DataShareResultSet::GetDouble(int columnIndex, double &value) } AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } int type = cellUnit->type; @@ -332,7 +326,6 @@ int DataShareResultSet::IsColumnNull(int columnIndex, bool &isNull) } AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { - LOG_ERROR("cellUnit is null!"); return E_ERROR; } if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) { diff --git a/data_share/frameworks/native/common/src/datashare_string_utils.cpp b/data_share/frameworks/native/common/src/datashare_string_utils.cpp index 1db79753e9d0903dfb102f83695842901981d46c..9dc847b5bf1c91712c72000714c7a755098a640c 100644 --- a/data_share/frameworks/native/common/src/datashare_string_utils.cpp +++ b/data_share/frameworks/native/common/src/datashare_string_utils.cpp @@ -17,32 +17,15 @@ namespace OHOS { namespace DataShare { -std::string DataShareStringUtils::SurroundWithQuote(std::string value, std::string quote) +constexpr int32_t END_SIZE = 6; +constexpr const char *DEFAULT_ANONYMOUS = "******"; +std::string DataShareStringUtils::Anonymous(const std::string &name) { - if (value.empty()) { - return value; + if (name.length() <= END_SIZE) { + return DEFAULT_ANONYMOUS; } - std::string str = quote + value + quote; - return str; -} -// Join array members as parameters of a function call. -std::string DataShareStringUtils::SurroundWithFunction(std::string function, std::string separator, - std::vector array) -{ - std::string builder(function); - builder += "("; - bool isFirst = true; - for (auto text : array) { - if (!isFirst) { - builder = builder + " " + separator + " "; - } else { - isFirst = false; - } - builder += text; - } - builder += ")"; - return builder; + return (DEFAULT_ANONYMOUS + name.substr(name.length() - END_SIZE, END_SIZE)); } DataShareStringUtils::DataShareStringUtils() {} diff --git a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp index 200428da066932b0e647b58b2fc198d82349217b..d03ff73fde8b3f9591559181929ae39230226843 100644 --- a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp +++ b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp @@ -17,6 +17,7 @@ #include "dataobs_mgr_client.h" #include "datashare_log.h" +#include "datashare_string_utils.h" namespace OHOS { namespace DataShare { @@ -72,9 +73,8 @@ void GeneralControllerServiceImpl::RegisterObserver(const Uri &uri, return; } ErrCode ret = obsMgrClient->RegisterObserver(uri, dataObserver); - if (ret != ERR_OK) { - LOG_ERROR("RegisterObserver failed"); - } + LOG_INFO("Register observer ret: %{public}d, uri: %{public}s", ret, + DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } void GeneralControllerServiceImpl::UnregisterObserver(const Uri &uri, @@ -86,9 +86,8 @@ void GeneralControllerServiceImpl::UnregisterObserver(const Uri &uri, return; } ErrCode ret = obsMgrClient->UnregisterObserver(uri, dataObserver); - if (ret != ERR_OK) { - LOG_ERROR("UnregisterObserver failed"); - } + LOG_INFO("Unregister observer ret: %{public}d, uri: %{public}s", ret, + DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } void GeneralControllerServiceImpl::NotifyChange(const Uri &uri) diff --git a/data_share/frameworks/native/consumer/src/datashare_helper.cpp b/data_share/frameworks/native/consumer/src/datashare_helper.cpp index b545f568511e21df0c1e8bc72842d7509c663a6b..e820e543419125959506c740e7620a32465f1623 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper.cpp @@ -163,7 +163,7 @@ std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, cons void DataShareHelper::RegisterObserverExt(const Uri &uri, std::shared_ptr dataObserver, bool isDescendants) { - LOG_INFO("Start"); + LOG_DEBUG("Start"); if (dataObserver == nullptr) { LOG_ERROR("dataObserver is nullptr"); return; @@ -193,7 +193,7 @@ void DataShareHelper::RegisterObserverExt(const Uri &uri, std::shared_ptr dataObserver) { - LOG_INFO("Start"); + LOG_DEBUG("Start"); if (dataObserver == nullptr) { LOG_ERROR("dataObserver is nullptr"); return; @@ -229,7 +229,7 @@ void DataShareHelper::UnregisterObserverExt(const Uri &uri, std::shared_ptr asyncContext); + void SaveNewCallingInfo(napi_env &env); void GetSrcPath(std::string &srcPath); napi_value MakePredicates(napi_env env, const DataSharePredicates &predicates); static napi_value AsyncCallback(napi_env env, napi_callback_info info); @@ -328,6 +329,7 @@ private: static std::string UnWrapProperty(napi_env env, napi_value info, const std::string &key); int32_t InitAsyncCallParams(size_t argc, napi_env &env, napi_value *args); + static constexpr int ACTIVE_INVOKER = 1; JsRuntime& jsRuntime_; std::unique_ptr jsObj_; bool isRecvReply_ = false; diff --git a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp index 637d62dba918821b93afd14d9ad6c6f303153806..c78aa36267757682f8eebc5e31568ba7bb576cd5 100644 --- a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp @@ -43,7 +43,7 @@ DataShareExtAbility* DataShareExtAbility::Create(const std::unique_ptr& return creator_(runtime); } - LOG_INFO("DataShareExtAbility::Create runtime"); + LOG_DEBUG("DataShareExtAbility::Create runtime"); switch (runtime->GetLanguage()) { case Runtime::Language::JS: return JsDataShareExtAbility::Create(runtime); diff --git a/data_share/frameworks/native/provider/src/datashare_stub.cpp b/data_share/frameworks/native/provider/src/datashare_stub.cpp index baf4391b70b12bc3db00bbb4d5a513770801c77a..cc667447ea8ad84ed3c602dbf11fb311bb7c7e1c 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub.cpp @@ -74,7 +74,7 @@ int DataShareStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessagePa return (this->*(itFunc->second))(data, reply); } - LOG_INFO("remote request unhandled: %{public}d", code); + LOG_DEBUG("remote request unhandled: %{public}d", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp index 57c9af57deb78477ac5773505281a1e2a27c7445..3cf33416da99287762517ff15d8173d0a4021d10 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp @@ -45,12 +45,15 @@ bool DataShareStubImpl::CheckCallingPermission(const std::string &permission) std::vector DataShareStubImpl::GetFileTypes(const Uri &uri, const std::string &mimeTypeFilter) { + CallingInfo info; + GetCallingInfo(info); std::vector ret; std::function syncTaskFunc = [=, &ret, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); ret = extension->GetFileTypes(uri, mimeTypeFilter); }; std::function getRetFunc = [=, &ret, client = sptr(this)]() -> bool { @@ -67,12 +70,15 @@ std::vector DataShareStubImpl::GetFileTypes(const Uri &uri, const s int DataShareStubImpl::OpenFile(const Uri &uri, const std::string &mode) { + CallingInfo info; + GetCallingInfo(info); int ret = -1; std::function syncTaskFunc = [=, &ret, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); ret = extension->OpenFile(uri, mode); }; std::function getRetFunc = [=, &ret, client = sptr(this)]() -> bool { @@ -89,12 +95,15 @@ int DataShareStubImpl::OpenFile(const Uri &uri, const std::string &mode) int DataShareStubImpl::OpenRawFile(const Uri &uri, const std::string &mode) { + CallingInfo info; + GetCallingInfo(info); int ret = -1; std::function syncTaskFunc = [=, &ret, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); ret = extension->OpenRawFile(uri, mode); }; uvQueue_->SyncCall(syncTaskFunc); @@ -222,6 +231,7 @@ std::shared_ptr DataShareStubImpl::Query(const Uri &uri, } std::function syncTaskFunc = [=, &columns, &resultSet, &businessError, &extension]() { + extension->SetCallingInfo(info); resultSet = extension->Query(uri, predicates, columns, businessError); }; std::function getRetFunc = [=, &resultSet, &businessError, @@ -230,7 +240,6 @@ std::shared_ptr DataShareStubImpl::Query(const Uri &uri, if (extension == nullptr) { return false; } - extension->SetCallingInfo(info); extension->GetResultSet(resultSet); extension->GetBusinessError(businessError); return (extension->GetRecvReply() != false); @@ -242,12 +251,15 @@ std::shared_ptr DataShareStubImpl::Query(const Uri &uri, std::string DataShareStubImpl::GetType(const Uri &uri) { + CallingInfo info; + GetCallingInfo(info); std::string ret = ""; std::function syncTaskFunc = [=, &ret, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); ret = extension->GetType(uri); }; std::function getRetFunc = [=, &ret, client = sptr(this)]() -> bool { @@ -264,6 +276,8 @@ std::string DataShareStubImpl::GetType(const Uri &uri) int DataShareStubImpl::BatchInsert(const Uri &uri, const std::vector &values) { + CallingInfo info; + GetCallingInfo(info); auto client = sptr(this); auto extension = client->GetOwner(); if (extension == nullptr) { @@ -281,6 +295,7 @@ int DataShareStubImpl::BatchInsert(const Uri &uri, const std::vectorSetCallingInfo(info); ret = extension->BatchInsert(uri, values); }; std::function getRetFunc = [=, &ret, client = sptr(this)]() -> bool { @@ -330,12 +345,15 @@ bool DataShareStubImpl::NotifyChange(const Uri &uri) Uri DataShareStubImpl::NormalizeUri(const Uri &uri) { + CallingInfo info; + GetCallingInfo(info); Uri urivalue(""); std::function syncTaskFunc = [=, &urivalue, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); urivalue = extension->NormalizeUri(uri); }; std::function getRetFunc = [=, &urivalue, client = sptr(this)]() -> bool { @@ -355,12 +373,15 @@ Uri DataShareStubImpl::NormalizeUri(const Uri &uri) Uri DataShareStubImpl::DenormalizeUri(const Uri &uri) { + CallingInfo info; + GetCallingInfo(info); Uri urivalue(""); std::function syncTaskFunc = [=, &urivalue, client = sptr(this)]() { auto extension = client->GetOwner(); if (extension == nullptr) { return; } + extension->SetCallingInfo(info); urivalue = extension->DenormalizeUri(uri); }; std::function getRetFunc = [=, &urivalue, client = sptr(this)]() -> bool { diff --git a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp index 4995d8313d36bb1e10184d8559fe7d1875cce6a5..683805c8bcfea001e09f9bdc7b43db01fc5e1459 100644 --- a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp +++ b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp @@ -15,10 +15,12 @@ #include "datashare_uv_queue.h" #include +#include #include "datashare_log.h" namespace OHOS { namespace DataShare { +using namespace std::chrono; constexpr int WAIT_TIME = 3; constexpr int SLEEP_TIME = 1; constexpr int TRY_TIMES = 2000; @@ -75,7 +77,9 @@ void DataShareUvQueue::SyncCall(NapiVoidFunc func, NapiBoolFunc retFunc) return; } if (uvEntry->condition.wait_for(lock, std::chrono::seconds(WAIT_TIME), [uvEntry] { return uvEntry->done; })) { - LOG_INFO("function ended successfully"); + auto time = static_cast(duration_cast( + system_clock::now().time_since_epoch()).count()); + LOG_INFO("function ended successfully. times %{public}" PRIu64 ".", time); } if (!uvEntry->done && !uv_cancel((uv_req_t*)&work)) { LOG_ERROR("uv_cancel failed."); diff --git a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp index d6bdc09c8b19cd68209aea08c40a3c87c52b152f..0d22f6cf3c80b2c64b93022d15e2c71fe139abff 100644 --- a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp @@ -78,7 +78,7 @@ void JsDataShareExtAbility::Init(const std::shared_ptr &reco std::string moduleName(Extension::abilityInfo_->moduleName); moduleName.append("::").append(abilityInfo_->name); - LOG_INFO("module:%{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str()); + LOG_DEBUG("module:%{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str()); HandleScope handleScope(jsRuntime_); napi_env env = jsRuntime_.GetNapiEnv(); @@ -336,7 +336,11 @@ napi_value JsDataShareExtAbility::CallObjectMethod(const char* name, napi_value } napi_value remoteNapi = nullptr; + NAPI_CallingInfo oldCallingInfo; + NAPI_RemoteObject_saveOldCallingInfo(env, oldCallingInfo); + SaveNewCallingInfo(env); napi_status status = napi_call_function(env, obj, method, count, args, &remoteNapi); + NAPI_RemoteObject_resetOldCallingInfo(env, oldCallingInfo); delete []args; if (status != napi_ok) { return nullptr; @@ -344,6 +348,22 @@ napi_value JsDataShareExtAbility::CallObjectMethod(const char* name, napi_value return handleEscape.Escape(remoteNapi); } +void JsDataShareExtAbility::SaveNewCallingInfo(napi_env &env) +{ + auto newCallingInfo = GetCallingInfo(); + if (newCallingInfo == nullptr) { + LOG_ERROR("newCallingInfo is null."); + return; + } + CallingInfo callingInfo { + .callingPid = newCallingInfo->callingPid, + .callingUid = newCallingInfo->callingUid, + .callingTokenId = newCallingInfo->callingTokenId, + .activeStatus = ACTIVE_INVOKER, + }; + NAPI_RemoteObject_setNewCallingInfo(env, callingInfo); +} + int32_t JsDataShareExtAbility::InitAsyncCallParams(size_t argc, napi_env &env, napi_value *args) { AsyncCallBackPoint *point = new (std::nothrow)AsyncCallBackPoint(); diff --git a/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp b/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp index 646a7a59b8bc2043838d9a23fbf86eca6e99b105..0aa892b01eae84513769fa4cd695385b672dea56 100644 --- a/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp +++ b/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp @@ -39,7 +39,7 @@ public: static void Finalizer(napi_env env, void* data, void* hint) { - LOG_INFO("JsAbilityContext::Finalizer is called"); + LOG_DEBUG("JsAbilityContext::Finalizer is called"); std::unique_ptr(static_cast(data)); } private: @@ -50,7 +50,7 @@ private: napi_value CreateJsDataShareExtAbilityContext(napi_env env, std::shared_ptr context) { - LOG_INFO("CreateJsDataShareExtAbilityContext begin"); + LOG_DEBUG("CreateJsDataShareExtAbilityContext begin"); napi_value objValue = CreateJsExtensionContext(env, context); std::unique_ptr jsContext = std::make_unique(context); napi_wrap(env, objValue, jsContext.release(), JsDataShareExtAbilityContext::Finalizer, nullptr, nullptr); diff --git a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp index 5fbb9cccf68933e83e8173ffbe29583368fee971..4007ed1fe1fe5dfd4ff33e14651f3dbd8da0b4de 100644 --- a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp @@ -59,7 +59,7 @@ AmsMgrProxy* AmsMgrProxy::GetInstance() return proxy; } -int AmsMgrProxy::Connect( +__attribute__ ((no_sanitize("cfi"))) int AmsMgrProxy::Connect( const std::string &uri, const sptr &connect, const sptr &callerToken) { AAFwk::Want want; diff --git a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp index 44fca74eef3f5791b551f2df61ddb9124d44f695..b9d4ff2ecf67a8bb985df498313fc15358169573 100644 --- a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp @@ -80,7 +80,7 @@ void DataShareManagerImpl::LinkToDeath(const sptr remote) if (!remote->AddDeathRecipient(deathRecipient)) { LOG_ERROR("add death recipient failed"); } - LOG_INFO("link to death success"); + LOG_DEBUG("link to death success"); } sptr DataShareManagerImpl::GetDataShareServiceProxy() @@ -123,7 +123,6 @@ void DataShareManagerImpl::RegisterClientDeathObserver() DataShareManagerImpl::DataShareManagerImpl() { - LOG_INFO("construct"); pool_ = std::make_shared(MAX_THREADS, MIN_THREADS); SetDeathCallback([](std::shared_ptr proxy) { LOG_INFO("RecoverObs start"); @@ -134,7 +133,6 @@ DataShareManagerImpl::DataShareManagerImpl() DataShareManagerImpl::~DataShareManagerImpl() { - LOG_INFO("destroy"); } std::shared_ptr DataShareManagerImpl::GetProxy() @@ -171,7 +169,7 @@ std::shared_ptr DataShareManagerImpl::GetServiceProxy() void DataShareManagerImpl::ResetServiceHandle() { - LOG_INFO("enter"); + LOG_DEBUG("enter"); std::lock_guard lock(mutex_); dataMgrService_ = nullptr; dataShareService_ = nullptr; diff --git a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp index 694b7fcefa063527024539edc5d879bf6b6c9840..360151335ea8a0cf85a7c30a07381842ed53bd47 100644 --- a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp @@ -26,7 +26,6 @@ using InterfaceCode = OHOS::DistributedShare::DataShare::DataShareServiceInterfa DataShareServiceProxy::DataShareServiceProxy(const sptr &object) : IRemoteProxy(object) { - LOG_INFO("Construct complete."); } int32_t DataShareServiceProxy::Insert(const Uri &uri, const DataShareValuesBucket &value) diff --git a/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp b/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp index d7f9651a1a557a1d729fe8dbb8c369e2cdff3d2f..6b3f3a8ab7949679a0c22f7b45a00e8cc3b2fdee 100644 --- a/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp +++ b/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp @@ -20,12 +20,12 @@ namespace OHOS { namespace DataShare { DataShareClientDeathObserverStub::DataShareClientDeathObserverStub() { - LOG_INFO("this client death observer"); + LOG_DEBUG("this client death observer"); } DataShareClientDeathObserverStub::~DataShareClientDeathObserverStub() { - LOG_INFO("destructor this client death observer"); + LOG_DEBUG("destructor this client death observer"); } } } diff --git a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp index 6ec27fd330db834f486167025b31f1c5e10681dc..24314937175bc6a24fe0b990023c51d996a15f5a 100644 --- a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp +++ b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp @@ -280,7 +280,7 @@ void PublishedDataSubscriberManager::EmitOnEnable(std::map buffer= {10, 20, 30}; + data.datas_.emplace_back("datashareproxy://com.acts.ohos.data.datasharetest/test", SUBSCRIBER_ID, buffer); + std::string bundleName = "com.acts.ohos.data.datasharetest"; + std::vector results = helper->Publish(data, bundleName); + EXPECT_EQ(results.size(), data.datas_.size()); + for (auto const &result : results) { + EXPECT_EQ(result.errCode_, 0); + } + + int errCode = 0; + auto getData = helper->GetPublishedData(bundleName, errCode); + EXPECT_EQ(errCode, 0); + EXPECT_EQ(getData.datas_.size(), data.datas_.size()); + for (auto &publishedDataItem : getData.datas_) { + EXPECT_EQ(publishedDataItem.subscriberId_, SUBSCRIBER_ID); + bool isAshmem = publishedDataItem.IsAshmem(); + EXPECT_TRUE(isAshmem); + auto value = publishedDataItem.GetData(); + EXPECT_EQ(std::get>(value)[0], buffer[0]); + } + LOG_INFO("ProxyDatasTest_Publish_Test_003::End"); +} + HWTEST_F(ProxyDatasTest, ProxyDatasTest_CombinationRdbData_Test_001, TestSize.Level0) { LOG_INFO("ProxyDatasTest_CombinationRdbData_Test_001::Start"); diff --git a/datamgr_service/conf/config.json b/datamgr_service/conf/config.json index 55cca51f6d32653af796b05705fb23576c1f24cf..d82bc2104a7ba07962ddedfbd14e474c8e31dba4 100644 --- a/datamgr_service/conf/config.json +++ b/datamgr_service/conf/config.json @@ -27,9 +27,7 @@ "bundleChecker": { "checkers": [ "SystemChecker", - "BundleChecker", - "PackageChecker", - "ExternalChecker" + "BundleChecker" ], "trusts": [ { @@ -37,7 +35,8 @@ "appId": "bundle_manager_service", "checker": "SystemChecker" } - ] + ], + "distrusts": [] }, "networks": { "chains": [ @@ -92,4 +91,4 @@ "backupInternal" : 36000, "backupNumber" : 20 } -} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index 01eb4c444cc7f288a4965d1d7478331712a54a76..864b3c660183d496b18e36fe9693d61728e2eaf6 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -142,20 +142,6 @@ DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const return DBStatus::OK; } -DeviceType ProcessCommunicatorImpl::GetDeviceType(int32_t deviceType) -{ - switch (deviceType) { - case 0x06D: // SMART_WATCH - case 0x0A1: // SMART_WATCH - return SMART_WATCH; - case 0x085: // KID_WATCH - case 0x0A3: // KID_WATCH - return KID_WATCH; - default: - return OTHERS; - } -} - uint32_t ProcessCommunicatorImpl::GetMtuSize() { return MTU_SIZE; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index 488361ab52a6a6ee6a2657454ec5a527cbc5a955..09ad9fa6954789ab19a5d9d5d6d65c68c8f63c70 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -40,6 +40,12 @@ public: ~SoftBusAdapter(); static std::shared_ptr GetInstance(); + struct ServerSocketInfo { + std::string name; /**< Peer socket name */ + std::string networkId; /**< Peer network ID */ + std::string pkgName; /**< Peer package name */ + }; + // add DataChangeListener to watch data change; Status StartWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); @@ -66,7 +72,7 @@ public: void OnServerShutdown(int32_t socket); - bool GetPeerSocketInfo(int32_t socket, PeerSocketInfo &info); + bool GetPeerSocketInfo(int32_t socket, ServerSocketInfo &info); int32_t Broadcast(const PipeInfo &pipeInfo, uint16_t mask); void OnBroadcast(const DeviceId &device, uint16_t mask); @@ -97,7 +103,7 @@ private: ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; Time next_ = INVALID_NEXT; - ConcurrentMap peerSocketInfos_; + ConcurrentMap peerSocketInfos_; ISocketListener clientListener_{}; ISocketListener serverListener_{}; int32_t socket_ = 0; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index 32ba0fd659f69210b045d84f7c035d34b159c23f..3915b30a62b49ae1b86f2d9f9a67c58f00813f22 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -52,7 +52,6 @@ public: 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); - static std::string GetPipeId(const char *name); public: // notify all listeners when received message @@ -216,7 +215,7 @@ SoftBusAdapter::Task SoftBusAdapter::GetCloseSessionTask() } auto expireTime = conn->GetExpireTime(); if (expireTime <= now) { - ZLOGD("[timeout] close session socket:%{public}d", conn->GetSocket()); + ZLOGI("[timeout] close session socket:%{public}d", conn->GetSocket()); connToClose.emplace_back(conn); } else { holdConnects.emplace_back(conn); @@ -277,7 +276,23 @@ uint32_t SoftBusAdapter::GetMtuSize(const DeviceId &deviceId) uint32_t SoftBusAdapter::GetTimeout(const DeviceId &deviceId) { - return DEFAULT_TIMEOUT; + uint32_t interval = DEFAULT_TIMEOUT; + connects_.ComputeIfPresent(deviceId.deviceId, [&interval](auto, auto &connects) { + uint32_t time = 0; + for (auto conn : connects) { + if (conn == nullptr) { + continue; + } + if (time < conn->GetTimeout()) { + time = conn->GetTimeout(); + } + } + if (time != 0) { + interval = time; + } + return true; + }); + return interval; } std::string SoftBusAdapter::DelConnect(int32_t socket) @@ -403,19 +418,19 @@ void AppDataListenerWrap::OnServerBind(int32_t socket, PeerSocketInfo info) softBusAdapter_->OnBind(socket, info); std::string peerDevUuid = DmAdapter::GetInstance().GetUuidByNetworkId(std::string(info.networkId)); - ZLOGD("[OnServerBind] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s", socket, info.name, + ZLOGI("[OnServerBind] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s", socket, info.name, KvStoreUtils::ToBeAnonymous(peerDevUuid).c_str()); } void AppDataListenerWrap::OnServerShutdown(int32_t socket, ShutdownReason reason) { softBusAdapter_->OnServerShutdown(socket); - ZLOGD("Shut down reason:%{public}d socket id:%{public}d", reason, socket); + ZLOGI("Shut down reason:%{public}d socket id:%{public}d", reason, socket); } void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen) { - PeerSocketInfo info; + SoftBusAdapter::ServerSocketInfo info; if (!softBusAdapter_->GetPeerSocketInfo(socket, info)) { ZLOGE("Get peer socket info failed, socket id %{public}d", socket); return; @@ -423,9 +438,9 @@ void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data std::string peerDevUuid = DmAdapter::GetInstance().GetUuidByNetworkId(std::string(info.networkId)); ZLOGD("[OnBytesReceived] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s, data len:%{public}u", - socket, info.name, KvStoreUtils::ToBeAnonymous(peerDevUuid).c_str(), dataLen); + socket, info.name.c_str(), KvStoreUtils::ToBeAnonymous(peerDevUuid).c_str(), dataLen); - std::string pipeId = GetPipeId(info.name); + std::string pipeId = info.name; if (pipeId.empty()) { ZLOGE("pipId is invalid"); return; @@ -434,23 +449,13 @@ void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data NotifyDataListeners(reinterpret_cast(data), dataLen, peerDevUuid, { pipeId, "" }); } -std::string AppDataListenerWrap::GetPipeId(const char *name) -{ - std::string nameStr = name; - auto pos = nameStr.find('_'); - if (pos != std::string::npos) { - return nameStr.substr(0, pos); - } - return ""; -} - void AppDataListenerWrap::NotifyDataListeners(const uint8_t *data, const int size, const std::string &deviceId, const PipeInfo &pipeInfo) { softBusAdapter_->NotifyDataListeners(data, size, deviceId, pipeInfo); } -bool SoftBusAdapter::GetPeerSocketInfo(int32_t socket, PeerSocketInfo& info) +bool SoftBusAdapter::GetPeerSocketInfo(int32_t socket, ServerSocketInfo &info) { auto it = peerSocketInfos_.Find(socket); if (it.first) { @@ -462,7 +467,11 @@ bool SoftBusAdapter::GetPeerSocketInfo(int32_t socket, PeerSocketInfo& info) void SoftBusAdapter::OnBind(int32_t socket, PeerSocketInfo info) { - peerSocketInfos_.Insert(socket, info); + ServerSocketInfo socketInfo; + socketInfo.name = info.name; + socketInfo.networkId = info.networkId; + socketInfo.pkgName = info.pkgName; + peerSocketInfos_.Insert(socket, socketInfo); } void SoftBusAdapter::OnServerShutdown(int32_t socket) diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp index 72b514769ce6f28214947c537f1ba012c4636eba..4a18383f372ad67186ed842e5c319f6a1974d54a 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -56,6 +56,11 @@ uint32_t SoftBusClient::GetMtuSize() const return mtu_; } +uint32_t SoftBusClient::GetTimeout() const +{ + return DEFAULT_TIMEOUT; +} + Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener *listener) { std::lock_guard lock(mutex_); @@ -70,7 +75,7 @@ Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener * ZLOGE("send data to socket%{public}d failed, ret:%{public}d.", socket_, ret); return Status::ERROR; } - expireTime_ = std::chrono::steady_clock::now() + SESSION_CLOSE_DELAY; + expireTime_ = CalcExpireTime(); return Status::SUCCESS; } @@ -90,8 +95,7 @@ Status SoftBusClient::OpenConnect(const ISocketListener *listener) socketInfo.peerName = const_cast(peerName.c_str()); std::string networkId = DmAdapter::GetInstance().ToNetworkID(device_.deviceId); socketInfo.peerNetworkId = const_cast(networkId.c_str()); - std::string clientName = pipe_.pipeId + "_client_" + socketInfo.peerNetworkId; - socketInfo.name = const_cast(clientName.c_str()); + socketInfo.name = const_cast(peerName.c_str()); std::string pkgName = "ohos.distributeddata"; socketInfo.pkgName = pkgName.data(); socketInfo.dataType = DATA_TYPE_BYTES; @@ -160,7 +164,7 @@ int32_t SoftBusClient::GetSocket() const void SoftBusClient::UpdateExpireTime() { - auto expireTime = std::chrono::steady_clock::now() + SESSION_CLOSE_DELAY; + auto expireTime = CalcExpireTime(); std::lock_guard lock(mutex_); if (expireTime > expireTime_) { expireTime_ = expireTime; @@ -178,4 +182,10 @@ uint32_t SoftBusClient::GetQoSType() const { return type_ % QOS_COUNT; } + +SoftBusClient::Time SoftBusClient::CalcExpireTime() const +{ + auto delay = type_ == QOS_BR ? BR_CLOSE_DELAY : HML_CLOSE_DELAY; + return std::chrono::steady_clock::now() + delay; +} } // namespace OHOS::AppDistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h index a4ba06ce3ffbe3321cf1a1fac35796210b00e58c..acc343e9a7155cd5772033d78bef325d64ed0e1d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -38,11 +38,11 @@ public: using Time = std::chrono::steady_clock::time_point; using Duration = std::chrono::steady_clock::duration; - static constexpr Duration P2P_CLOSE_DELAY = std::chrono::seconds(3); Status SendData(const DataInfo &dataInfo, const ISocketListener *listener); bool operator==(int32_t socket) const; bool operator==(const std::string &deviceId) const; uint32_t GetMtuSize() const; + uint32_t GetTimeout() const; Time GetExpireTime() const; int32_t GetSocket() const; uint32_t GetQoSType() const; @@ -52,14 +52,14 @@ private: Status OpenConnect(const ISocketListener *listener); Status Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); std::pair GetMtu(int32_t socket); + Time CalcExpireTime() const; static constexpr int32_t INVALID_SOCKET_ID = -1; - static constexpr uint32_t DEFAULT_TIMEOUT = 15 * 1000; - static constexpr uint32_t WAIT_MAX_TIME = 10; + static constexpr uint32_t DEFAULT_TIMEOUT = 30 * 1000; static constexpr uint32_t DEFAULT_MTU_SIZE = 4096u; - static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB - static constexpr Duration SESSION_CLOSE_DELAY = std::chrono::seconds(3); - static constexpr Duration SESSION_OPEN_DELAY = std::chrono::seconds(20); + static constexpr Duration BR_CLOSE_DELAY = std::chrono::seconds(5); + static constexpr Duration HML_CLOSE_DELAY = std::chrono::seconds(3); + static constexpr Duration MAX_DELAY = std::chrono::seconds(60 * 60 * 24 * 365); static constexpr uint32_t QOS_COUNT = 3; static constexpr QosTV QOS_INFOS[QOS_BUTT][QOS_COUNT] = { { // BR QOS @@ -79,8 +79,7 @@ private: PipeInfo pipe_; DeviceId device_; uint32_t mtu_; - std::function getConnStatus_; - Time expireTime_ = std::chrono::steady_clock::now() + SESSION_OPEN_DELAY; + Time expireTime_ = std::chrono::steady_clock::now() + MAX_DELAY; int32_t socket_ = INVALID_SOCKET_ID; int32_t bindState_ = -1; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h index b39e02be6ca65fa030cc9f7eee078995b7d4ffb9..8f60d6d01778162761161400699a0d10f9b8687c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -28,13 +28,6 @@ struct API_EXPORT DeviceInfo { uint32_t deviceType; }; -enum DeviceType { - SMART_WATCH, - KID_WATCH, - PHONE, - OTHERS, -}; - enum RouteType : int32_t { INVALID_ROUTE_TYPE = -1, ROUTE_TYPE_ALL = 0, diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index d337052617fb9dff3801eb4464ebcc7e308842d9..217fd5f7f1d81a5de44e8aa5340ec1f79489d716 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -66,7 +66,6 @@ public: private: void OnMessage(const DeviceInfo &info, const uint8_t *ptr, const int size, const PipeInfo &pipeInfo) const override; - static DeviceType GetDeviceType(int32_t deviceType); std::string thisProcessLabel_; OnDeviceChange onDeviceChangeHandler_; diff --git a/datamgr_service/services/distributeddataservice/app/BUILD.gn b/datamgr_service/services/distributeddataservice/app/BUILD.gn index 6b1c62a20f97bdf63c2919b7f93f3ea245bd06e6..9435af0660a79372d46cb8bb22f2f10205724fe4 100644 --- a/datamgr_service/services/distributeddataservice/app/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/BUILD.gn @@ -83,6 +83,7 @@ ohos_shared_library("distributeddataservice") { debug = false } sources = [ + "src/db_info_handle_impl.cpp", "src/feature_stub_impl.cpp", "src/kvstore_account_observer.cpp", "src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg index b9d527d720f2198ec3d74573b8fc67b159d123bc..d5d214a102a1e5791cfe2cd5865cdd539d8d91b3 100644 --- a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg +++ b/datamgr_service/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"], + "gid" : ["system","shell","readproc","ddms","dfs_share","netsys_socket"], "writepid":[ "/dev/cpuset/foreground/tasks", "/dev/stune/foreground/tasks", @@ -37,7 +37,8 @@ "ohos.permission.CLOUDFILE_SYNC", "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT", "ohos.permission.GET_BUNDLE_INFO", - "ohos.permission.GET_NETWORK_INFO" + "ohos.permission.GET_NETWORK_INFO", + "ohos.permission.INTERNET" ] } ] diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp index 557c99900c50b0bcac7b067d332ee225030660aa..69c2739e350cd64f97fb15244da9e174875f944d 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp @@ -44,6 +44,12 @@ bool BundleChecker::SetTrustInfo(const CheckerManager::Trust &trust) return true; } +bool BundleChecker::SetDistrustInfo(const CheckerManager::Distrust &distrust) +{ + distrusts_[distrust.bundleName] = distrust.appId; + return true; +} + std::string BundleChecker::GetAppId(const CheckerManager::StoreInfo &info) { if (AccessTokenKit::GetTokenTypeFlag(info.tokenId) != TOKEN_HAP) { @@ -80,5 +86,27 @@ bool BundleChecker::IsValid(const CheckerManager::StoreInfo &info) return tokenInfo.bundleName == info.bundleName; } + +bool BundleChecker::IsDistrust(const CheckerManager::StoreInfo &info) +{ + if (AccessTokenKit::GetTokenTypeFlag(info.tokenId) != TOKEN_HAP) { + return false; + } + HapTokenInfo tokenInfo; + auto result = AccessTokenKit::GetHapTokenInfo(info.tokenId, tokenInfo); + if (result != RET_SUCCESS) { + ZLOGE("token:0x%{public}x, result:%{public}d", info.tokenId, result); + return false; + } + if (!info.bundleName.empty() && tokenInfo.bundleName != info.bundleName) { + ZLOGE("bundlename:%{public}s <-> %{public}s", info.bundleName.c_str(), tokenInfo.bundleName.c_str()); + return false; + } + auto it = distrusts_.find(info.bundleName); + if (it != distrusts_.end() && (it->second == tokenInfo.appID)) { + return true; + } + return false; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h index e55a20a56a56e42b06a40eb894811cd4ea7304c6..5392347388110f27a6069f506d2c9c131a7bb726 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h +++ b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h @@ -24,12 +24,15 @@ public: ~BundleChecker(); void Initialize() override; bool SetTrustInfo(const CheckerManager::Trust &trust) override; + bool SetDistrustInfo(const CheckerManager::Distrust &distrust) override; std::string GetAppId(const CheckerManager::StoreInfo &info) override; bool IsValid(const CheckerManager::StoreInfo &info) override; + bool IsDistrust(const CheckerManager::StoreInfo &info) override; private: static BundleChecker instance_; std::map trusts_; + std::map distrusts_; }; } // namespace DistributedData } // namespace OHOS -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CHECKER_BUNDLE_CHECKER_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CHECKER_BUNDLE_CHECKER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp index c653d9576b4338d1e1e065d464d03293546bce90..aff8299e0b4ca9715f2971b98b3c7c10b7dc1559 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp @@ -40,6 +40,12 @@ bool SystemChecker::SetTrustInfo(const CheckerManager::Trust &trust) return true; } +bool SystemChecker::SetDistrustInfo(const CheckerManager::Distrust &distrust) +{ + distrusts_[distrust.bundleName] = distrust.appId; + return true; +} + std::string SystemChecker::GetAppId(const CheckerManager::StoreInfo &info) { if (!IsValid(info)) { @@ -55,5 +61,17 @@ bool SystemChecker::IsValid(const CheckerManager::StoreInfo &info) auto type = AccessTokenKit::GetTokenTypeFlag(info.tokenId); return (type == TOKEN_NATIVE || type == TOKEN_SHELL); } + +bool SystemChecker::IsDistrust(const CheckerManager::StoreInfo &info) +{ + if (!IsValid(info)) { + return false; + } + auto it = distrusts_.find(info.bundleName); + if (it != distrusts_.end()) { + return true; + } + return false; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.h b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.h index 1f441908e5892b1bf169befbbd34e8c7e69961d7..f81bcc99557c56a6b4e1038a93f27a2c8abb49fd 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.h +++ b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.h @@ -25,12 +25,15 @@ public: ~SystemChecker(); void Initialize() override; bool SetTrustInfo(const CheckerManager::Trust &trust) override; + bool SetDistrustInfo(const CheckerManager::Distrust &distrust) override; std::string GetAppId(const CheckerManager::StoreInfo &info) override; bool IsValid(const CheckerManager::StoreInfo &info) override; + bool IsDistrust(const CheckerManager::StoreInfo &info) override; private: std::map trusts_; + std::map distrusts_; static SystemChecker instance_; }; } // namespace DistributedData } // namespace OHOS -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_SYSTEM_CHECKER_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_SYSTEM_CHECKER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..014471b2aa61b7a2eb1658dc722b5f72b81a5ee6 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.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 "db_info_handle_impl.h" +namespace OHOS::DistributedKv { +bool DBInfoHandleImpl::IsSupport() +{ + return true; +} +bool DBInfoHandleImpl::IsNeedAutoSync(const std::string& userId, const std::string& appId, + const std::string& storeId, const DistributedDB::DeviceInfos& devInfo) +{ + return true; +} +} diff --git a/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.h b/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..b764db1fb8c5c95c4f0d49c465ba5c099f5fe393 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/app/src/db_info_handle_impl.h @@ -0,0 +1,31 @@ +/* +* 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_DB_INFO_HANDLE_IMPL_H +#define DISTRIBUTEDDATAMGR_DB_INFO_HANDLE_IMPL_H + +#include "db_info_handle.h" +namespace OHOS::DistributedKv { +using namespace DistributedDB; +class DBInfoHandleImpl : public DBInfoHandle { +public: + // return true if you can notify with RuntimeConfig::NotifyDBInfo + bool IsSupport() override; + // check is need auto sync when remote db is open + // return true if data has changed + bool IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId, + const DeviceInfos &devInfo) override; +}; +} +#endif //DISTRIBUTEDDATAMGR_DB_INFO_HANDLE_IMPL_H diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp index 9e31afef1e72fe7d8ffa13c485aeee8959c4baa0..45409734eb65867b5e0c41a6f112f7321bb2bcae 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -28,6 +28,7 @@ #include "communicator_context.h" #include "config_factory.h" #include "crypto_manager.h" +#include "db_info_handle_impl.h" #include "device_manager_adapter.h" #include "device_matrix.h" #include "dump/dump_manager.h" @@ -71,7 +72,7 @@ using DBConfig = DistributedDB::RuntimeConfig; REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true); KvStoreDataService::KvStoreDataService(bool runOnCreate) - : SystemAbility(runOnCreate), mutex_(), clients_() + : SystemAbility(runOnCreate), clients_() { ZLOGI("begin."); if (executors_ == nullptr) { @@ -83,7 +84,7 @@ KvStoreDataService::KvStoreDataService(bool runOnCreate) } KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate) - : SystemAbility(systemAbilityId, runOnCreate), mutex_(), clients_() + : SystemAbility(systemAbilityId, runOnCreate), clients_() { ZLOGI("begin"); if (executors_ == nullptr) { @@ -97,7 +98,7 @@ KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate KvStoreDataService::~KvStoreDataService() { ZLOGI("begin."); - clients_.clear(); + clients_.Clear(); features_.Clear(); } @@ -133,6 +134,7 @@ void KvStoreDataService::Initialize() return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta); }; DBConfig::SetTranslateToDeviceIdCallback(translateCall); + DistributedDB::RuntimeConfig::SetDBInfoHandle(std::make_shared()); } sptr KvStoreDataService::GetFeatureInterface(const std::string &name) @@ -192,22 +194,27 @@ Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr< ZLOGW("check bundleName:%{public}s uid:%{public}d failed.", appId.appId.c_str(), info.uid); return Status::PERMISSION_DENIED; } - - std::lock_guard lg(mutex_); - auto iter = clients_.find(info.tokenId); - // Ignore register with same tokenId and pid - if (iter != clients_.end() && IPCSkeleton::GetCallingPid() == iter->second.GetPid()) { - ZLOGW("bundleName:%{public}s, uid:%{public}d, pid:%{public}d has already registered.", - appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid()); - return Status::SUCCESS; - } - - clients_.erase(info.tokenId); - auto it = clients_.emplace(std::piecewise_construct, std::forward_as_tuple(info.tokenId), + KvStoreClientDeathObserverImpl kvStoreClientDeathObserver(*this); + auto inserted = clients_.Emplace( + [&info, &appId, &kvStoreClientDeathObserver](decltype(clients_)::map_type &entries) { + auto it = entries.find(info.tokenId); + if (it == entries.end()) { + return true; + } + if (IPCSkeleton::GetCallingPid() == it->second.GetPid()) { + ZLOGW("bundleName:%{public}s, uid:%{public}d, pid:%{public}d has already registered.", + appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid()); + return false; + } + kvStoreClientDeathObserver = std::move(it->second); + entries.erase(it); + return true; + }, + std::piecewise_construct, std::forward_as_tuple(info.tokenId), std::forward_as_tuple(appId, *this, std::move(observer))); - ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d inserted:%{public}s.", - appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid(), it.second ? "success" : "failed"); - return it.second ? Status::SUCCESS : Status::ERROR; + ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d, inserted:%{public}s.", appId.appId.c_str(), info.uid, + IPCSkeleton::GetCallingPid(), inserted ? "success" : "failed"); + return Status::SUCCESS; } Status KvStoreDataService::AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId) @@ -216,8 +223,11 @@ Status KvStoreDataService::AppExit(pid_t uid, pid_t pid, uint32_t token, const A // memory of parameter appId locates in a member of clientDeathObserverMap_ and will be freed after // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation. AppId appIdTmp = appId; - std::lock_guard lg(mutex_); - clients_.erase(token); + KvStoreClientDeathObserverImpl impl(*this); + clients_.ComputeIfPresent(token, [&impl](auto &, auto &value) { + impl = std::move(value); + return false; + }); return Status::SUCCESS; } @@ -540,7 +550,7 @@ KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverIm : appId_(appId), dataService_(service), observerProxy_(std::move(observer)), deathRecipient_(new KvStoreDeathRecipient(*this)) { - ZLOGI("KvStoreClientDeathObserverImpl"); + ZLOGD("KvStoreClientDeathObserverImpl"); uid_ = IPCSkeleton::GetCallingUid(); pid_ = IPCSkeleton::GetCallingPid(); token_ = IPCSkeleton::GetCallingTokenID(); @@ -551,6 +561,33 @@ KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverIm ZLOGW("observerProxy_ is nullptr"); } } +KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl(KvStoreDataService &service) + : dataService_(service) +{ + Reset(); +} + +KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl( + KvStoreDataService::KvStoreClientDeathObserverImpl &&impl) + : dataService_(impl.dataService_) +{ + uid_ = impl.uid_; + pid_ = impl.pid_; + token_ = impl.token_; + appId_.appId = std::move(impl.appId_.appId); + impl.Reset(); +} + +KvStoreDataService::KvStoreClientDeathObserverImpl &KvStoreDataService::KvStoreClientDeathObserverImpl::operator=( + KvStoreDataService::KvStoreClientDeathObserverImpl &&impl) +{ + uid_ = impl.uid_; + pid_ = impl.pid_; + token_ = impl.token_; + appId_.appId = std::move(impl.appId_.appId); + impl.Reset(); + return *this; +} KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverImpl() { @@ -559,6 +596,9 @@ KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverI ZLOGI("remove death recipient"); observerProxy_->RemoveDeathRecipient(deathRecipient_); } + if (uid_ == INVALID_UID || pid_ == INVALID_PID || token_ == INVALID_TOKEN || !appId_.IsValid()) { + return; + } dataService_.features_.ForEachCopies([this](const auto &, sptr &value) { value->OnAppExit(uid_, pid_, token_, appId_); return false; @@ -576,6 +616,14 @@ pid_t KvStoreDataService::KvStoreClientDeathObserverImpl::GetPid() const return pid_; } +void KvStoreDataService::KvStoreClientDeathObserverImpl::Reset() +{ + uid_ = INVALID_UID; + pid_ = INVALID_PID; + token_ = INVALID_TOKEN; + appId_.appId = ""; +} + KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvStoreDeathRecipient( KvStoreClientDeathObserverImpl &kvStoreClientDeathObserverImpl) : kvStoreClientDeathObserverImpl_(kvStoreClientDeathObserverImpl) @@ -585,7 +633,7 @@ KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvSto KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::~KvStoreDeathRecipient() { - ZLOGI("KvStore Client Death Observer"); + ZLOGD("~KvStore Client Death Observer"); } void KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::OnRemoteDied( diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h index 09f7784e26f57fdfef855da459ac9d5ff13212c3..1f7d001ac08ecac9ab7b7e83578548008b15586f 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -121,6 +121,9 @@ private: class KvStoreClientDeathObserverImpl { public: KvStoreClientDeathObserverImpl(const AppId &appId, KvStoreDataService &service, sptr observer); + explicit KvStoreClientDeathObserverImpl(KvStoreDataService &service); + explicit KvStoreClientDeathObserverImpl(KvStoreClientDeathObserverImpl &&impl); + KvStoreClientDeathObserverImpl &operator=(KvStoreClientDeathObserverImpl &&impl); virtual ~KvStoreClientDeathObserverImpl(); @@ -137,6 +140,7 @@ private: KvStoreClientDeathObserverImpl &kvStoreClientDeathObserverImpl_; }; void NotifyClientDie(); + void Reset(); pid_t uid_; pid_t pid_; uint32_t token_; @@ -166,8 +170,7 @@ private: static constexpr int TEN_SEC = 10; - std::mutex mutex_; - std::map clients_; + ConcurrentMap clients_; std::shared_ptr accountEventObserver_; std::shared_ptr security_; @@ -180,6 +183,9 @@ private: static constexpr char FORMAT_BLANK_SPACE = ' '; static constexpr int32_t PRINTF_COUNT_2 = 2; static constexpr int MAXIMUM_PARAMETER_LIMIT = 3; + static constexpr pid_t INVALID_UID = -1; + static constexpr pid_t INVALID_PID = -1; + static constexpr uint32_t INVALID_TOKEN = 0; }; } #endif // KVSTORE_DATASERVICE_H diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 8111325aa53f00196b7640fba6621a0a43fae473..aa1ececae0e2146e6fe72e3079a4c889f049365a 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -32,10 +32,13 @@ #include "log_print.h" #include "matrix_event.h" #include "metadata/meta_data_manager.h" +#include "metadata/version_meta_data.h" +#include "runtime_config.h" #include "utils/anonymous.h" #include "utils/block_integer.h" #include "utils/crypto.h" #include "utils/ref_count.h" +#include "utils/converter.h" namespace OHOS { namespace DistributedKv { @@ -47,6 +50,7 @@ using namespace DistributedDB; using namespace OHOS::AppDistributedKv; KvStoreMetaManager::MetaDeviceChangeListenerImpl KvStoreMetaManager::listener_; +KvStoreMetaManager::DBInfoDeviceChangeListenerImpl KvStoreMetaManager::dbInfoListener_; KvStoreMetaManager::KvStoreMetaManager() : metaDelegate_(nullptr), metaDBDirectory_(DirectoryManager::GetInstance().GetMetaStorePath()), @@ -80,14 +84,21 @@ void KvStoreMetaManager::InitMetaListener() InitMetaData(); auto status = DmAdapter::GetInstance().StartWatchDeviceChange(&listener_, { "metaMgr" }); if (status != AppDistributedKv::Status::SUCCESS) { - ZLOGW("register failed."); + ZLOGW("register metaMgr failed: %{public}d.", status); return; } - ZLOGI("register meta device change success."); + status = DmAdapter::GetInstance().StartWatchDeviceChange(&dbInfoListener_, { "notifyDbInfos" }); + if (status != AppDistributedKv::Status::SUCCESS) { + ZLOGW("register notifyDbInfos failed: %{public}d.", status); + return; + } + ZLOGI("register metaMgr and notifyDbInfos device change success."); + SubscribeMetaKvStore(); SyncMeta(); InitBroadcast(); InitDeviceOnline(); + NotifyAllAutoSyncDBInfo(); } void KvStoreMetaManager::InitBroadcast() @@ -171,9 +182,34 @@ void KvStoreMetaManager::InitMetaData() MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data, true))) { ZLOGE("save meta fail"); } + UpdateMetaData(); + SetSyncer(); ZLOGI("end."); } +void KvStoreMetaManager::UpdateMetaData() +{ + VersionMetaData versionMeta; + if (!MetaDataManager::GetInstance().LoadMeta(versionMeta.GetKey(), versionMeta, true) + || versionMeta.version < META_VERSION) { + std::vector metaDataList; + std::string prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid }); + MetaDataManager::GetInstance().LoadMeta(prefix, metaDataList); + for (auto metaData : metaDataList) { + MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true); + if (CheckerManager::GetInstance().IsDistrust(Converter::ConvertToStoreInfo(metaData)) || + (metaData.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN + && metaData.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END)) { + MetaDataManager::GetInstance().DelMeta(metaData.GetKey()); + } + } + } + if (versionMeta.version != VersionMetaData::CURRENT_VERSION) { + versionMeta.version = VersionMetaData::CURRENT_VERSION; + MetaDataManager::GetInstance().SaveMeta(versionMeta.GetKey(), versionMeta, true); + } +} + void KvStoreMetaManager::InitMetaParameter() { ZLOGI("start."); @@ -213,8 +249,13 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore() std::lock_guard lock(mutex_); if (metaDelegate_ == nullptr) { metaDelegate_ = CreateMetaKvStore(); + auto fullName = GetBackupPath(); + auto backup = [fullName](const auto &store) -> int32_t { + DistributedDB::CipherPassword password; + return store->Export(fullName, password); + }; + MetaDataManager::GetInstance().Initialize(metaDelegate_, backup); } - ConfigMetaDataManager(); return metaDelegate_; } @@ -261,13 +302,8 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() return NbDelegate(delegate, release); } -void KvStoreMetaManager::ConfigMetaDataManager() +void KvStoreMetaManager::SetSyncer() { - auto fullName = GetBackupPath(); - auto backup = [fullName](const auto &store) -> int32_t { - DistributedDB::CipherPassword password; - return store->Export(fullName, password); - }; auto syncer = [this](const auto &store, int32_t status) { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); auto size = DmAdapter::GetInstance().GetOnlineSize(); @@ -284,7 +320,7 @@ void KvStoreMetaManager::ConfigMetaDataManager() executors_->Reset(delaySyncTaskId_, std::chrono::milliseconds(DELAY_SYNC)); } }; - MetaDataManager::GetInstance().Initialize(metaDelegate_, backup, syncer); + MetaDataManager::GetInstance().SetSyncer(syncer); } std::function KvStoreMetaManager::SyncTask(const NbDelegate &store, int32_t status) @@ -370,6 +406,9 @@ void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvSt HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted()); HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated()); HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted()); + KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::INSERT, data.GetEntriesInserted()); + KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated()); + KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::DELETE, data.GetEntriesDeleted()); } void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges(CHANGE_FLAG flag, @@ -423,5 +462,101 @@ void KvStoreMetaManager::BindExecutor(std::shared_ptr executors) { executors_ = executors; } + +void KvStoreMetaManager::OnDataChange(CHANGE_FLAG flag, const std::list& changedData) +{ + for (const auto& entry : changedData) { + std::string key(entry.key.begin(), entry.key.end()); + if (key.find(StoreMetaData::GetKey({})) != 0) { + continue; + } + StoreMetaData metaData; + metaData.Unmarshall({ entry.value.begin(), entry.value.end() }); + if (!metaData.isAutoSync) { + continue; + } + std::vector dbInfos; + AddDbInfo(metaData, dbInfos, flag == CHANGE_FLAG::DELETE); + DistributedDB::RuntimeConfig::NotifyDBInfos({ metaData.deviceId }, dbInfos); + } +} + +void KvStoreMetaManager::GetDbInfosByDeviceId(const std::string& deviceId, std::vector& dbInfos) +{ + std::vector metaData; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ deviceId }), metaData)) { + ZLOGW("load meta failed, deviceId:%{public}s", Anonymous::Change(deviceId).c_str()); + return; + } + for (auto const& data : metaData) { + if (data.isAutoSync) { + AddDbInfo(data, dbInfos); + } + } +} + +void KvStoreMetaManager::AddDbInfo(const StoreMetaData& metaData, std::vector& dbInfos, + bool isDeleted) +{ + DistributedDB::DBInfo dbInfo; + dbInfo.appId = metaData.deviceId; + dbInfo.userId = metaData.user; + dbInfo.storeId = metaData.storeId; + dbInfo.isNeedSync = !isDeleted; + dbInfo.syncDualTupleMode = true; + dbInfos.push_back(dbInfo); +} + +void KvStoreMetaManager::OnDeviceChange(const std::string& deviceId) +{ + std::vector dbInfos; + GetDbInfosByDeviceId(deviceId, dbInfos); + DistributedDB::RuntimeConfig::NotifyDBInfos({ deviceId }, dbInfos); +} + +void KvStoreMetaManager::NotifyAllAutoSyncDBInfo() +{ + auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (deviceId.empty()) { + ZLOGE("local deviceId empty"); + return; + } + std::vector metaData; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ deviceId }), metaData)) { + ZLOGE("load meta failed, deviceId:%{public}s", Anonymous::Change(deviceId).c_str()); + return; + } + std::vector dbInfos; + for (auto const& data : metaData) { + if (!data.isAutoSync) { + continue; + } + AddDbInfo(data, dbInfos); + } + if (!dbInfos.empty()) { + DistributedDB::RuntimeConfig::NotifyDBInfos({ deviceId }, dbInfos); + } +} + +void KvStoreMetaManager::DBInfoDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo& info, + const DeviceChangeType& type) const +{ + if (type != DeviceChangeType::DEVICE_ONLINE) { + ZLOGD("offline or onReady ignore, type:%{public}d, deviceId:%{public}s", type, + Anonymous::Change(info.uuid).c_str()); + return; + } + if (info.uuid == DistributedData::DeviceManagerAdapter::CLOUD_DEVICE_UUID) { + ZLOGD("Network change, ignore"); + return; + } + KvStoreMetaManager::GetInstance().SyncMeta(); + KvStoreMetaManager::GetInstance().OnDeviceChange(info.uuid); +} + +AppDistributedKv::ChangeLevelType KvStoreMetaManager::DBInfoDeviceChangeListenerImpl::GetChangeLevelType() const +{ + return AppDistributedKv::ChangeLevelType::MIN; +} } // namespace DistributedKv -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h index 3bea8a46369a095736cc19db1696fafc2aad9098..a59f4b143e8d409598b063997467f719241c2de4 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -23,6 +23,7 @@ #include "kv_store_delegate_manager.h" #include "system_ability.h" #include "types.h" +#include "metadata/store_meta_data.h" namespace OHOS { namespace DistributedKv { @@ -61,20 +62,33 @@ private: NbDelegate CreateMetaKvStore(); - void ConfigMetaDataManager(); + void SetSyncer(); KvStoreMetaManager(); void InitMetaData(); + void UpdateMetaData(); + void SubscribeMetaKvStore(); void SyncMeta(); + void NotifyAllAutoSyncDBInfo(); + + void OnDataChange(CHANGE_FLAG flag, const std::list& changedData); + + void OnDeviceChange(const std::string& deviceId); + + void AddDbInfo(const DistributedData::StoreMetaData& metaData, std::vector& dbInfos, + bool isDeleted = false); + + void GetDbInfosByDeviceId(const std::string& deviceId, std::vector& dbInfos); + std::string GetBackupPath() const; ExecutorPool::Task GetTask(uint32_t retry); - + std::function SyncTask(const NbDelegate &store, int32_t status); class KvStoreMetaObserver : public DistributedDB::KvStoreObserver { @@ -88,6 +102,13 @@ private: void HandleChanges(CHANGE_FLAG flag, const std::list &entries); }; + class DBInfoDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceChangeListener { + void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, + const AppDistributedKv::DeviceChangeType &type) const override; + + AppDistributedKv::ChangeLevelType GetChangeLevelType() const override; + }; + static constexpr int32_t RETRY_MAX_TIMES = 100; static constexpr int32_t RETRY_INTERVAL = 1; static constexpr uint8_t COMPRESS_RATE = 10; @@ -97,11 +118,13 @@ private: const std::string label_; DistributedDB::KvStoreDelegateManager delegateManager_; static MetaDeviceChangeListenerImpl listener_; + static DBInfoDeviceChangeListenerImpl dbInfoListener_; KvStoreMetaObserver metaObserver_; std::mutex mutex_; std::shared_ptr executors_; TaskId delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID; + static constexpr int32_t META_VERSION = 2; }; } // namespace DistributedKv } // namespace OHOS -#endif // KVSTORE_META_MANAGER_H +#endif // KVSTORE_META_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp index c8515d4a464e1507167120ffbeae8d51ffa013e0..323b62e92db7de0e810cd767f1d537d36672a74a 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -15,7 +15,8 @@ #include "route_head_handler_impl.h" #define LOG_TAG "RouteHeadHandler" - +#include +#include #include "auth_delegate.h" #include "device_manager_adapter.h" #include "kvstore_meta_manager.h" @@ -30,6 +31,7 @@ namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; +using namespace std::chrono; using DmAdapter = DistributedData::DeviceManagerAdapter; constexpr const int ALIGN_WIDTH = 8; std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) @@ -92,7 +94,9 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize // align message uint width headSize = GET_ALIGNED_SIZE(expectSize, ALIGN_WIDTH); - ZLOGI("packed size:%{public}u", headSize); + auto time = + static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + ZLOGI("packed size:%{public}u times %{public}" PRIu64 ".", headSize, time); headSize_ = headSize; return DistributedDB::OK; } @@ -188,7 +192,9 @@ bool RouteHeadHandlerImpl::ParseHeadData( headSize = 0; return false; } - ZLOGI("unpacked size:%{public}u", headSize); + auto time = + static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + ZLOGI("unpacked size:%{public}u times %{public}" PRIu64 ".", headSize, time); // flip the local and peer ends SessionPoint local { .deviceId = session_.targetDeviceId, .appId = session_.appId }; SessionPoint peer { .deviceId = session_.sourceDeviceId, .userId = session_.sourceUserId, .appId = session_.appId }; diff --git a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn index d13ad3869ef1e06b31c01a6913bf2db488a2741a..dba18f091d409daedbdfc65f82c2145e555a5ae8 100644 --- a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn @@ -67,6 +67,7 @@ config("module_private_config") { ohos_unittest("KvStoreDataServiceTest") { module_out_path = module_output_path sources = [ + "../src/db_info_handle_impl.cpp", "../src/feature_stub_impl.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_data_service.cpp", @@ -211,6 +212,7 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { ohos_unittest("KvStoreDataServiceClearTest") { module_out_path = module_output_path sources = [ + "${data_service_path}/app/src/db_info_handle_impl.cpp", "${data_service_path}/app/src/feature_stub_impl.cpp", "${data_service_path}/app/src/kvstore_account_observer.cpp", "${data_service_path}/app/src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn index d0ecb8236c0dd959860e52859d6215e2a052c05d..5e6a9098a9f09761e880c16f08cc8395930788ee 100644 --- a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn @@ -63,6 +63,7 @@ ohos_fuzztest("DataServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/app/src/db_info_handle_impl.cpp", "${data_service_path}/app/src/feature_stub_impl.cpp", "${data_service_path}/app/src/kvstore_account_observer.cpp", "${data_service_path}/app/src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index 14d7b58522e46be3cd21cd2098cd88a6d7028fc4..aa0df79dd0afd49eaae79fe29e9a51f226cb5a5c 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -80,6 +80,7 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/store_meta_data_local.cpp", "metadata/strategy_meta_data.cpp", "metadata/user_meta_data.cpp", + "metadata/version_meta_data.cpp", "serializable/serializable.cpp", "snapshot/bind_event.cpp", "snapshot/snapshot.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp b/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp index 8dbc1bb39650f35574872abef279e293cf6a9e91..9a384153d39948b269487b78b9f010d2637a0537 100644 --- a/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp @@ -76,6 +76,20 @@ bool CheckerManager::IsValid(const StoreInfo &info) return false; } +bool CheckerManager::IsDistrust(const StoreInfo &info) +{ + for (auto &[name, checker] : checkers_) { + if (checker == nullptr) { + continue; + } + if (!checker->IsDistrust(info)) { + continue; + } + return true; + } + return false; +} + CheckerManager::Checker *CheckerManager::GetChecker(const std::string &checker) { auto it = checkers_.find(checker); diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp index 7df8309f4f2a84a75d9d176a4789df5b52635264..f6f01847176795b8e4737bb619c10a63e5dbcb70 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp @@ -121,6 +121,16 @@ bool CloudInfo::IsOn(const std::string &bundleName, int32_t instanceId) return it != apps.end() && it->second.instanceId == instanceId && it->second.cloudSwitch; } +bool CloudInfo::IsAllSwitchOff() const +{ + for (auto &[bundle, app] : apps) { + if (app.cloudSwitch) { + return false; + } + } + return true; +} + std::string CloudInfo::GetPrefix(const std::initializer_list &fields) { return GetKey(INFO_PREFIX, fields).append(Constant::KEY_SEPARATOR); diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp index ef3a75391d177c3ed7e3d0982bf327098e8246a5..897a567d60db9e2e28f8a718895dec6d492d24af 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp @@ -72,4 +72,8 @@ void CloudServer::Clean(int32_t userId) void CloudServer::ReleaseUserInfo(int32_t userId) { } + +void CloudServer::Bind(std::shared_ptr executor) +{ +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp index 7bddb52c3744542b623df82347c1a724238b66df..28030d881146285152f98573b4daf1fb798c6938 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp @@ -58,6 +58,25 @@ std::string Subscription::GetRelationKey(const std::string &bundleName) return GetRelationKey(userId, bundleName); } +uint64_t Subscription::GetMinExpireTime() const +{ + if (expiresTime.empty()) { + return 0; + } + auto it = expiresTime.begin(); + uint64_t expire = it->second; + it++; + for (; it != expiresTime.end(); it++) { + if (it->second == 0) { + continue; + } + if (it->second < expire) { + expire = it->second; + } + } + return expire; +} + std::string Subscription::GetKey(int32_t userId) { return Constant::Join(PREFIX, Constant::KEY_SEPARATOR, { std::to_string(userId) }); diff --git a/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h b/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h index 95b4022799e862849049197c1b2fc935980f87f2..b54063d7eb9385311b7d2939b7718203170d0108 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h @@ -29,6 +29,7 @@ public: std::string base64Key; std::string checker; }; + using Distrust = Trust; struct StoreInfo { pid_t uid; uint32_t tokenId; @@ -39,8 +40,10 @@ public: public: virtual void Initialize() = 0; virtual bool SetTrustInfo(const Trust &trust) = 0; + virtual bool SetDistrustInfo(const Distrust &distrust) = 0; virtual std::string GetAppId(const StoreInfo &info) = 0; virtual bool IsValid(const StoreInfo &info) = 0; + virtual bool IsDistrust(const StoreInfo &info) = 0; protected: API_EXPORT ~Checker() = default; }; @@ -48,6 +51,7 @@ public: API_EXPORT void RegisterPlugin(const std::string &checker, std::function getter); API_EXPORT std::string GetAppId(const StoreInfo &info); API_EXPORT bool IsValid(const StoreInfo &info); + API_EXPORT bool IsDistrust(const StoreInfo &info); API_EXPORT void LoadCheckers(std::vector &checkers); API_EXPORT Checker *GetChecker(const std::string &checker); private: @@ -56,4 +60,4 @@ private: }; } // namespace DistributedData } // namespace OHOS -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CHECKER_CHECKER_MANAGER_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CHECKER_CHECKER_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h index b88e997944ead97181d5d276beaf45d621865683..14cdf141c685a8adbef94436fc51d327cb7c034e 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h @@ -46,6 +46,7 @@ public: bool IsValid() const; bool Exist(const std::string &bundleName, int32_t instanceId = 0); bool IsOn(const std::string &bundleName, int32_t instanceId = 0); + bool IsAllSwitchOff() const; static std::string GetPrefix(const std::initializer_list &field); bool Marshal(json &node) const override; diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h index dbf8a4901a52921a7d2daa1e25db0aed698f2c57..ebe4220c03881772e3be41084542c7f868ffcfb7 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h @@ -20,6 +20,7 @@ #include "cloud/cloud_info.h" #include "cloud/schema_meta.h" #include "cloud/sharing_center.h" +#include "executor_pool.h" #include "visibility.h" namespace OHOS::DistributedData { class API_EXPORT CloudServer { @@ -37,6 +38,7 @@ public: virtual std::shared_ptr ConnectSharingCenter(int32_t userId, const std::string &bunleName); virtual void Clean(int32_t userId); virtual void ReleaseUserInfo(int32_t userId); + virtual void Bind(std::shared_ptr executor); private: static CloudServer *instance_; diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h index cd612cf216daa4d7e6948b48525c60ca8ebaf6b8..7836822c8f303ff9dd8a18008124c399504e06f1 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h @@ -60,7 +60,7 @@ public: static constexpr const char *REFERENCE_FIELD = "#_reference"; static constexpr const char *CLOUD_OWNER = "cloud_owner"; static constexpr const char *CLOUD_PRIVILEGE = "cloud_privilege"; - static constexpr const char *SHARING_RESOURCE = "sharing_resource"; + static constexpr const char *SHARING_RESOURCE = "#_sharing_resource"; int32_t version = 0; std::string bundleName; std::vector databases; diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/subscription.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/subscription.h index c0e8dec5f5cb3f9342fc58961744a0e4e9469d65..1d81ea3a974d728a48678a3b05ba96d8026b7ec8 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/subscription.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/subscription.h @@ -34,6 +34,7 @@ struct API_EXPORT Subscription final : public Serializable { bool Unmarshal(const json &node); std::string GetKey(); std::string GetRelationKey(const std::string &bundleName); + uint64_t GetMinExpireTime() const; static std::string GetKey(int32_t userId); static std::string GetRelationKey(int32_t userId, const std::string &bundleName); static std::string GetPrefix(const std::initializer_list &fields); diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h index 55d0b47f52f1c765459880384e7bdc5b7d52e799..b1588b7052a2df104dcc70d2361fb86550953311 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h @@ -49,8 +49,10 @@ public: using Syncer = std::function &, int32_t)>; using Backup = std::function &)>; using Bytes = std::vector; + using OnComplete = std::function &)>; API_EXPORT static MetaDataManager &GetInstance(); - API_EXPORT void Initialize(std::shared_ptr metaStore, const Backup &backup, const Syncer &syncer); + API_EXPORT void Initialize(std::shared_ptr metaStore, const Backup &backup); + API_EXPORT void SetSyncer(const Syncer &syncer); API_EXPORT bool SaveMeta(const std::string &key, const Serializable &value, bool isLocal = false); API_EXPORT bool LoadMeta(const std::string &key, Serializable &value, bool isLocal = false); template @@ -72,8 +74,10 @@ public: API_EXPORT bool DelMeta(const std::string &key, bool isLocal = false); API_EXPORT bool Subscribe(std::shared_ptr filter, Observer observer); - API_EXPORT bool Subscribe(std::string prefix, Observer observer); + API_EXPORT bool Subscribe(std::string prefix, Observer observer, bool isLocal = false); API_EXPORT bool Unsubscribe(std::string filter); + API_EXPORT bool Sync(const std::vector &devices, OnComplete complete); + private: MetaDataManager(); ~MetaDataManager(); diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index 6a8a15e4d6d83c50b9773501543a7db2f12b9907..fdcb3d49a4635ca0eba404ba4770cad7d442e2b0 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -26,6 +26,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { // UID -> uid, deviceAccountId -> userId, userId -> user static constexpr uint32_t FIELD_CHANGED_TAG = 0x03000003; static constexpr uint32_t UUID_CHANGED_TAG = 0x03000004; + static constexpr const char *KEY_PREFIX = "KvStoreMetaData"; uint32_t version = CURRENT_VERSION; bool isAutoSync = false; bool isBackup = false; @@ -77,9 +78,6 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT std::string GetStoreAlias() const; API_EXPORT static std::string GetKey(const std::initializer_list &fields); API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); - -private: - static constexpr const char *KEY_PREFIX = "KvStoreMetaData"; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h new file mode 100644 index 0000000000000000000000000000000000000000..07080e374ad9a5819c24b3427355c90c1fc617f0 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h @@ -0,0 +1,37 @@ +/* + * 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_VERSION_META_DATA_H +#define DISTRIBUTEDDATAMGR_VERSION_META_DATA_H +#include "serializable/serializable.h" + +namespace OHOS::DistributedData { +class API_EXPORT VersionMetaData final : public Serializable { +public: + static constexpr int32_t CURRENT_VERSION = 2; + static constexpr int32_t INVALID_VERSION = -1; + int32_t version = INVALID_VERSION; + + API_EXPORT VersionMetaData(); + API_EXPORT ~VersionMetaData(); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; + API_EXPORT std::string GetKey() const; + +private: + static constexpr const char *KEY_PREFIX = "VersionKey"; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_VERSION_META_DATA_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h index b8bfd7db2b1a858c37968557cc97b85c10af5694..a3be9f70833ad3e2e4597bb99375217d711b0991 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -99,6 +99,8 @@ public: virtual int32_t Update(const std::string &table, const std::string &setSql, Values &&values, const std::string &whereSql, Values &&conditions) = 0; + virtual int32_t Replace(const std::string &table, VBucket &&value) = 0; + virtual int32_t Delete(const std::string &table, const std::string &sql, Values &&args) = 0; virtual std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) = 0; diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index 0ae44908ad5bb0b840b7f88f8439a6cb724844b5..1e8cd74fb644910ff228a54eeccd46bc3512f210 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -26,7 +26,8 @@ public: using Filter = MetaDataManager::Filter; using MetaStore = MetaDataManager::MetaStore; using Observer = MetaDataManager::Observer; - MetaObserver(std::shared_ptr metaStore, std::shared_ptr filter, Observer observer); + MetaObserver(std::shared_ptr metaStore, + std::shared_ptr filter, Observer observer, bool isLocal = false); virtual ~MetaObserver(); // Database change callback @@ -38,11 +39,13 @@ private: Observer observer_; }; -MetaObserver::MetaObserver(std::shared_ptr metaStore, std::shared_ptr filter, Observer observer) +MetaObserver::MetaObserver(std::shared_ptr metaStore, + std::shared_ptr filter, Observer observer, bool isLocal) : metaStore_(std::move(metaStore)), filter_(std::move(filter)), observer_(std::move(observer)) { if (metaStore_ != nullptr) { - int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN; + int mode = isLocal ? DistributedDB::OBSERVER_CHANGES_LOCAL_ONLY + : (DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN); auto status = metaStore_->RegisterObserver(filter_->GetKey(), mode, this); if (status != DistributedDB::DBStatus::OK) { ZLOGE("register meta observer failed :%{public}d.", status); @@ -104,7 +107,7 @@ MetaDataManager::~MetaDataManager() metaObservers_.Clear(); } -void MetaDataManager::Initialize(std::shared_ptr metaStore, const Backup &backup, const Syncer &syncer) +void MetaDataManager::Initialize(std::shared_ptr metaStore, const Backup &backup) { if (metaStore == nullptr) { return; @@ -116,10 +119,17 @@ void MetaDataManager::Initialize(std::shared_ptr metaStore, const Bac } metaStore_ = std::move(metaStore); backup_ = backup; - syncer_ = syncer; inited_ = true; } +void MetaDataManager::SetSyncer(const Syncer &syncer) +{ + if (metaStore_ == nullptr) { + return; + } + syncer_ = syncer; +} + bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value, bool isLocal) { if (!inited_) { @@ -196,6 +206,25 @@ bool MetaDataManager::DelMeta(const std::string &key, bool isLocal) return ((status == DistributedDB::DBStatus::OK) || (status == DistributedDB::DBStatus::NOT_FOUND)); } +bool MetaDataManager::Sync(const std::vector &devices, OnComplete complete) +{ + if (!inited_ || devices.empty()) { + return false; + } + auto status = metaStore_->Sync( + devices, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, [complete](auto &dbResults) { + std::map results; + for (auto &[uuid, status] : dbResults) { + results.insert_or_assign(uuid, static_cast(status)); + } + complete(results); + }); + if (status != DistributedDB::OK) { + ZLOGW("meta data sync error %{public}d.", status); + } + return status == DistributedDB::OK; +} + bool MetaDataManager::Subscribe(std::shared_ptr filter, Observer observer) { if (!inited_) { @@ -208,15 +237,15 @@ bool MetaDataManager::Subscribe(std::shared_ptr filter, Observer observe }); } -bool MetaDataManager::Subscribe(std::string prefix, Observer observer) +bool MetaDataManager::Subscribe(std::string prefix, Observer observer, bool isLocal) { if (!inited_) { return false; } return metaObservers_.ComputeIfAbsent( - prefix, [ this, &observer, &prefix ](const std::string &key) -> auto { - return std::make_shared(metaStore_, std::make_shared(prefix), observer); + prefix, [ this, isLocal, &observer, &prefix ](const std::string &key) -> auto { + return std::make_shared(metaStore_, std::make_shared(prefix), observer, isLocal); }); } diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/version_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/version_meta_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfe1738d63f18fd330099b7398a9712f3e96dfa9 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/metadata/version_meta_data.cpp @@ -0,0 +1,45 @@ +/* + * 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/version_meta_data.h" + +namespace OHOS::DistributedData { +VersionMetaData::VersionMetaData() +{ +} + +VersionMetaData::~VersionMetaData() +{ +} + +bool VersionMetaData::Marshal(json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(version)], version) && ret; + return ret; +} + +bool VersionMetaData::Unmarshal(const json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(version), version) && ret; + return ret; +} + +std::string VersionMetaData::GetKey() const +{ + return KEY_PREFIX; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn index ba13118563d60acb0ca051e54f4ee6b8a91e2e58..6ccb44ea451e4dce8686104b261bdb07a08befcd 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos_var.gni") import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") module_output_path = "datamgr_service/distributeddatafwk" @@ -20,8 +21,30 @@ config("module_private_config") { visibility = [ ":*" ] include_dirs = [ + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", "../include/", "../../service/bootstrap/include/", + "../../service/common/", + "../../service/rdb/", + "../../../../../relational_store/interfaces/inner_api/rdb/include", + "../../../../../relational_store/interfaces/inner_api/common_type/include", + "${kv_store_distributeddb_path}/interfaces/include", + "${kv_store_distributeddb_path}/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/src", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${data_service_path}/adapter/include", + "${data_service_path}/framework/include", + "${data_service_path}/service/config/include", + "${data_service_path}/app/src", + "${data_service_path}/adapter/include/account", + "${data_service_path}/app/src/security", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/matrix/include", + "//third_party/json/single_include", ] ldflags = [ "-Wl,--whole-archive" ] defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] @@ -96,6 +119,183 @@ ohos_unittest("SerializableTest") { ] } +ohos_unittest("UtilsTest") { + module_out_path = module_output_path + + sources = [ "utils_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "//third_party/googletest:gtest_main", + ] +} + +ohos_unittest("StoreTest") { + module_out_path = module_output_path + + sources = [ + "../../service/rdb/rdb_query.cpp", + "store_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "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", + ] +} + +ohos_unittest("AssetLoaderTest") { + module_out_path = module_output_path + sources = [ "asset_loader_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("BackupRuleManagerTest") { + module_out_path = module_output_path + sources = [ "backup_rule_manager_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("BindEventTest") { + module_out_path = module_output_path + sources = [ "bind_event_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("CloudInfoTest") { + module_out_path = module_output_path + sources = [ "cloud_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("EventTest") { + module_out_path = module_output_path + sources = [ "event_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("GeneralStoreTest") { + module_out_path = module_output_path + sources = [ "general_store_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("SubscriptionTest") { + module_out_path = module_output_path + sources = [ "subscription_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("FeatureTest") { + module_out_path = module_output_path + sources = [ "feature_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_path}/interfaces/innerkits/distributeddata:distributeddata_inner", + ] +} + +ohos_unittest("MetaDataManagerTest") { + module_out_path = module_output_path + sources = [ "meta_data_manager_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("StoreMetaDataLocalTest") { + module_out_path = module_output_path + sources = [ "store_meta_data_local_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("ConstantTest") { + module_out_path = module_output_path + sources = [ "constant_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("CryptoTest") { + module_out_path = module_output_path + sources = [ "crypto_test.cpp" ] + configs = [ ":module_private_config" ] + deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] +} + +ohos_unittest("ServiceMetaDataTest") { + module_out_path = module_output_path + + sources = [ + "${data_service_path}/app/src/kvstore_meta_manager.cpp", + "meta_data_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dataclassification:data_transit_mgr", + "device_auth:deviceauth_sdk", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/broadcaster:distributeddata_broadcaster_static", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/app/src/checker:distributeddata_checker_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${kv_store_distributeddb_path}:distributeddb", + "${kv_store_path}/interfaces/innerkits/distributeddata:distributeddata_inner", + "${kv_store_path}/interfaces/innerkits/distributeddatamgr:distributeddata_mgr", + "//third_party/googletest:gtest_main", + "//third_party/openssl:libcrypto_shared", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -103,9 +303,24 @@ group("unittest") { deps = [] deps += [ + ":AssetLoaderTest", + ":BackupRuleManagerTest", + ":BindEventTest", ":CheckerManagerTest", + ":CloudInfoTest", + ":ConstantTest", + ":CryptoTest", ":EventCenterTest", + ":EventTest", + ":FeatureTest", + ":GeneralStoreTest", + ":MetaDataManagerTest", ":SerializableTest", + ":ServiceMetaDataTest", + ":StoreMetaDataLocalTest", + ":StoreTest", + ":SubscriptionTest", + ":UtilsTest", ] } ############################################################################### diff --git a/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9ff6e451bc0bce8d7486171d4f87712e9cefdf6 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "cloud/asset_loader.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class AssetLoaderTest : public testing::Test {}; + +/** +* @tc.name: Download +* @tc.desc: download. +* @tc.type: FUNC +*/ +HWTEST_F(AssetLoaderTest, Download, TestSize.Level1) +{ + AssetLoader loader; + std::string tableName; + std::string gid; + Value prefix; + VBucket assets; + auto ret = loader.Download(tableName, gid, prefix, assets); + ASSERT_EQ(ret, E_NOT_SUPPORT); +} + +/** +* @tc.name: RemoveLocalAssets +* @tc.desc: remove local assets. +* @tc.type: FUNC +*/ +HWTEST_F(AssetLoaderTest, RemoveLocalAssets, TestSize.Level1) +{ + AssetLoader loader; + std::string tableName; + std::string gid; + Value prefix; + VBucket assets; + auto ret = loader.RemoveLocalAssets(tableName, gid, prefix, assets); + ASSERT_EQ(ret, E_NOT_SUPPORT); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/backup_rule_manager_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/backup_rule_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0242fe0629cab6c5af473bb71d2203336422ff93 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/backup_rule_manager_test.cpp @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "backuprule/backup_rule_manager.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class BackupRuleManagerTest : public testing::Test { +public: + class TestRule : public BackupRuleManager::BackupRule { + public: + TestRule() + { + BackupRuleManager::GetInstance().RegisterPlugin("TestRule", [this]() -> auto { + return this; + }); + } + bool CanBackup() override + { + return false; + } + }; +}; + +/** +* @tc.name: BackupRuleManager +* @tc.desc: backup rule manager. +* @tc.type: FUNC +*/ +HWTEST_F(BackupRuleManagerTest, BackupRuleManager, TestSize.Level1) +{ + BackupRuleManagerTest::TestRule(); + std::vector rule = { "TestRule" }; + BackupRuleManager::GetInstance().LoadBackupRules(rule); + ASSERT_FALSE(BackupRuleManager::GetInstance().CanBackup()); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/bind_event_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/bind_event_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..309c196a200f1fac832f2248da73267898935f55 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/bind_event_test.cpp @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "snapshot/bind_event.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class BindEventTest : public testing::Test {}; + +/** +* @tc.name: GetBindInfo +* @tc.desc: get bind info. +* @tc.type: FUNC +*/ +HWTEST_F(BindEventTest, GetBindInfo, TestSize.Level1) +{ + BindEvent::BindEventInfo info; + info.tokenId = 100; + BindEvent event(BindEvent::BIND_SNAPSHOT, std::move(info)); + auto ret = event.GetBindInfo().tokenId; + ASSERT_EQ(ret, 100); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a3a863fb246d8b6ded6acad07d8b2166b630334 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp @@ -0,0 +1,236 @@ +/* +* 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 "CloudInfoTest" +#include + +#include "serializable/serializable.h" +#include "cloud/cloud_info.h" +#include "cloud/schema_meta.h" +#include "nlohmann/json.hpp" +#include "utils/crypto.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; +class CloudInfoTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +/** +* @tc.name: GetSchemaPrefix +* @tc.desc: Get schema prefix. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, GetSchemaPrefix, TestSize.Level0) +{ + CloudInfo cloudInfo; + auto result = cloudInfo.GetSchemaPrefix("ohos.test.demo"); + ASSERT_EQ(result, "CLOUD_SCHEMA###0###ohos.test.demo"); + + result = cloudInfo.GetSchemaPrefix(""); + ASSERT_EQ(result, "CLOUD_SCHEMA###0"); +} + +/** +* @tc.name: IsValid +* @tc.desc: Determine if it is limited. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, IsValid, TestSize.Level0) +{ + CloudInfo cloudInfo; + auto result = cloudInfo.IsValid(); + ASSERT_FALSE(result); + + CloudInfo cloudInfo1; + cloudInfo1.user = 111; + cloudInfo1.id = "test1_id"; + cloudInfo1.totalSpace = 0; + cloudInfo1.remainSpace = 0; + cloudInfo1.enableCloud = false; + + Serializable::json node1; + cloudInfo1.Marshal(node1); + result = cloudInfo1.IsValid(); + ASSERT_TRUE(result); +} + +/** +* @tc.name: Exist +* @tc.desc: Determine if the package exists. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, Exist, TestSize.Level0) +{ + CloudInfo cloudInfo; + auto result = cloudInfo.Exist("", 1); + ASSERT_FALSE(result); + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = "test_cloud_bundleName"; + appInfo.appId = "test_cloud_id"; + appInfo.version = 0; + appInfo.instanceId = 100; + appInfo.cloudSwitch = false; + + cloudInfo.user = 111; + cloudInfo.id = "test_cloud_id"; + cloudInfo.totalSpace = 0; + cloudInfo.remainSpace = 100; + cloudInfo.enableCloud = true; + cloudInfo.apps["test_cloud_bundleName"] = std::move(appInfo); + + Serializable::json node1; + cloudInfo.Marshal(node1); + result = cloudInfo.Exist("test_cloud_bundleName", 100); + ASSERT_TRUE(result); +} + +/** +* @tc.name: Exist +* @tc.desc: Is it on. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, IsOn, TestSize.Level0) +{ + CloudInfo cloudInfo; + auto result = cloudInfo.IsOn("ohos.test.demo", 1); + ASSERT_FALSE(result); + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = "test_cloud_bundleName"; + appInfo.appId = "test_cloud_id"; + appInfo.version = 0; + appInfo.instanceId = 100; + appInfo.cloudSwitch = true; + + cloudInfo.user = 111; + cloudInfo.id = "test_cloud_id"; + cloudInfo.totalSpace = 0; + cloudInfo.remainSpace = 100; + cloudInfo.enableCloud = true; + cloudInfo.apps["test_cloud_bundleName"] = std::move(appInfo); + + Serializable::json node1; + cloudInfo.Marshal(node1); + result = cloudInfo.IsOn("test_cloud_bundleName", 100); + ASSERT_TRUE(result); +} + +/** +* @tc.name: GetPrefix +* @tc.desc: Get prefix. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, GetPrefix, TestSize.Level0) +{ + const std::initializer_list fields; + auto result = CloudInfo::GetPrefix(fields); + ASSERT_EQ(result, "CLOUD_INFO###"); +} + +/** +* @tc.name: CloudInfoTest +* @tc.desc: Marshal and Unmarshal of CloudInfo. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, CloudInfoTest, TestSize.Level0) +{ + CloudInfo cloudInfo1; + cloudInfo1.user = 111; + cloudInfo1.id = "test1_id"; + cloudInfo1.totalSpace = 0; + cloudInfo1.remainSpace = 0; + cloudInfo1.enableCloud = false; + + 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. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, AppInfoTest, TestSize.Level0) +{ + CloudInfo::AppInfo cloudInfoAppInfo1; + cloudInfoAppInfo1.bundleName = "ohos.test.demo"; + cloudInfoAppInfo1.appId = "test1_id"; + cloudInfoAppInfo1.version = 0; + cloudInfoAppInfo1.instanceId = 0; + cloudInfoAppInfo1.cloudSwitch = false; + + Serializable::json node1; + cloudInfoAppInfo1.Marshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfoAppInfo1), to_string(node1)); + + CloudInfo::AppInfo cloudInfoAppInfo2; + cloudInfoAppInfo2.Unmarshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfoAppInfo1), Serializable::Marshall(cloudInfoAppInfo2)); +} + +/** +* @tc.name: TableTest +* @tc.desc: Marshal and Unmarshal of Table. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Anvette +*/ +HWTEST_F(CloudInfoTest, TableTest, TestSize.Level0) +{ + Field field1; + field1.colName = "test1_colName"; + field1.alias = "test1_alias"; + field1.type = 1; + field1.primary = true; + field1.nullable = false; + + Table table1; + table1.name = "test1_name"; + table1.sharedTableName = "test1_sharedTableName"; + table1.alias = "test1_alias"; + table1.fields.push_back(field1); + Serializable::json node1; + table1.Marshal(node1); + EXPECT_EQ(Serializable::Marshall(table1), to_string(node1)); + + Table table2; + table2.Unmarshal(node1); + EXPECT_EQ(Serializable::Marshall(table1), Serializable::Marshall(table2)); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a5147d3578d261d51426946ee8075eb51c6502ab --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp @@ -0,0 +1,61 @@ +/* +* 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 "utils/constant.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class ConstantTest : public testing::Test { +}; + +/** +* @tc.name: EqualTest +* @tc.desc: Equal. +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(ConstantTest, EqualTest, TestSize.Level1) +{ + bool result = Constant::Equal(true, true); + ASSERT_TRUE(result); + + result = Constant::Equal(true, false); + ASSERT_FALSE(result); + + result = OHOS::DistributedData::Constant::Equal(false, false); + ASSERT_TRUE(result); +} + +/** +* @tc.name: NotEqualTest +* @tc.desc: NotEqual. +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(ConstantTest, NotEqualTest, TestSize.Level1) +{ + bool result = Constant::NotEqual(true, true); + ASSERT_FALSE(result); + + result = Constant::NotEqual(true, false); + ASSERT_TRUE(result); + + result = Constant::NotEqual(false, false); + ASSERT_FALSE(result); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/crypto_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/crypto_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0cb302c74f006ce8277202aa9a7d039e0dd9bcf --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/crypto_test.cpp @@ -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. +*/ +#include "utils/crypto.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; +using namespace std; + +class CryptoTest : public testing::Test { +}; + +/** +* @tc.name: RandomTest +* @tc.desc: Random. +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(CryptoTest, RandomTest, TestSize.Level1) +{ + int32_t len = 10; + int32_t min = 0; + int32_t max = 255; + + vector randomNumbers = Crypto::Random(len, min, max); + ASSERT_EQ(randomNumbers.size(), 10); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/event_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/event_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8499fbfdef28262430d097a6ad9331093fb26a6 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/event_test.cpp @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "eventcenter/event.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class EventTest : public testing::Test {}; + +/** +* @tc.name: Equals +* @tc.desc: equals. +* @tc.type: FUNC +*/ +HWTEST_F(EventTest, Equals, TestSize.Level1) +{ + Event event1(1); + Event event2(2); + ASSERT_FALSE(event1.Equals(event2)); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1fdbd16a33a0f6dca634dcce2426dd9219d1ffd5 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp @@ -0,0 +1,257 @@ +/* +* 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 + +#include "feature/feature_system.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +namespace DistributedDB { +struct AutoLaunchParam { +}; +} + +class FeatureSystemTest : public testing::Test { +}; + +class MockFeature : public FeatureSystem::Feature { +public: + int OnRemoteRequest(uint32_t code, OHOS::MessageParcel& data, OHOS::MessageParcel& reply) override + { + return E_OK; + } +}; + +/** +* @tc.name: GetInstanceTest +* @tc.desc: getInstance +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, GetInstanceTest, TestSize.Level1) +{ + FeatureSystem& featureSystem = FeatureSystem::GetInstance(); + ASSERT_NE(&featureSystem, nullptr); +} + +/** +* @tc.name: RegisterCreatorTest And GetCreatorTest +* @tc.desc: registerCreatorTest And getCreator +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, RegisterCreatorAndGetCreatorTest, TestSize.Level1) +{ + FeatureSystem& featureSystem = FeatureSystem::GetInstance(); + std::string featureName = "MockFeature"; + FeatureSystem::Creator creator = []() { + return std::shared_ptr(); + }; + + int32_t result = featureSystem.RegisterCreator(featureName, creator); + EXPECT_EQ(result, E_OK); + + FeatureSystem::Creator registeredCreator = featureSystem.GetCreator(featureName); + EXPECT_NE(registeredCreator, nullptr); +} + +/** +* @tc.name: RegisterStaticActsTest And GetStaticActsTest +* @tc.desc: registerStaticActs And getStaticActs +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, GetStaticActsAndetStaticActsTest, TestSize.Level1) +{ + FeatureSystem& featureSystem = FeatureSystem::GetInstance(); + std::string staticActsName = "StaticActs"; + std::shared_ptr staticActs = std::make_shared(); + + int32_t result = featureSystem.RegisterStaticActs(staticActsName, staticActs); + EXPECT_EQ(result, E_OK); + + const OHOS::ConcurrentMap>& staticActsMap = featureSystem.GetStaticActs(); + auto [success, staticActsPtr] = staticActsMap.Find("StaticActs"); + EXPECT_NE(staticActsPtr, nullptr); +} + +/** +* @tc.name: GetFeatureNameTest +* @tc.desc: getFeatureNameTest +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, GetFeatureNameTest, TestSize.Level1) +{ + FeatureSystem& featureSystem = FeatureSystem::GetInstance(); + std::string featureName1 = "Feature1"; + std::string featureName2 = "Feature2"; + + featureSystem.RegisterCreator(featureName1, []() { + return nullptr; + }); + featureSystem.RegisterCreator(featureName2, []() { + return nullptr; + }); + + std::vector featureNames = featureSystem.GetFeatureName(FeatureSystem::BIND_LAZY); + + EXPECT_EQ(featureNames[0], featureName1); + EXPECT_EQ(featureNames[1], featureName2); +} + +/** +* @tc.name: OnInitializeTest +* @tc.desc: onInitializeTest +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, OnInitializeTest, TestSize.Level1) +{ + MockFeature feature; + int32_t result = feature.OnInitialize(); + EXPECT_EQ(result, E_OK); +} + +/** +* @tc.name: OnBindTest +* @tc.desc: onBind +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, OnBindTest, TestSize.Level1) +{ + MockFeature feature; + FeatureSystem::Feature::BindInfo bindInfo; + bindInfo.selfName = "Feature1"; + bindInfo.selfTokenId = 123; + bindInfo.executors = std::shared_ptr(); + int32_t result = feature.OnBind(bindInfo); + EXPECT_EQ(result, E_OK); +} + +/** +* @tc.name: OnAppExitTest +* @tc.desc: onAppExitTest +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, OnAppExitTest, TestSize.Level1) +{ + MockFeature feature; + pid_t uid = 1; + pid_t pid = 2; + uint32_t tokenId = 3; + std::string bundleName = "com.example.app"; + int32_t result = feature.OnAppExit(uid, pid, tokenId, bundleName); + EXPECT_EQ(result, E_OK); +} + +/** +* @tc.name: FeatureTest001 +* @tc.desc: onAppUninstallTest and onAppUpdate and onAppInstall +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, FeatureTest001, TestSize.Level1) +{ + FeatureSystem::Feature::BindInfo bindInfo; + std::string bundleName = "com.example.app"; + int32_t user = 0; + int32_t index = 1; + + MockFeature mockFeature; + + int32_t ret = mockFeature.OnAppInstall(bundleName, user, index); + EXPECT_EQ(ret, E_OK); + + ret = mockFeature.OnAppUpdate(bundleName, user, index); + EXPECT_EQ(ret, E_OK); + + ret = mockFeature.OnAppUninstall(bundleName, user, index); + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: ResolveAutoLaunchTest +* @tc.desc: resolveAutoLaunch +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, ResolveAutoLaunchTest, TestSize.Level1) +{ + FeatureSystem::Feature::BindInfo bindInfo; + std::string identifier = "example_identifier"; + DistributedDB::AutoLaunchParam param; + + MockFeature mockFeature; + int32_t ret = mockFeature.ResolveAutoLaunch(identifier, param); + + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: OnUserChangeTest +* @tc.desc: onUserChange +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, OnUserChangeTest, TestSize.Level1) +{ + FeatureSystem::Feature::BindInfo bindInfo; + uint32_t code = 1; + std::string user = "example_user"; + std::string account = "example_account"; + + MockFeature mockFeature; + int32_t ret = mockFeature.OnUserChange(code, user, account); + + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: FeatureTest002 +* @tc.desc: online and offline and onReady +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(FeatureSystemTest, FeatureTest002, TestSize.Level1) +{ + FeatureSystem::Feature::BindInfo bindInfo; + std::string device = "example_device"; + + MockFeature mockFeature; + + int32_t ret = mockFeature.Online(device); + EXPECT_EQ(ret, E_OK); + + ret = mockFeature.Offline(device); + EXPECT_EQ(ret, E_OK); + + ret = mockFeature.OnReady(device); + EXPECT_EQ(ret, E_OK); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..401602a4f38d4342a17fd0a9d73a7fcca8fbaac6 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "store/general_store.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class GeneralStoreTest : public testing::Test {}; + +/** +* @tc.name: MixMode +* @tc.desc: mix mode. +* @tc.type: FUNC +*/ +HWTEST_F(GeneralStoreTest, MixMode, TestSize.Level1) +{ + uint32_t syncMode = GeneralStore::SyncMode::NEARBY_BEGIN; + uint32_t highMode = GeneralStore::HighMode::MANUAL_SYNC_MODE; + auto ret = GeneralStore::MixMode(syncMode, highMode); + ASSERT_EQ(ret, 0); +} + +/** +* @tc.name: GetSyncMode +* @tc.desc: get sync mode. +* @tc.type: FUNC +*/ +HWTEST_F(GeneralStoreTest, GetSyncMode, TestSize.Level1) +{ + uint32_t syncMode = GeneralStore::SyncMode::NEARBY_PULL; + uint32_t highMode = GeneralStore::HighMode::MANUAL_SYNC_MODE; + auto mixMode = GeneralStore::MixMode(syncMode, highMode); + auto ret = GeneralStore::GetSyncMode(mixMode); + ASSERT_EQ(ret, syncMode); +} + +/** +* @tc.name: GetHighMode +* @tc.desc: get high mode. +* @tc.type: FUNC +*/ +HWTEST_F(GeneralStoreTest, GetHighMode, TestSize.Level1) +{ + uint32_t syncMode = GeneralStore::SyncMode::NEARBY_PULL; + uint32_t highMode = GeneralStore::HighMode::MANUAL_SYNC_MODE; + auto mixMode = GeneralStore::MixMode(syncMode, highMode); + auto ret = GeneralStore::GetHighMode(mixMode); + ASSERT_EQ(ret, highMode); +} + +/** +* @tc.name: BindInfo +* @tc.desc: bind info. +* @tc.type: FUNC +*/ +HWTEST_F(GeneralStoreTest, BindInfo, TestSize.Level1) +{ + std::shared_ptr db; + std::shared_ptr loader; + GeneralStore::BindInfo bindInfo(db, loader); + ASSERT_EQ(bindInfo.db_, db); + ASSERT_EQ(bindInfo.loader_, loader); +} + diff --git a/datamgr_service/services/distributeddataservice/framework/test/meta_data_manager_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/meta_data_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..161b2261e3db03217a997234adc1c1d80ba403c4 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/meta_data_manager_test.cpp @@ -0,0 +1,58 @@ +/* +* 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/meta_data_manager.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class MetaDataManagerTest : public testing::Test { +}; + +/** +* @tc.name: FilterConstructorAndGetKeyTest +* @tc.desc: FilterConstructor and GetKey. +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(MetaDataManagerTest, FilterConstructorAndGetKeyTest, TestSize.Level1) +{ + std::string pattern = "test"; + MetaDataManager::Filter filter(pattern); + + std::vector key = filter.GetKey(); + ASSERT_EQ(key.size(), 0); +} + +/** +* @tc.name: FilterOperatorTest +* @tc.desc: FilterOperator. +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(MetaDataManagerTest, FilterOperatorTest, TestSize.Level1) +{ + std::string pattern = "test"; + MetaDataManager::Filter filter(pattern); + + std::string key = "test_key"; + ASSERT_TRUE(filter(key)); + + key = "another_key"; + ASSERT_FALSE(filter(key)); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..742195e0c945d27b039196607c09a2e753ecba98 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp @@ -0,0 +1,638 @@ +/* + * 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 "gtest/gtest.h" +#include "utils/constant.h" +#include +#include "bootstrap.h" +#include "device_manager_adapter.h" +#include "kvstore_meta_manager.h" +#include "metadata/appid_meta_data.h" +#include "metadata/corrupted_meta_data.h" +#include "metadata/capability_range.h" +#include "metadata/meta_data.h" +#include "metadata/meta_data_manager.h" +#include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "metadata/strategy_meta_data.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::DistributedKv; +using namespace OHOS::DistributedData; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +namespace OHOS::Test { +class ServiceMetaDataTest : public testing::Test { +public: + static constexpr size_t NUM_MIN = 5; + static constexpr size_t NUM_MAX = 12; + static constexpr uint32_t TEST_CURRENT_VERSION = 0x03000002; + static void SetUpTestCase() + { + auto executors = std::make_shared(NUM_MAX, NUM_MIN); + Bootstrap::GetInstance().LoadComponents(); + Bootstrap::GetInstance().LoadDirectory(); + Bootstrap::GetInstance().LoadCheckers(); + KvStoreMetaManager::GetInstance().BindExecutor(executors); + KvStoreMetaManager::GetInstance().InitMetaParameter(); + KvStoreMetaManager::GetInstance().InitMetaListener(); + DmAdapter::GetInstance().Init(executors); + } + static void TearDownTestCase(void) {}; + void SetUp() {}; + void TearDown() {}; +}; + +/** +* @tc.name: AppIDMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, AppIDMetaData, TestSize.Level1) +{ + AppIDMetaData appIdMetaData("appid", "ohos.test.demo"); + AppIDMetaData appIdMeta; + + std::string key = appIdMetaData.GetKey(); + EXPECT_EQ(key, "appid"); + auto result = MetaDataManager::GetInstance().SaveMeta(key, appIdMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, appIdMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(appIdMetaData.appId, appIdMeta.appId); + EXPECT_EQ(appIdMetaData.bundleName, appIdMeta.bundleName); + EXPECT_EQ(appIdMetaData.GetKey(), appIdMeta.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, appIdMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, appIdMeta); + EXPECT_TRUE(result); + EXPECT_EQ(appIdMetaData.appId, appIdMeta.appId); + EXPECT_EQ(appIdMetaData.bundleName, appIdMeta.bundleName); + EXPECT_EQ(appIdMetaData.GetKey(), appIdMeta.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: corruptedMeta +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, corruptedMeta, TestSize.Level1) +{ + CorruptedMetaData corruptedMeta("appid", "ohos.test.demo", "test_store"); + CorruptedMetaData corruptedMetaData; + corruptedMeta.isCorrupted = true; + std::string key = corruptedMeta.GetKey(); + EXPECT_EQ(key, "CorruptedMetaData###appid###ohos.test.demo###test_store"); + + auto result = MetaDataManager::GetInstance().SaveMeta(key, corruptedMeta, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, corruptedMetaData, true); + EXPECT_TRUE(result); + EXPECT_EQ(corruptedMeta.appId, corruptedMetaData.appId); + EXPECT_EQ(corruptedMeta.bundleName, corruptedMetaData.bundleName); + EXPECT_EQ(corruptedMeta.storeId, corruptedMetaData.storeId); + EXPECT_EQ(corruptedMeta.GetKey(), corruptedMetaData.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, corruptedMeta); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, corruptedMetaData); + EXPECT_TRUE(result); + EXPECT_EQ(corruptedMeta.appId, corruptedMetaData.appId); + EXPECT_EQ(corruptedMeta.bundleName, corruptedMetaData.bundleName); + EXPECT_EQ(corruptedMeta.storeId, corruptedMetaData.storeId); + EXPECT_EQ(corruptedMeta.GetKey(), corruptedMetaData.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: SecretKeyMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, SecretKeyMetaData001, TestSize.Level1) +{ + SecretKeyMetaData secretKeyMeta; + SecretKeyMetaData secretKeyMetaData; + secretKeyMeta.storeType = 1; + std::initializer_list fields = {"time", "skey"}; + + std::string key = secretKeyMeta.GetKey(fields); + EXPECT_EQ(key, "SecretKey###time###skey###SINGLE_KEY"); + std::string backupkey = secretKeyMeta.GetBackupKey(fields); + EXPECT_EQ(backupkey, "BackupSecretKey###time###skey###"); + + auto result = MetaDataManager::GetInstance().SaveMeta(key, secretKeyMeta, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, secretKeyMetaData, true); + EXPECT_TRUE(result); + EXPECT_EQ(secretKeyMeta.GetKey(fields), secretKeyMetaData.GetKey(fields)); + EXPECT_EQ(secretKeyMeta.GetBackupKey(fields), secretKeyMetaData.GetBackupKey(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, secretKeyMeta); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, secretKeyMetaData); + EXPECT_TRUE(result); + EXPECT_EQ(secretKeyMeta.GetKey(fields), secretKeyMetaData.GetKey(fields)); + EXPECT_EQ(secretKeyMeta.GetBackupKey(fields), secretKeyMetaData.GetBackupKey(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: SecretKeyMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, SecretKeyMetaData002, TestSize.Level1) +{ + SecretKeyMetaData secretKeyMeta; + SecretKeyMetaData secretKeyMetaData; + secretKeyMeta.storeType = 1; + std::initializer_list fields = {"time", "skey"}; + + std::string prefix = secretKeyMeta.GetPrefix(fields); + EXPECT_EQ(prefix, "SecretKey###time###skey###"); + std::string backupprefix = secretKeyMeta.GetBackupPrefix(fields); + EXPECT_EQ(backupprefix, "BackupSecretKey###time###skey###"); + + auto result = MetaDataManager::GetInstance().SaveMeta(prefix, secretKeyMeta, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(prefix, secretKeyMetaData, true); + EXPECT_TRUE(result); + EXPECT_EQ(secretKeyMeta.GetPrefix(fields), secretKeyMetaData.GetPrefix(fields)); + EXPECT_EQ(secretKeyMeta.GetBackupPrefix(fields), secretKeyMetaData.GetBackupPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(prefix, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(prefix, secretKeyMeta); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(prefix, secretKeyMetaData); + EXPECT_TRUE(result); + EXPECT_EQ(secretKeyMeta.GetPrefix(fields), secretKeyMetaData.GetPrefix(fields)); + EXPECT_EQ(secretKeyMeta.GetBackupPrefix(fields), secretKeyMetaData.GetBackupPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(prefix); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData001, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + StoreMetaData storeMeta; + + std::string key = storeMetaData.GetKey(); + EXPECT_EQ(key, "KvStoreMetaData######100###default######test_store"); + std::string keylocal = storeMetaData.GetKeyLocal(); + EXPECT_EQ(keylocal, "KvStoreMetaDataLocal######100###default######test_store"); + std::initializer_list fields = {"100", "appid", "test_store"}; + std::string keyfields = storeMetaData.GetKey(fields); + EXPECT_EQ(keyfields, "KvStoreMetaData###100###appid###test_store"); + + auto result = MetaDataManager::GetInstance().SaveMeta(key, storeMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, storeMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetKey(), storeMeta.GetKey()); + EXPECT_EQ(storeMetaData.GetKeyLocal(), storeMeta.GetKeyLocal()); + EXPECT_EQ(storeMetaData.GetKey(fields), storeMeta.GetKey(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, storeMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, storeMeta); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetKey(), storeMeta.GetKey()); + EXPECT_EQ(storeMetaData.GetKeyLocal(), storeMeta.GetKeyLocal()); + EXPECT_EQ(storeMetaData.GetKey(fields), storeMeta.GetKey(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData002, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + StoreMetaData storeMeta; + + std::string secretkey = storeMetaData.GetSecretKey(); + EXPECT_EQ(secretkey, "SecretKey###100###default######test_store###0###SINGLE_KEY"); + std::string backupsecretkey = storeMetaData.GetBackupSecretKey(); + EXPECT_EQ(backupsecretkey, "BackupSecretKey###100###default######test_store###0###"); + + auto result = MetaDataManager::GetInstance().SaveMeta(secretkey, storeMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(secretkey, storeMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetSecretKey(), storeMeta.GetSecretKey()); + EXPECT_EQ(storeMetaData.GetBackupSecretKey(), storeMeta.GetBackupSecretKey()); + + result = MetaDataManager::GetInstance().DelMeta(secretkey, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(secretkey, storeMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(secretkey, storeMeta); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetSecretKey(), storeMeta.GetSecretKey()); + EXPECT_EQ(storeMetaData.GetBackupSecretKey(), storeMeta.GetBackupSecretKey()); + + result = MetaDataManager::GetInstance().DelMeta(secretkey); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData003, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + StoreMetaData storeMeta; + + auto storealias = storeMetaData.GetStoreAlias(); + EXPECT_EQ(storealias, "tes***ore"); + std::string strategykey = storeMetaData.GetStrategyKey(); + EXPECT_EQ(strategykey, "StrategyMetaData######100###default######test_store"); + std::initializer_list fields = {"100", "appid", "test_store"}; + std::string prefix = storeMetaData.GetPrefix(fields); + EXPECT_EQ(prefix, "KvStoreMetaData###100###appid###test_store###"); + + auto result = MetaDataManager::GetInstance().SaveMeta(strategykey, storeMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(strategykey, storeMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetStrategyKey(), storeMeta.GetStrategyKey()); + EXPECT_EQ(storeMetaData.GetStoreAlias(), storeMeta.GetStoreAlias()); + EXPECT_EQ(storeMetaData.GetPrefix(fields), storeMeta.GetPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(strategykey, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(strategykey, storeMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(strategykey, storeMeta); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetStrategyKey(), storeMeta.GetStrategyKey()); + EXPECT_EQ(storeMetaData.GetStoreAlias(), storeMeta.GetStoreAlias()); + EXPECT_EQ(storeMetaData.GetPrefix(fields), storeMeta.GetPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(strategykey); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData004, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + storeMetaData.version = TEST_CURRENT_VERSION; + storeMetaData.instanceId = 1; + StoreMetaData storeMeta; + + std::string key = storeMetaData.GetKey(); + EXPECT_EQ(key, "KvStoreMetaData######100###default######test_store###1"); + std::string keylocal = storeMetaData.GetKeyLocal(); + EXPECT_EQ(keylocal, "KvStoreMetaDataLocal######100###default######test_store###1"); + + auto result = MetaDataManager::GetInstance().SaveMeta(key, storeMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, storeMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetKey(), storeMeta.GetKey()); + EXPECT_EQ(storeMetaData.GetKeyLocal(), storeMeta.GetKeyLocal()); + + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, storeMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, storeMeta); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetKey(), storeMeta.GetKey()); + EXPECT_EQ(storeMetaData.GetKeyLocal(), storeMeta.GetKeyLocal()); + + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData005, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + storeMetaData.version = TEST_CURRENT_VERSION; + storeMetaData.instanceId = 1; + StoreMetaData storeMeta; + + std::string secretkey = storeMetaData.GetSecretKey(); + EXPECT_EQ(secretkey, "SecretKey###100###default######test_store###SINGLE_KEY"); + std::string backupsecretkey = storeMetaData.GetBackupSecretKey(); + EXPECT_EQ(backupsecretkey, "BackupSecretKey###100###default######test_store###"); + std::string strategykey = storeMetaData.GetStrategyKey(); + EXPECT_EQ(strategykey, "StrategyMetaData######100###default######test_store###1"); + + auto result = MetaDataManager::GetInstance().SaveMeta(secretkey, storeMetaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(secretkey, storeMeta, true); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetSecretKey(), storeMeta.GetSecretKey()); + EXPECT_EQ(storeMetaData.GetBackupSecretKey(), storeMeta.GetBackupSecretKey()); + EXPECT_EQ(storeMetaData.GetStrategyKey(), storeMeta.GetStrategyKey()); + + result = MetaDataManager::GetInstance().DelMeta(secretkey, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(secretkey, storeMetaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(secretkey, storeMeta); + EXPECT_TRUE(result); + EXPECT_EQ(storeMetaData.GetSecretKey(), storeMeta.GetSecretKey()); + EXPECT_EQ(storeMetaData.GetBackupSecretKey(), storeMeta.GetBackupSecretKey()); + EXPECT_EQ(storeMetaData.GetStrategyKey(), storeMeta.GetStrategyKey()); + + result = MetaDataManager::GetInstance().DelMeta(secretkey); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData006, TestSize.Level1) +{ + StoreMetaData storemetaData1("100", "appid", "test_store"); + StoreMetaData storemetaData2("100", "appid", "test_store"); + StoreMetaData storemetaData3("10", "appid1", "storeid"); + EXPECT_TRUE(storemetaData1 == storemetaData2); + EXPECT_FALSE(storemetaData1 == storemetaData3); + + storemetaData1.isAutoSync = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isAutoSync = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.isBackup = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isBackup = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.isDirty = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isDirty = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.isEncrypt = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isEncrypt = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.isSearchable = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isSearchable = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.isNeedCompress = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.isNeedCompress = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); +} + +/** +* @tc.name: StoreMetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StoreMetaData007, TestSize.Level1) +{ + StoreMetaData storemetaData1("100", "appid", "test_store"); + StoreMetaData storemetaData2("100", "appid", "test_store"); + StoreMetaData storemetaData3("10", "appid1", "storeid"); + EXPECT_TRUE(storemetaData1 != storemetaData3); + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isAutoSync = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isAutoSync = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isBackup = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isBackup = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isDirty = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isDirty = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isEncrypt = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isEncrypt = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isSearchable = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isSearchable = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.isNeedCompress = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.isNeedCompress = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); +} + +/** +* @tc.name: StrategyMeta001 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StrategyMeta001, TestSize.Level1) +{ + auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + StrategyMeta strategyMeta(deviceId, "100", "ohos.test.demo", "test_store"); + std::vector local = {"local1"}; + std::vector remote = {"remote1"}; + strategyMeta.capabilityRange.localLabel = local; + strategyMeta.capabilityRange.remoteLabel = remote; + strategyMeta.capabilityEnabled = true; + auto result = strategyMeta.IsEffect(); + EXPECT_TRUE(result); + StrategyMeta strategyMetaData(deviceId, "200", "ohos.test.test", "test_stores"); + + std::string key = strategyMeta.GetKey(); + EXPECT_EQ(key, "StrategyMetaData######100###default###ohos.test.demo###test_store"); + std::initializer_list fields = { deviceId, "100", "default", "ohos.test.demo", "test_store" }; + std::string prefix = strategyMeta.GetPrefix(fields); + EXPECT_EQ(prefix, "StrategyMetaData######100###default###ohos.test.demo###test_store"); + + result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, strategyMetaData, true); + EXPECT_TRUE(result); + EXPECT_EQ(strategyMeta.GetKey(), strategyMetaData.GetKey()); + EXPECT_EQ(strategyMeta.GetPrefix(fields), strategyMetaData.GetPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, strategyMetaData); + EXPECT_TRUE(result); + EXPECT_EQ(strategyMeta.GetKey(), strategyMetaData.GetKey()); + EXPECT_EQ(strategyMeta.GetPrefix(fields), strategyMetaData.GetPrefix(fields)); + + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: StrategyMeta +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, StrategyMeta002, TestSize.Level1) +{ + auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + StrategyMeta strategyMeta(deviceId, "100", "ohos.test.demo", "test_store"); + std::vector local = {"local1"}; + std::vector remote = {"remote1"}; + strategyMeta.capabilityRange.localLabel = local; + strategyMeta.capabilityRange.remoteLabel = remote; + strategyMeta.capabilityEnabled = true; + auto result = strategyMeta.IsEffect(); + EXPECT_TRUE(result); + strategyMeta.instanceId = 1; + StrategyMeta strategyMetaData(deviceId, "200", "ohos.test.test", "test_stores"); + + std::string key = strategyMeta.GetKey(); + EXPECT_EQ(key, "StrategyMetaData######100###default###ohos.test.demo###test_store###1"); + + result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, strategyMetaData, true); + EXPECT_TRUE(result); + EXPECT_EQ(strategyMeta.GetKey(), strategyMetaData.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, strategyMetaData); + EXPECT_TRUE(result); + EXPECT_EQ(strategyMeta.GetKey(), strategyMetaData.GetKey()); + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} + +/** +* @tc.name: MetaData +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, MetaData, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + SecretKeyMetaData secretKeyMetaData; + MetaData metaData; + MetaData metaDataLoad; + metaData.storeMetaData = storeMetaData; + metaData.secretKeyMetaData = secretKeyMetaData; + metaData.storeType = 1; + std::initializer_list fields = {"time", "skey"}; + std::string key = metaData.storeMetaData.GetKey(); + std::string secretkey = metaData.secretKeyMetaData.GetKey(fields); + + auto result = MetaDataManager::GetInstance().SaveMeta(key, metaData, true); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, metaDataLoad, true); + EXPECT_TRUE(result); + EXPECT_EQ(key, metaDataLoad.storeMetaData.GetKey()); + EXPECT_EQ(secretkey, metaDataLoad.secretKeyMetaData.GetKey(fields)); + result = MetaDataManager::GetInstance().DelMeta(key, true); + EXPECT_TRUE(result); + + result = MetaDataManager::GetInstance().SaveMeta(key, metaData); + EXPECT_TRUE(result); + result = MetaDataManager::GetInstance().LoadMeta(key, metaDataLoad); + EXPECT_TRUE(result); + EXPECT_EQ(key, metaDataLoad.storeMetaData.GetKey()); + EXPECT_EQ(secretkey, metaDataLoad.secretKeyMetaData.GetKey(fields)); + result = MetaDataManager::GetInstance().DelMeta(key); + EXPECT_TRUE(result); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp index d12a95f5de18bcf40cc05edd20a96a0af04db5d3..14a00bf91a0266ec90bec59962ead12d0fd43a31 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp @@ -301,4 +301,17 @@ HWTEST_F(SerializableTest, SetPointerValue, TestSize.Level2) out.Unmarshall(json); ASSERT_TRUE(in == out) << in.count; } + +/** +* @tc.name: IsJson +* @tc.desc: is json. +* @tc.type: FUNC +*/ +HWTEST_F(SerializableTest, IsJson, TestSize.Level1) +{ + std::string str = "test"; + std::string jsonStr = "\"test\""; + ASSERT_FALSE(Serializable::IsJson(str)); + ASSERT_TRUE(Serializable::IsJson(jsonStr)); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b061380ea42dbf5561ef19d19b73bdf4438f1ef2 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp @@ -0,0 +1,69 @@ +/* +* 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_meta_data_local.h" + +#include + +using namespace testing::ext; +using OHOS::DistributedData::StoreMetaDataLocal; + +class StoreMetaDataLocalTest : public testing::Test { +}; + +/** +* @tc.name: EqualityOperatorTest And InequalityOperatorTest +* @tc.desc: equalityOperator and inequalityOperator +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(StoreMetaDataLocalTest, EqualityOperatorTest, TestSize.Level1) +{ + StoreMetaDataLocal metaData1; + metaData1.isAutoSync = true; + metaData1.isBackup = true; + StoreMetaDataLocal metaData2; + metaData2.isAutoSync = true; + metaData2.isBackup = false; + StoreMetaDataLocal metaData3; + metaData3.isAutoSync = true; + metaData3.isBackup = true; + + ASSERT_FALSE(metaData1 == metaData2); + ASSERT_TRUE(metaData1 == metaData3); + ASSERT_FALSE(metaData2 == metaData3); + + ASSERT_TRUE(metaData1 != metaData2); + ASSERT_FALSE(metaData1 != metaData3); + ASSERT_TRUE(metaData2 != metaData3); +} + +/** +* @tc.name: GetPrefixTest +* @tc.desc: getPrefix +* @tc.type: FUNC +* @tc.require: +* @tc.author: MengYao +*/ +HWTEST_F(StoreMetaDataLocalTest, GetPrefixTest, TestSize.Level1) +{ + StoreMetaDataLocal metaData; + std::string expectedPrefix = "KvStoreMetaDataLocal###field1###field2###"; + std::initializer_list fields{ "field1", "field2" }; + + std::string prefix = metaData.GetPrefix(fields); + + ASSERT_EQ(prefix, expectedPrefix); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1d58814adc66ae1030fa439055af9d1cc9ca8a8 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp @@ -0,0 +1,88 @@ +/* +* 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 "StoreTest" + +#include "access_token.h" +#include "gtest/gtest.h" +#include "log_print.h" +#include "rdb_query.h" +#include "rdb_types.h" +#include "store/general_store.h" +#include "store/general_value.h" +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class GeneralValueTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; +class GeneralStoreTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +/** + * @tc.name: SetQueryNodesTest + * @tc.desc: Set and query nodes. + * @tc.type: FUNC + * @tc.require: AR000F8N0 + */ +HWTEST_F(GeneralValueTest, SetQueryNodesTest, TestSize.Level2) +{ + ZLOGI("GeneralValueTest SetQueryNodesTest begin."); + std::string tableName = "test_tableName"; + QueryNode node; + node.op = OHOS::DistributedData::QueryOperation::EQUAL_TO; + node.fieldName = "test_fieldName"; + node.fieldValue = {"aaa", "bbb", "ccc"}; + QueryNodes nodes{ + {node} + }; + OHOS::DistributedRdb::RdbQuery query; + query.SetQueryNodes(tableName, std::move(nodes)); + QueryNodes nodes1 = query.GetQueryNodes("test_tableName"); + EXPECT_EQ(nodes1[0].fieldName, "test_fieldName"); + EXPECT_EQ(nodes1[0].op, OHOS::DistributedData::QueryOperation::EQUAL_TO); + EXPECT_EQ(nodes1[0].fieldValue.size(), 3); +} + +/** +* @tc.name: GetMixModeTest +* @tc.desc: get mix mode +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(GeneralStoreTest, GetMixModeTest, TestSize.Level2) +{ + ZLOGI("GeneralStoreTest GetMixModeTest begin."); + auto mode1 = OHOS::DistributedRdb::TIME_FIRST; + auto mode2 = GeneralStore::AUTO_SYNC_MODE; + + auto mixMode = GeneralStore::MixMode(mode1, mode2); + EXPECT_EQ(mixMode, mode1 | mode2); + + auto syncMode = GeneralStore::GetSyncMode(mixMode); + EXPECT_EQ(syncMode, OHOS::DistributedRdb::TIME_FIRST); + + auto highMode = GeneralStore::GetHighMode(mixMode); + EXPECT_EQ(highMode, GeneralStore::AUTO_SYNC_MODE); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/subscription_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/subscription_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39ebac54d2f8dd0cf620fdb52a1a96f9f459ccf0 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/subscription_test.cpp @@ -0,0 +1,159 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "cloud/subscription.h" + +#include + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class SubscriptionTest : public testing::Test { +public: + const std::map testRelation = { { "testUserId", "testBundleName" } }; + const std::map testExpiresTime = { { "1h", 3600 } }; +}; + +/** +* @tc.name: RelationMarshal +* @tc.desc: relation marshal. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, RelationMarshal, TestSize.Level1) +{ + Subscription::Relation relation; + relation.id = "testId"; + relation.bundleName = "testBundleName"; + relation.relations = testRelation; + Subscription::json node; + relation.Marshal(node); + ASSERT_EQ(node["id"], "testId"); + ASSERT_EQ(node["bundleName"], "testBundleName"); + ASSERT_EQ(node["relations"], testRelation); +} + +/** +* @tc.name: RelationUnmarshal +* @tc.desc: relation unmarshal. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, RelationUnmarshal, TestSize.Level1) +{ + Subscription::json node; + node["id"] = "testId"; + node["bundleName"] = "testBundleName"; + node["relations"] = testRelation; + Subscription::Relation relation; + relation.Unmarshal(node); + ASSERT_EQ(relation.id, "testId"); + ASSERT_EQ(relation.bundleName, "testBundleName"); + ASSERT_EQ(relation.relations, testRelation); +} + +/** +* @tc.name: Marshal +* @tc.desc: marshal. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, Marshal, TestSize.Level1) +{ + Subscription subscription; + subscription.userId = 100; + subscription.id = "testId"; + subscription.expiresTime = testExpiresTime; + Subscription::json node; + subscription.Marshal(node); + ASSERT_EQ(node["userId"], 100); + ASSERT_EQ(node["id"], "testId"); + ASSERT_EQ(node["expiresTime"], testExpiresTime); +} + +/** +* @tc.name: Unmarshal +* @tc.desc: unmarshal. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, Unmarshal, TestSize.Level1) +{ + Subscription::json node; + node["userId"] = 100; + node["id"] = "testId"; + node["expiresTime"] = testExpiresTime; + Subscription subscription; + subscription.Unmarshal(node); + ASSERT_EQ(subscription.userId, 100); + ASSERT_EQ(subscription.id, "testId"); + ASSERT_EQ(subscription.expiresTime, testExpiresTime); +} + +/** +* @tc.name: GetKey +* @tc.desc: get key. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, GetKey, TestSize.Level1) +{ + Subscription subscription; + subscription.userId = 100; + std::string key = subscription.GetKey(); + ASSERT_EQ(key, "CLOUD_SUBSCRIPTION###100"); +} + +/** +* @tc.name: GetRelationKey +* @tc.desc: get relation key. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, GetRelationKey, TestSize.Level1) +{ + Subscription subscription; + subscription.userId = 100; + std::string relationKey = subscription.GetRelationKey("testBundleName"); + ASSERT_EQ(relationKey, "CLOUD_RELATION###100###testBundleName"); +} + +/** +* @tc.name: GetKey002 +* @tc.desc: get key. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, GetKey002, TestSize.Level1) +{ + std::string key = Subscription::GetKey(100); + ASSERT_EQ(key, "CLOUD_SUBSCRIPTION###100"); +} + +/** +* @tc.name: GetRelationKey002 +* @tc.desc: get relation key. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, GetRelationKey002, TestSize.Level1) +{ + std::string relationKey = Subscription::GetRelationKey(100, "testBundleName"); + ASSERT_EQ(relationKey, "CLOUD_RELATION###100###testBundleName"); +} + +/** +* @tc.name: GetPrefix +* @tc.desc: get prefix. +* @tc.type: FUNC +*/ +HWTEST_F(SubscriptionTest, GetPrefix, TestSize.Level1) +{ + std::initializer_list fields = { "field1", "field2" }; + std::string prefix = Subscription::GetPrefix(fields); + ASSERT_EQ(prefix, "CLOUD_SUBSCRIPTION###field1###field2"); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..435130c1555ab5e6238eca843d001fda7f7d0ca8 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp @@ -0,0 +1,141 @@ +/* +* 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 "UtilsTest" +#include + +#include "access_token.h" +#include "gtest/gtest.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "utils/block_integer.h" +#include "utils/converter.h" +#include "utils/ref_count.h" +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class UtilsTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class BlockIntegerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; + static uint64_t GetCurrentTime() + { + return static_cast(std::chrono::duration_cast + (std::chrono::system_clock::now().time_since_epoch()).count()); + } + int intervalTime = 100 * 1000; + int testNum = 10; +}; + +class RefCountTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +/** + * @tc.name: StoreMetaDataConvertToStoreInfo + * @tc.desc: Storemeta data convert to storeinfo. + * @tc.type: FUNC + */ +HWTEST_F(UtilsTest, StoreMetaDataConvertToStoreInfo, TestSize.Level2) +{ + ZLOGI("UtilsTest StoreMetaDataConvertToStoreInfo begin."); + StoreMetaData metaData; + metaData.bundleName = "ohos.test.demo1"; + metaData.storeId = "test_storeId"; + metaData.uid = OHOS::IPCSkeleton::GetCallingUid(); + metaData.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + CheckerManager::StoreInfo info = Converter::ConvertToStoreInfo(metaData); + EXPECT_EQ(info.uid, metaData.uid); + EXPECT_EQ(info.tokenId, metaData.tokenId); + EXPECT_EQ(info.bundleName, metaData.bundleName); + EXPECT_EQ(info.storeId, metaData.storeId); +} + + +/** +* @tc.name: SymbolOverloadingTest +* @tc.desc: Symbol Overloading +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(BlockIntegerTest, SymbolOverloadingTest, TestSize.Level2) +{ + ZLOGI("BlockIntegerTest SymbolOverloading begin."); + int interval = intervalTime; + BlockInteger blockInteger(interval); + blockInteger = testNum; + ASSERT_EQ(blockInteger, testNum); + + auto now1 = GetCurrentTime(); + int val = blockInteger++; + auto now2 = GetCurrentTime(); + ASSERT_EQ(val, 10); + ASSERT_EQ(blockInteger, 11); + ASSERT_TRUE(now2 - now1 >= interval); + + now1 = GetCurrentTime(); + val = ++blockInteger; + now2 = GetCurrentTime(); + ASSERT_EQ(val, 12); + ASSERT_EQ(blockInteger, 12); + ASSERT_TRUE(now2 - now1 >= interval); + ASSERT_TRUE(blockInteger < 20); +} + +/** +* @tc.name: ConstrucTortest +* @tc.desc: Create Object. +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) +{ + int num = 0; + { + RefCount refCount([&num]() { + num += 10; + }); + ASSERT_TRUE(refCount); + + RefCount refCount1(refCount); + ASSERT_TRUE(refCount1); + + RefCount refCount2(std::move(refCount)); + ASSERT_TRUE(refCount2); + + RefCount refCount3 = refCount1; + ASSERT_TRUE(refCount3); + + RefCount refCount4 = std::move(refCount2); + ASSERT_TRUE(refCount4); + ASSERT_EQ(num, 0); + } + ASSERT_EQ(num, 10); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn index 16b18c0d4b98a409ecd9782e6342cb6f45498a8f..15a75ef1f30df320e789bf3f072102bd377e1d40 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn @@ -54,6 +54,7 @@ ohos_shared_library("opencloudextension") { external_deps = [ "access_token:libaccesstoken_sdk", "hilog:libhilog", + "kv_store:distributeddata_inner", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 8f958cf3a47531883641e53cfec1e70dd490a6b2..ab8832b6fc2629c44494e4e758a3863124dfce95 100644 --- a/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -93,6 +93,13 @@ void Bootstrap::LoadCheckers() } checker->SetTrustInfo(trust); } + for (const auto &distrust : checkers->distrusts) { + auto *checker = CheckerManager::GetInstance().GetChecker(distrust.checker); + if (checker == nullptr) { + continue; + } + checker->SetDistrustInfo(distrust); + } } void Bootstrap::LoadBackup(std::shared_ptr executors) diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index b27c27fa9dec5985717bd4a8c11228d2def18c92..960d9ca4678ad62d0f3e0429a8d41a9796c0bc1a 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -17,6 +17,8 @@ #include "cloud_service_impl.h" +#include +#include #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "checker/checker_manager.h" @@ -74,6 +76,17 @@ CloudServiceImpl::CloudServiceImpl() EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SHARE, [this](const Event &event) { CloudShare(event); }); + MetaDataManager::GetInstance().Subscribe( + Subscription::GetPrefix({ "" }), [this](const std::string &key, + const std::string &value, int32_t flag) -> auto { + if (flag != MetaDataManager::INSERT && flag != MetaDataManager::UPDATE) { + return true; + } + Subscription sub; + Subscription::Unmarshall(value, sub); + InitSubTask(sub); + return true; + }, true); } int32_t CloudServiceImpl::EnableCloud(const std::string &id, const std::map &switches) @@ -164,7 +177,7 @@ int32_t CloudServiceImpl::DoClean(CloudInfo &cloudInfo, const std::map()); Execute(GenTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB })); + std::vector users; + Account::GetInstance()->QueryUsers(users); + for (auto user : users) { + if (user == DEFAULT_USER) { + continue; + } + Subscription sub; + sub.userId = user; + if (!MetaDataManager::GetInstance().LoadMeta(sub.GetKey(), sub, true)) { + continue; + } + InitSubTask(sub); + } return E_OK; } @@ -323,6 +349,10 @@ int32_t CloudServiceImpl::OnBind(const BindInfo &info) executor_ = std::move(info.executors); syncManager_.Bind(executor_); + auto instance = CloudServer::GetInstance(); + if (instance != nullptr) { + instance->Bind(executor_); + } return E_OK; } @@ -382,7 +412,8 @@ std::pair CloudServiceImpl::GetCloudInfoFromMeta(int32_t use CloudInfo cloudInfo; cloudInfo.user = userId; if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true)) { - ZLOGE("no exist meta, user:%{public}d", cloudInfo.user); + auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + ZLOGE("no exist meta, user:%{public}d times:%{public}" PRIu64 ".", cloudInfo.user, time); return { ERROR, cloudInfo }; } return { SUCCESS, cloudInfo }; @@ -392,6 +423,9 @@ std::pair CloudServiceImpl::GetCloudInfoFromServer(int32_t u { CloudInfo cloudInfo; cloudInfo.user = userId; + if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + return { ERROR, cloudInfo }; + } auto instance = CloudServer::GetInstance(); if (instance == nullptr) { return { SERVER_UNAVAILABLE, cloudInfo }; @@ -450,6 +484,9 @@ bool CloudServiceImpl::UpdateSchema(int32_t user) std::pair CloudServiceImpl::GetAppSchemaFromServer(int32_t user, const std::string &bundleName) { SchemaMeta schemaMeta; + if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + return { ERROR, schemaMeta }; + } auto instance = CloudServer::GetInstance(); if (instance == nullptr) { return { SERVER_UNAVAILABLE, schemaMeta }; @@ -538,7 +575,7 @@ std::pair CloudServiceImpl::GetCloudInfo(int32_t userId) return { ERROR, cloudInfo }; } std::tie(status, cloudInfo) = GetCloudInfoFromServer(userId); - if (status == SUCCESS) { + if (status != SUCCESS) { return { status, cloudInfo }; } MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); @@ -573,6 +610,7 @@ void CloudServiceImpl::CloudShare(const Event &event) if (callback) { callback(GeneralError::E_ERROR, nullptr); } + return; } ZLOGD("Start PreShare, bundleName:%{public}s, storeName:%{public}s, instanceId:%{public}d", storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.instanceId); @@ -592,7 +630,7 @@ std::pair> CloudServiceImpl::P meta.user = std::to_string(storeInfo.user); meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; meta.instanceId = storeInfo.instanceId; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + if (!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 { GeneralError::E_ERROR, nullptr }; @@ -962,4 +1000,48 @@ std::shared_ptr CloudServiceImpl::GetSharingHandle(const HapInfo auto handle = instance->ConnectSharingCenter(hapInfo.user, hapInfo.bundleName); return handle; } + +ExecutorPool::Task CloudServiceImpl::GenSubTask(Task task, int32_t user) +{ + return [this, user, work = std::move(task)] () { + { + std::lock_guard lock(mutex_); + subTask_ = ExecutorPool::INVALID_TASK_ID; + } + auto [status, cloudInfo] = GetCloudInfoFromMeta(user); + if (status != SUCCESS || !cloudInfo.enableCloud || cloudInfo.IsAllSwitchOff()) { + ZLOGW("[sub task] all switch off, status:%{public}d user:%{public}d enableCloud:%{public}d", + status, user, cloudInfo.enableCloud); + return; + } + work(); + }; +} + +void CloudServiceImpl::InitSubTask(const Subscription &sub) +{ + auto expire = sub.GetMinExpireTime(); + if (expire == INVALID_SUB_TIME) { + return; + } + auto executor = executor_; + if (executor == nullptr) { + return; + } + ZLOGI("Subscription Info, subTask:%{public}" PRIu64", user:%{public}d", subTask_, sub.userId); + expire = expire - TIME_BEFORE_SUB; // before 12 hours + auto now = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + Duration delay = expire > now ? milliseconds(expire - now) : milliseconds(0); + std::lock_guard lock(mutex_); + if (subTask_ != ExecutorPool::INVALID_TASK_ID) { + if (expire < expireTime_) { + subTask_ = executor->Reset(subTask_, delay); + expireTime_ = expire > now ? expire : now; + } + return; + } + subTask_ = executor->Schedule(delay, GenSubTask(GenTask(0, sub.userId), sub.userId)); + expireTime_ = expire > now ? expire : now; +} + } // namespace OHOS::CloudData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h index 2e6f30e258dc357333f21596f2ab2832735be54b..10c446d04cab21824b0da53502bdf15d2c38b887 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -86,6 +86,8 @@ private: using Handle = bool (CloudServiceImpl::*)(int32_t); using Handles = std::deque; using Task = ExecutorPool::Task; + using TaskId = ExecutorPool::TaskId; + using Duration = ExecutorPool::Duration; struct HapInfo { int32_t user; @@ -96,11 +98,13 @@ private: static std::map ConvertAction(const std::map &actions); static HapInfo GetHapInfo(uint32_t tokenId); + static constexpr uint64_t INVALID_SUB_TIME = 0; static constexpr int32_t RETRY_TIMES = 3; static constexpr int32_t RETRY_INTERVAL = 60; static constexpr int32_t EXPIRE_INTERVAL = 2 * 24; // 2 day static constexpr int32_t WAIT_TIME = 30; // 30 seconds static constexpr int32_t DEFAULT_USER = 0; + static constexpr int32_t TIME_BEFORE_SUB = 12 * 60 * 60 * 1000; // 12hours, ms bool UpdateCloudInfo(int32_t user); bool UpdateSchema(int32_t user); @@ -120,6 +124,8 @@ private: void CloudShare(const Event &event); Task GenTask(int32_t retry, int32_t user, Handles handles = { WORK_SUB }); + Task GenSubTask(Task task, int32_t user); + void InitSubTask(const Subscription &sub); void Execute(Task task); void CleanSubscription(Subscription &sub); int32_t DoClean(CloudInfo &cloudInfo, const std::map &actions); @@ -132,6 +138,10 @@ private: std::shared_ptr GetSharingHandle(const HapInfo& hapInfo); std::shared_ptr executor_; SyncManager syncManager_; + std::mutex mutex_; + TaskId subTask_ = ExecutorPool::INVALID_TASK_ID; + uint64_t expireTime_ = static_cast(std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); static constexpr Handle WORK_CLOUD_INFO_UPDATE = &CloudServiceImpl::UpdateCloudInfo; static constexpr Handle WORK_SCHEMA_UPDATE = &CloudServiceImpl::UpdateSchema; diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index 8adae93a692240fc3e90ae19b6a44cfb51343262..d739aae727b8ac318b44c394ff0302ba241e0f9e 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -247,7 +247,7 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) meta.user = std::to_string(storeInfo.user); meta.instanceId = storeInfo.instanceId; meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + if (!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; diff --git a/datamgr_service/services/distributeddataservice/service/config/include/model/checker_config.h b/datamgr_service/services/distributeddataservice/service/config/include/model/checker_config.h index 1cbb8c4476040024ec0af56ddaf484529f652e5e..c4755d8ee54a318368ce8f77ea9ece2bbf8de297 100644 --- a/datamgr_service/services/distributeddataservice/service/config/include/model/checker_config.h +++ b/datamgr_service/services/distributeddataservice/service/config/include/model/checker_config.h @@ -25,8 +25,10 @@ public: bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; + using Distrust = Trust; std::vector checkers; std::vector trusts; + std::vector distrusts; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; diff --git a/datamgr_service/services/distributeddataservice/service/config/src/model/checker_config.cpp b/datamgr_service/services/distributeddataservice/service/config/src/model/checker_config.cpp index f543df0ab409182b09250417bb8472d165888444..f65f2d0d32dafc604b2a1e19b2cb3abd83b4c85f 100644 --- a/datamgr_service/services/distributeddataservice/service/config/src/model/checker_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/config/src/model/checker_config.cpp @@ -40,6 +40,7 @@ bool CheckerConfig::Marshal(json &node) const { SetValue(node[GET_NAME(checkers)], checkers); SetValue(node[GET_NAME(trusts)], trusts); + SetValue(node[GET_NAME(distrusts)], distrusts); return true; } @@ -47,6 +48,7 @@ bool CheckerConfig::Unmarshal(const json &node) { GetValue(node, GET_NAME(checkers), checkers); GetValue(node, GET_NAME(trusts), trusts); + GetValue(node, GET_NAME(distrusts), distrusts); return true; } } // namespace DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp index 1bd4a9136475e12e3ac375008aa8e3f28ac9b713..7a692802ab682f6d17a4d936ef9e2bb62040b704 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp @@ -45,7 +45,12 @@ sptr BundleMgrProxy::GetBundleMgrProxy() ZLOGE("deathRecipient alloc failed."); return nullptr; } - proxy_->AddDeathRecipient(deathRecipient_); + if (!proxy_->AddDeathRecipient(deathRecipient_)) { + ZLOGE("add death recipient failed."); + proxy_ = nullptr; + deathRecipient_ = nullptr; + return nullptr; + } return iface_cast(proxy_); } @@ -76,10 +81,12 @@ bool BundleMgrProxy::GetBundleInfoFromBMS( void BundleMgrProxy::OnProxyDied() { std::lock_guard lock(mutex_); + ZLOGE("bundleMgr died, proxy=null ? %{public}s.", proxy_ == nullptr ? "true" : "false"); if (proxy_ != nullptr) { proxy_->RemoveDeathRecipient(deathRecipient_); } proxy_ = nullptr; + deathRecipient_ = nullptr; } BundleMgrProxy::~BundleMgrProxy() diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h index 451f375fa18526d6ac8afeb9425276ed9ee526ad..28db02518138fce1e4f9c1333263f7bef3445c65 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h @@ -21,21 +21,25 @@ namespace OHOS::DataShare { class CallbackImpl : public AAFwk::AbilityConnectionStub { public: - explicit CallbackImpl(BlockData &data) : data_(data) {} + explicit CallbackImpl(std::shared_ptr> data) : data_(data) {} void OnAbilityConnectDone( const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override { - bool result = true; - data_.SetValue(result); + if (data_ == nullptr) { + return; + } + data_->SetValue(true); } void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override { - bool result = false; - data_.SetValue(result); + if (data_ == nullptr) { + return; + } + data_->SetValue(false); } private: - BlockData &data_; + std::shared_ptr> data_; }; } // namespace OHOS::DataShare #endif diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp index 2424abf25d9164877a71500155b4296b25e6479d..9f480741b7d1ff3f8af123c3ddd2bc733af41725 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp @@ -22,6 +22,7 @@ #include "callback_impl.h" #include "extension_mgr_proxy.h" #include "log_print.h" +#include "utils/anonymous.h" namespace OHOS::DataShare { bool ExtensionConnectAdaptor::Connect(std::shared_ptr context) @@ -34,26 +35,26 @@ bool ExtensionConnectAdaptor::Connect(std::shared_ptr context) return false; } -ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(1) {} +ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(std::make_shared>(1)) +{ + callback_ = new (std::nothrow) CallbackImpl(data_); +} bool ExtensionConnectAdaptor::DoConnect(std::shared_ptr context) { - data_.Clear(); - callback_ = new (std::nothrow) CallbackImpl(data_); + data_->Clear(); if (callback_ == nullptr) { - ZLOGE("new failed"); return false; } - ZLOGI("Start connect %{public}s", context->uri.c_str()); ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(context->uri, callback_->AsObject(), nullptr); if (ret != ERR_OK) { - ZLOGE("connect ability failed, ret = %{public}d", ret); + ZLOGE("connect ability failed, ret = %{public}d, uri: %{public}s", ret, + DistributedData::Anonymous::Change(context->uri).c_str()); return false; } - bool result = data_.GetValue(); - if (result) { - ZLOGI("connect ability ended successfully"); - } + bool result = data_->GetValue(); + ZLOGI("Do connect, result: %{public}d, uri: %{public}s", result, + DistributedData::Anonymous::Change(context->uri).c_str()); return result; } @@ -77,12 +78,10 @@ void ExtensionConnectAdaptor::Disconnect() ZLOGE("callback null"); return; } - data_.Clear(); - ZLOGI("Start disconnect"); + data_->Clear(); ExtensionMgrProxy::GetInstance()->DisConnect(callback_->AsObject()); - if (!data_.GetValue()) { - ZLOGI("disconnect ability ended successfully"); - } + bool result = data_->GetValue(); + ZLOGI("Do disconnect, result: %{public}d", result); callback_ = nullptr; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h index 6c24367c46f072ea9bb776f9ec46a3bec7df41b4..44eb9e8353c2af4fe92a5bbb3410a5ee03bf2c92 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h @@ -29,7 +29,7 @@ private: bool Connect(std::shared_ptr context); void Disconnect(); bool DoConnect(std::shared_ptr context); - BlockData data_; + std::shared_ptr> data_; sptr callback_ = nullptr; }; } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index f86c0dfac4170b08e76be7ecffc4e387fff404e6..5a1664050595b30c05c63cc3201cb3a863a71fb3 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -55,7 +55,7 @@ int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValu { ZLOGD("Insert enter."); if (!IsSilentProxyEnable(uri)) { - ZLOGE("check silent proxy switch disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } auto context = std::make_shared(uri); @@ -88,7 +88,7 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred { ZLOGD("Update enter."); if (!IsSilentProxyEnable(uri)) { - ZLOGE("check silent proxy switch disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } auto context = std::make_shared(uri); @@ -104,7 +104,7 @@ int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePred { ZLOGD("Delete enter."); if (!IsSilentProxyEnable(uri)) { - ZLOGE("check silent proxy switch disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } auto context = std::make_shared(uri); @@ -121,7 +121,7 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin { ZLOGD("Query enter."); if (!IsSilentProxyEnable(uri)) { - ZLOGE("check silent proxy switch disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return nullptr; } auto context = std::make_shared(uri); @@ -605,7 +605,6 @@ bool DataShareServiceImpl::IsSilentProxyEnable(const std::string &uri) int32_t currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(callerTokenId); UriInfo uriInfo; if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - ZLOGE("Get uriInfo from URI error."); return true; } std::string calledBundleName = uriInfo.bundleName; @@ -615,7 +614,7 @@ bool DataShareServiceImpl::IsSilentProxyEnable(const std::string &uri) } auto success = dataShareSilentConfig_.IsSilentProxyEnable(calledTokenId, currentUserId, calledBundleName, uri); if (!success) { - ZLOGE("check silent proxy switch disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); } return success; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index ccf44690fb3c8c3918a62e52a1f40ccc6e27e5b9..593ee190089fa08b382fd77751aeb52c72f2f18a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -17,6 +17,7 @@ #include "data_share_service_stub.h" +#include #include "data_share_obs_proxy.h" #include "ipc_skeleton.h" #include "ishared_result_set.h" @@ -320,14 +321,23 @@ int32_t DataShareServiceStub::OnRemoteNotifyConnectDone(MessageParcel &data, Mes int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) { - ZLOGD("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); + auto callingPid = IPCSkeleton::GetCallingPid(); + ZLOGD("code:%{public}u, callingPid:%{public}d", code, callingPid); if (!CheckInterfaceToken(data)) { return DATA_SHARE_ERROR; } + int res = -1; if (code < DATA_SHARE_SERVICE_CMD_MAX) { - return (this->*HANDLERS[code])(data, reply); - } - return -1; + 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); + if (duration >= TIME_THRESHOLD) { + ZLOGW("over time, code:%{public}u callingPid:%{public}d, cost:%{public}" PRIi64 "ms", + code, callingPid, duration.count()); + } + } + return res; } int32_t DataShareServiceStub::OnRemoteNotifyObserver(MessageParcel &data, MessageParcel &reply) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h index b9fa67dfba342bbab49953f84a6267bb3df412ba..e350eb1ce04d88e956d7876f2df29394157ec75f 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -26,6 +26,7 @@ public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; private: + static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(500); static bool CheckInterfaceToken(MessageParcel& data); int32_t OnRemoteInsert(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteUpdate(MessageParcel& data, MessageParcel& reply); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_silent_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_silent_config.cpp index fbeb0e33f8fcda7c448c8749f90378fb9551a1c5..dba45026414108fa1139fcd5d8dda3b885ae8a0c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_silent_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_silent_config.cpp @@ -39,8 +39,6 @@ bool DataShareSilentConfig::IsSilentProxyEnable(uint32_t callerTokenId, int32_t } std::map profileInfos; if (!DataShareProfileConfig::GetProfileInfo(calledBundleName, currentUserId, profileInfos)) { - ZLOGE("GetProfileInfo error, No configuration has been set for silent access. uri:%{public}s", - DistributedData::Anonymous::Change(uri).c_str()); return true; } for (const auto &[key, value] : profileInfos) { @@ -61,7 +59,7 @@ bool DataShareSilentConfig::EnableSilentProxy(uint32_t callerTokenId, const std: uri = ALL_URI; } ZLOGI("Enable silent proxy, callerTokenId:%{public}u, enable:%{public}d, uri:%{public}s", - callerTokenId, enable, uri.c_str()); + callerTokenId, enable, DistributedData::Anonymous::Change(uri).c_str()); enableSilentUris_.Compute(callerTokenId, [&enable, &uri](const uint32_t &key, std::map &uris) { uris[uri] = enable; @@ -90,8 +88,6 @@ int DataShareSilentConfig::CheckExistEnableSilentUris(uint32_t callerTokenId, } return !uris.empty(); }); - ZLOGI("Check exist enable silent uris, callerTokenId:%{public}u, status:%{public}d, uri:%{public}s", - callerTokenId, status, uri.c_str()); return status; } } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 1bfab8b2aacafe6edd612f8710b7d22edc7c0e49..6f17ca9ea600c812db69747c74ce7655a069e143 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -32,6 +32,7 @@ #include "log_print.h" #include "matrix_event.h" #include "metadata/appid_meta_data.h" +#include "metadata/capability_meta_data.h" #include "metadata/meta_data_manager.h" #include "permit_delegate.h" #include "query_helper.h" @@ -200,7 +201,33 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const S } } return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, - std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), + 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::SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +{ + if (syncInfo.devices.empty()) { + return Status::INVALID_ARGUMENT; + } + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); + auto uuid = DMAdapter::GetInstance().ToUUID(syncInfo.devices[0]); + if (uuid.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; + } + auto code = DeviceMatrix::GetInstance().GetCode(metaData); + auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid); + if (code != 0 && exist && ((mask & code) != code)) { + ZLOGD("no change, do not need sync, appId:%{public}s storeId:%{public}s", + metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str()); + return SUCCESS; + } + 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)); } @@ -314,7 +341,7 @@ Status KVDBServiceImpl::AddSubscribeInfo(const AppId &appId, const StoreId &stor MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); auto delay = GetSyncDelayTime(syncInfo.delay, storeId); return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, - std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_SUBSCRIBE), + std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SUBSCRIBE), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); } @@ -324,7 +351,8 @@ Status KVDBServiceImpl::RmvSubscribeInfo(const AppId &appId, const StoreId &stor MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); auto delay = GetSyncDelayTime(syncInfo.delay, storeId); return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, - std::bind(&KVDBServiceImpl::DoSync, this, metaData, syncInfo, std::placeholders::_1, ACTION_UNSUBSCRIBE), + std::bind( + &KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_UNSUBSCRIBE), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); } @@ -383,7 +411,7 @@ Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, AddOptions(options, meta); StoreMetaData old; - auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old); + auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old, true); if (!isCreated) { return SUCCESS; } @@ -416,7 +444,7 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, AddOptions(options, metaData); StoreMetaData oldMeta; - auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta); + auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta, true); Status status = SUCCESS; if (isCreated && oldMeta != metaData) { auto dbStatus = Upgrade::GetInstance().UpdateStore(oldMeta, metaData, password); @@ -430,7 +458,9 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, } if (!isCreated || oldMeta != metaData) { - MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData); + if (!CheckerManager::GetInstance().IsDistrust(Converter::ConvertToStoreInfo(metaData))) { + MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData); + } MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true); } AppIDMetaData appIdMeta; @@ -439,7 +469,7 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true); SaveLocalMetaData(options, metaData); Upgrade::GetInstance().UpdatePassword(metaData, password); - ZLOGI("appId:%{public}s storeId:%{public}s instanceId:%{public}d type:%{public}d dir:%{public}s" + ZLOGI("appId:%{public}s storeId:%{public}s instanceId:%{public}d type:%{public}d dir:%{public}s " "isCreated:%{public}d", appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId, metaData.storeType, metaData.dataDir.c_str(), isCreated); return status; @@ -636,6 +666,74 @@ Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, return Status::ERROR; } + return DoSyncBegin(uuids, meta, info, complete, type); +} + +Status KVDBServiceImpl::DoSyncInOrder( + const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type) +{ + ZLOGD("type:%{public}d seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", type, + info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); + auto uuids = ConvertDevices(info.devices); + 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; + } + bool isOnline = false; + bool isAfterMeta = false; + for (const auto &uuid : uuids) { + if (!DMAdapter::GetInstance().IsDeviceReady(uuid)) { + isOnline = true; + break; + } + auto metaData = meta; + metaData.deviceId = uuid; + auto matrixMeta = DeviceMatrix::GetInstance().GetMatrixMeta(uuid); + if (matrixMeta.version == MatrixMetaData::DEFAULT_VERSION + || !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) { + isAfterMeta = true; + } + } + if (!isOnline && isAfterMeta) { + auto result = MetaDataManager::GetInstance().Sync( + uuids, [this, meta, info, complete, type](const auto &results) { + auto ret = ProcessResult(results); + if (ret.first.empty()) { + DoComplete(meta, info, RefCount(), ret.second); + return; + } + auto status = DoSyncBegin(ret.first, meta, info, complete, type); + ZLOGD("data sync status:%{public}d appId:%{public}s, storeId:%{public}s", + static_cast(status), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); + }); + return result ? Status::SUCCESS : Status::ERROR; + } + return DoSyncBegin(uuids, meta, info, complete, type); +} + +KVDBServiceImpl::SyncResult KVDBServiceImpl::ProcessResult(const std::map &results) +{ + std::map dbResults; + std::vector devices; + for (const auto &[uuid, status] : results) { + dbResults.insert_or_assign(uuid, static_cast(status)); + if (static_cast(status) != DBStatus::OK) { + continue; + } + DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK); + devices.emplace_back(uuid); + } + ZLOGD("meta sync finish, total size:%{public}zu, success size:%{public}zu", dbResults.size(), devices.size()); + return { devices, dbResults }; +} + +Status KVDBServiceImpl::DoSyncBegin(const std::vector &devices, const StoreMetaData &meta, + const SyncInfo &info, const SyncEnd &complete, int32_t type) +{ + if (devices.empty()) { + return Status::INVALID_ARGUMENT; + } DistributedDB::DBStatus status; auto observers = GetObservers(meta.tokenId, meta.storeId); auto store = storeCache_.GetStore(meta, observers, status); @@ -653,13 +751,19 @@ Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, switch (type) { case ACTION_SYNC: - status = store->Sync(uuids, ConvertDBMode(SyncMode(info.mode)), complete, dbQuery, false); - break; + { + if (info.query.empty()) { + status = store->Sync(devices, ConvertDBMode(SyncMode(info.mode)), complete, false); + } else { + status = store->Sync(devices, ConvertDBMode(SyncMode(info.mode)), complete, dbQuery, false); + } + break; + } case ACTION_SUBSCRIBE: - status = store->SubscribeRemoteQuery(uuids, complete, dbQuery, false); + status = store->SubscribeRemoteQuery(devices, complete, dbQuery, false); break; case ACTION_UNSUBSCRIBE: - status = store->UnSubscribeRemoteQuery(uuids, complete, dbQuery, false); + status = store->UnSubscribeRemoteQuery(devices, complete, dbQuery, false); break; default: status = DBStatus::INVALID_ARGS; diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index d6f5b945efa8ad9e8ef42182491d3edfc3893d88..4cdac4574f25934658a2cc823435a2855749d824 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -42,6 +42,7 @@ public: const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId) override; Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback(const AppId &appId, sptr callback) override; Status UnregisterSyncCallback(const AppId &appId) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; @@ -97,12 +98,17 @@ private: StrategyMeta GetStrategyMeta(const AppId &appId, const StoreId &storeId); int32_t GetInstIndex(uint32_t tokenId, const AppId &appId); Status DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); + Status DoSyncInOrder(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); + Status DoSyncBegin(const std::vector &devices, const StoreMetaData &meta, + const SyncInfo &info, const SyncEnd &complete, int32_t type); 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; DBMode ConvertDBMode(SyncMode syncMode) const; std::vector ConvertDevices(const std::vector &deviceIds) const; std::shared_ptr GetObservers(uint32_t tokenId, const std::string &storeId); + using SyncResult = std::pair, std::map>; + SyncResult ProcessResult(const std::map &results); void SaveLocalMetaData(const Options &options, const StoreMetaData &metaData); void RegisterKvServiceInfo(); void RegisterHandler(); diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 1da51ce462fb7232c9cd535dba3ad376547de188..729e52b3d385aa69fbf5ad6ff0fdfc4e12885cd6 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -42,6 +42,7 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSubscribe, &KVDBServiceStub::OnUnsubscribe, &KVDBServiceStub::OnGetBackupPassword, + &KVDBServiceStub::OnSyncExt, }; int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) @@ -168,6 +169,25 @@ int32_t KVDBServiceStub::OnSync(const AppId &appId, const StoreId &storeId, Mess 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::OnRegisterCallback( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index 00b1763def44b6c8f646ad4139525b3046e34129..183fdbe187b9114400e2c0414eb96f4516ce6363 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -44,6 +44,7 @@ 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); static const Handler HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)]; }; } // namespace OHOS::DistributedKv diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/query_helper.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/query_helper.cpp index 822b25d67cbe70d79877dec1b4e8186794abc2b6..59739ccbd32e3d4e52a5a4b4f84a4488a1378d39 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/query_helper.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/query_helper.cpp @@ -34,7 +34,7 @@ DistributedDB::Query QueryHelper::StringToDbQuery(const std::string &query, bool ZLOGI("query string length:%{public}zu", query.length()); DBQuery dbQuery = DBQuery::Select(); if (query.empty()) { - ZLOGI("Query string is empty."); + ZLOGD("Query string is empty."); isSuccess = true; return dbQuery; } diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp index 1d245bf96de5112df8ee5f4515f4cc04b4fdfa0b..2c6a5c95e8cf512004867279e57d10c2cd94f5e2 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -15,7 +15,8 @@ #define LOG_TAG "UserDelegate" #include "user_delegate.h" - +#include +#include #include #include "communicator/device_manager_adapter.h" #include "log_print.h" @@ -24,6 +25,7 @@ namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; +using namespace std::chrono; std::string GetLocalDeviceId() { return DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -89,8 +91,10 @@ std::vector UserDelegate::GetUsers(const std::string &deviceId) } return !users.empty(); }); - ZLOGI("device:%{public}s, users:%{public}s", Anonymous::Change(deviceId).c_str(), - Serializable::Marshall(userStatus).c_str()); + auto time = + static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + ZLOGI("device:%{public}s, users:%{public}s times %{public}" PRIu64 ".", Anonymous::Change(deviceId).c_str(), + Serializable::Marshall(userStatus).c_str(), time); return userStatus; } diff --git a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h index f7f25b28ff48d08d77ab6193ca373084ef5ee899..527f0c57887eb76517547300d4cf61f4fd3829d2 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -44,10 +44,12 @@ public: bool IsChangedInTerm(const StoreMetaData &metaData, uint64_t term); uint16_t GetCode(const StoreMetaData &metaData); std::pair GetMask(const std::string &device); + std::pair GetRemoteMask(const std::string &device); + MatrixMetaData GetMatrixMeta(const std::string &device); void Clear(); private: - static constexpr uint32_t CURRENT_VERSION = 1; + static constexpr uint32_t CURRENT_VERSION = 2; static constexpr uint32_t CURRENT_MASK = 0x000E; static constexpr size_t MAX_DEVICES = 16; @@ -63,7 +65,6 @@ private: } uint16_t ConvertMask(const std::string &device, uint16_t code); - MatrixMetaData GetMatrixMeta(const std::string &device); struct Mask { uint16_t bitset = META_STORE_MASK | CURRENT_MASK; diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp index e406e6eee21d107782cfc29aae5f95e594af8163..c1b20abb26db8fc8a007b6f5f8768d8b422b371a 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -200,6 +200,16 @@ std::pair DeviceMatrix::GetMask(const std::string &device) return { false, 0 }; } +std::pair DeviceMatrix::GetRemoteMask(const std::string &device) +{ + std::lock_guard lockGuard(mutex_); + auto it = remotes_.find(device); + if (it != remotes_.end()) { + return { true, it->second.bitset }; + } + return { false, 0 }; +} + void DeviceMatrix::Clear() { versions_.ResetCapacity(0); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp index 8abeb3054d2071205ac430ae731278c2ab804c92..e72c81db9082481f975e5fd92714122ac548d69b 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp @@ -29,13 +29,18 @@ ObjectAssetLoader *ObjectAssetLoader::GetInstance() return loader; } +void ObjectAssetLoader::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} + bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string &bundleName, const std::string &deviceId, const DistributedData::Asset &assetValue) { AssetInfo assetInfo; assetInfo.uri = assetValue.uri; assetInfo.assetName = assetValue.name; - ZLOGD("Start transfer, bundleName: %{public}s, deviceId: %{public}s, assetName: %{public}s", bundleName.c_str(), + ZLOGI("Start transfer, bundleName: %{public}s, deviceId: %{public}s, assetName: %{public}s", bundleName.c_str(), DistributedData::Anonymous::Change(deviceId).c_str(), assetInfo.assetName.c_str()); auto block = std::make_shared>>(WAIT_TIME, std::tuple{ true, OBJECT_SUCCESS }); auto res = CloudSyncAssetManager::GetInstance().DownloadFile(userId, bundleName, deviceId, assetInfo, @@ -56,26 +61,22 @@ bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string &bundle return true; } -bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string& bundleName, const std::string& deviceId, - const DistributedData::Asset& assetValue, std::function callback) +void ObjectAssetLoader::TransferAssetsAsync(const int32_t userId, const std::string& bundleName, + const std::string& deviceId, const std::vector& assets, + const std::function& callback) { - AssetInfo assetInfo; - assetInfo.uri = assetValue.uri; - assetInfo.assetName = assetValue.name; - auto res = CloudSyncAssetManager::GetInstance().DownloadFile(userId, bundleName, deviceId, assetInfo, - [callback](const std::string& uri, int32_t status) { - if (status != OBJECT_SUCCESS) { - ZLOGE("fail, uri: %{public}s, status: %{public}d", DistributedData::Anonymous::Change(uri).c_str(), - status); - return callback(false); - } - return callback(true); - }); - if (res != OBJECT_SUCCESS) { - ZLOGE("fail, res: %{public}d, name: %{public}s, deviceId: %{public}s, bundleName: %{public}s", res, - assetValue.name.c_str(), DistributedData::Anonymous::Change(deviceId).c_str(), bundleName.c_str()); - return false; + 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); + callback(false); + return; } - return true; + executors_->Execute([this, userId, bundleName, deviceId, assets, callback]() { + bool result = true; + for (const auto& asset : assets) { + result &= Transfer(userId, bundleName, deviceId, asset); + } + callback(result); + }); } } // namespace OHOS::DistributedObject \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h index af4a7b5e7e8b244361c1f2af507a2216c343a631..2d8b300f19b6a6549e4ee482371fa1872c67907b 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h @@ -16,6 +16,7 @@ #define DISTRIBUTEDDATAMGR_OBJECT_ASSET_LOADER_H #include +#include "executor_pool.h" #include "object_types.h" #include "store/general_value.h" @@ -24,11 +25,11 @@ namespace DistributedObject { class ObjectAssetLoader { public: static ObjectAssetLoader *GetInstance(); + void SetThreadPool(std::shared_ptr executors); bool Transfer(const int32_t userId, const std::string &bundleName, const std::string &deviceId, const DistributedData::Asset &assetValue); - - bool Transfer(const int32_t userId, const std::string& bundleName, const std::string& deviceId, - const DistributedData::Asset& assetValue, std::function callback); + void TransferAssetsAsync(const int32_t userId, const std::string& bundleName, const std::string& deviceId, + const std::vector& assets, const std::function& callback); private: ObjectAssetLoader() = default; ~ObjectAssetLoader() = default; @@ -36,6 +37,7 @@ private: ObjectAssetLoader &operator=(const ObjectAssetLoader &) = delete; static constexpr int WAIT_TIME = 60; + std::shared_ptr executors_; }; } // namespace DistributedObject } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp index 5135c5d1e73d665a9e0f9e65810d230b8a85b7f0..020382805d7bf126789d9b7d95ee89f4a871e90c 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp @@ -37,22 +37,22 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; constexpr static const char* SQL_AND = " = ? and "; constexpr static const int32_t AND_SIZE = 5; static int32_t DoTransfer(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t ChangeAssetToNormal(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t CompensateSync(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t CompensateTransferring(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t SaveNewAsset(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t Recover(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset); + const std::pair& newAsset); static int32_t UpdateStore(ChangedAssetInfo& changedAsset); @@ -158,12 +158,13 @@ int32_t ObjectAssetMachine::DFAPostEvent(AssetEvent eventId, ChangedAssetInfo& c } static int32_t DoTransfer(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { changedAsset.deviceId = newAsset.first; changedAsset.asset = newAsset.second; - bool success = ObjectAssetLoader::GetInstance()->Transfer(changedAsset.storeInfo.user, - changedAsset.storeInfo.bundleName, changedAsset.deviceId, changedAsset.asset, [&changedAsset](bool success) { + std::vector assets{ changedAsset.asset }; + ObjectAssetLoader::GetInstance()->TransferAssetsAsync(changedAsset.storeInfo.user, + changedAsset.storeInfo.bundleName, changedAsset.deviceId, assets, [&changedAsset](bool success) { if (success) { auto status = UpdateStore(changedAsset); if (status != E_OK) { @@ -176,9 +177,6 @@ static int32_t DoTransfer(int32_t eventId, ChangedAssetInfo& changedAsset, Asset } ObjectAssetMachine::DFAPostEvent(TRANSFER_FINISHED, changedAsset, changedAsset.asset); }); - if (!success) { - ObjectAssetMachine::DFAPostEvent(TRANSFER_FINISHED, changedAsset, changedAsset.asset); - } return E_OK; } @@ -304,14 +302,14 @@ static AutoCache::Store GetStore(ChangedAssetInfo& changedAsset) } static int32_t CompensateTransferring(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { std::pair newChangedAsset{ changedAsset.deviceId, changedAsset.asset }; return ObjectAssetMachine::DFAPostEvent(REMOTE_CHANGED, changedAsset, changedAsset.asset, newChangedAsset); } static int32_t CompensateSync(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { BindEvent::BindEventInfo bindEventInfo = MakeBindInfo(changedAsset); auto evt = std::make_unique(BindEvent::COMPENSATE_SYNC, std::move(bindEventInfo)); @@ -320,7 +318,7 @@ static int32_t CompensateSync(int32_t eventId, ChangedAssetInfo& changedAsset, A } static int32_t SaveNewAsset(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { changedAsset.deviceId = newAsset.first; changedAsset.asset = newAsset.second; @@ -328,14 +326,14 @@ static int32_t SaveNewAsset(int32_t eventId, ChangedAssetInfo& changedAsset, Ass } static int32_t ChangeAssetToNormal(int32_t eventId, ChangedAssetInfo& changedAssetInfo, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { asset.status = Asset::STATUS_NORMAL; return E_OK; } static int32_t Recover(int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, - std::pair& newAsset) + const std::pair& newAsset) { ZLOGE("An abnormal event has occurred, eventId:%{public}d, status:%{public}d, assetName:%{public}s", eventId, changedAsset.status, changedAsset.asset.name.c_str()); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.h b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.h index 32b8a8a273ea2aaf1325a7a692157c1d0693ef17..fef1ccee2c86913058c35ec2c4339f7f7ee999cc 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.h @@ -39,7 +39,7 @@ struct ChangedAssetInfo { }; typedef int32_t (*Action) - (AssetEvent eventId, ChangedAssetInfo& changedAsset, Asset& asset, std::pair newAsset); + (int32_t eventId, ChangedAssetInfo& changedAsset, Asset& asset, const std::pair& newAsset); struct DFAAction { int32_t next; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp index fcad1fbdf6128929f36ce9b22392e0691b787493..fedce9676a2a1e146de271da81a24c8080813130 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "ObjectStoreManager" +#include #include "object_manager.h" @@ -187,7 +188,7 @@ int32_t ObjectStoreManager::Retrieve( return STORE_NOT_OPEN; } - std::map> results; + std::map> results{}; int32_t status = RetrieveFromStore(bundleName, sessionId, results); if (status != OBJECT_SUCCESS) { ZLOGE("Retrieve failed, status = %{public}d", status); @@ -195,8 +196,6 @@ int32_t ObjectStoreManager::Retrieve( proxy->Completed(std::map>()); return status; } - const int32_t userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); - TransferAssets(results, userId, bundleName); // delete local data status = RevokeSaveToStore(GetPrefixWithoutDeviceId(bundleName, sessionId)); if (status != OBJECT_SUCCESS) { @@ -206,42 +205,19 @@ int32_t ObjectStoreManager::Retrieve( return status; } Close(); - proxy->Completed(results); - return status; -} - -void ObjectStoreManager::TransferAssets( - std::map>& results, int32_t userId, const std::string& bundleName) -{ - std::map assets; - std::string deviceId; - - for (auto const&[key, value] : results) { - if (key.find(ObjectStore::ASSET_DOT) == std::string::npos) { - if (key == (ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY)) { - ObjectStore::StringUtils::BytesToStrWithType(value, deviceId); - } - } else { - std::string assetKey = key.substr(0, key.find(ObjectStore::ASSET_DOT)); - auto it = assets.find(assetKey); - if (it == assets.end()) { - Asset asset; - ObjectStore::StringUtils::BytesToStrWithType(results[assetKey+ObjectStore::NAME_SUFFIX], asset.name); - asset.name = asset.name.substr(ObjectStore::STRING_PREFIX_LEN); - ObjectStore::StringUtils::BytesToStrWithType(results[assetKey+ObjectStore::URI_SUFFIX], asset.uri); - asset.uri = asset.uri.substr(ObjectStore::STRING_PREFIX_LEN); - assets[assetKey] = asset; - } - } - } - if (!assets.empty()) { - for (auto&[key, asset] : assets) { - if (!ObjectAssetLoader::GetInstance()->Transfer(userId, bundleName, deviceId, asset)) { - ZLOGE("Transfer fail, userId: %{public}d, bundleName: %{public}s, networkId: %{public}s, asset name : " - "%{public}s", userId, bundleName.c_str(), deviceId.c_str(), asset.name.c_str()); - } - } + Assets assets = GetAssetsFromDBRecords(results); + if (assets.empty() || results.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY) == results.end()) { + proxy->Completed(results); + return status; } + int32_t userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + std::string deviceId; + ObjectStore::StringUtils::BytesToStrWithType( + results.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY)->second, deviceId); + ObjectAssetLoader::GetInstance()->TransferAssetsAsync(userId, bundleName, deviceId, assets, [=](bool success) { + proxy->Completed(results); + }); + return status; } int32_t ObjectStoreManager::Clear() @@ -354,33 +330,131 @@ void ObjectStoreManager::NotifyChange(std::map ZLOGD("ObjectStoreManager::NotifyChange start"); SaveUserToMeta(); std::map>> data; - std::map>> transferData; for (const auto &item : changedData) { std::string prefix = GetBundleName(item.first) + GetSessionId(item.first); std::string propertyName = GetPropertyName(item.first); data[prefix].insert_or_assign(propertyName, item.second); - - std::string bundleName = GetBundleName(item.first); - transferData[bundleName].insert_or_assign(std::move(propertyName), std::move(item.second)); } - + std::function callback = [this, data](bool success) { + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data); + return false; + }); + }; + std::map> changedAssets = GetAssetsFromStore(changedData); + if (changedAssets.empty()) { + callback(true); + } const int32_t userId = std::stoi(GetCurrentUser()); - for (auto item : transferData) { - std::string bundleName = item.first; - auto results = item.second; - TransferAssets(results, userId, bundleName); + for (const auto& assetsOfBundle : changedAssets) { + std::string bundleName = assetsOfBundle.first; + for (const auto& assetsOfDevice : assetsOfBundle.second) { + std::string deviceId = assetsOfDevice.first; + Assets assets = assetsOfDevice.second; + ObjectAssetLoader::GetInstance()->TransferAssetsAsync(userId, bundleName, deviceId, assets, callback); + } } +} - callbacks_.ForEach([&data](uint32_t tokenId, CallbackInfo &value) { - for (const auto &observer : value.observers_) { - auto it = data.find(observer.first); - if (it == data.end()) { - continue; - } - observer.second->Completed((*it).second); +std::map> ObjectStoreManager::GetAssetsFromStore( + const std::map>& changedData) +{ + std::set assetKeyPrefix; + for (const auto& item : changedData) { + if (isAssetKey(GetPropertyName(item.first))) { + assetKeyPrefix.insert(item.first.substr(0, item.first.find_last_of(ObjectStore::ASSET_DOT))); + } + } + std::map>>> results; + for (const auto& keyPrefix : assetKeyPrefix) { + std::vector entries; + auto status = delegate_->GetEntries(std::vector(keyPrefix.begin(), keyPrefix.end()), entries); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("GetEntries fail. keyPrefix = %{public}s", keyPrefix.c_str()); + continue; } + std::map> result{}; + std::for_each(entries.begin(), entries.end(), [&result, this](const DistributedDB::Entry entry) { + std::string key(entry.key.begin(), entry.key.end()); + result[GetPropertyName(key)] = entry.value; + }); + if (!isAssetComplete(result, GetPropertyName(keyPrefix))) { + continue; + } + std::string networkId = GetNetworkId(keyPrefix); + for (const auto& [key, value] : result) { + results[GetBundleName(keyPrefix)][networkId][key] = value; + } + } + std::map> changedAssets{}; + for (const auto& resultOfBundle : results) { + std::string bundleName = resultOfBundle.first; + for (const auto& resultOfDevice : resultOfBundle.second) { + std::string deviceId = resultOfDevice.first; + Assets assets = GetAssetsFromDBRecords(resultOfDevice.second); + changedAssets[bundleName][deviceId] = assets; + } + } + return changedAssets; +} + +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) +{ + if (result.find(assetPrefix + ObjectStore::NAME_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::URI_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::PATH_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::CREATE_TIME_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::SIZE_SUFFIX) == result.end()) { return false; - }); + } + return true; +} + +Assets ObjectStoreManager::GetAssetsFromDBRecords(const std::map>& result) +{ + Assets assets{}; + std::set assetKey; + for (const auto& [key, value] : result) { + std::string assetPrefix = key.substr(0, key.find(ObjectStore::ASSET_DOT)); + if (!isAssetKey(key) || assetKey.find(assetPrefix) != assetKey.end() || + result.find(assetPrefix + ObjectStore::NAME_SUFFIX) == result.end() || + result.find(assetPrefix + ObjectStore::URI_SUFFIX) == result.end()) { + continue; + } + Asset asset; + ObjectStore::StringUtils::BytesToStrWithType( + result.find(assetPrefix + ObjectStore::NAME_SUFFIX)->second, asset.name); + if (asset.name.find(ObjectStore::STRING_PREFIX) != std::string::npos) { + asset.name = asset.name.substr(ObjectStore::STRING_PREFIX_LEN); + } + ObjectStore::StringUtils::BytesToStrWithType( + result.find(assetPrefix + ObjectStore::URI_SUFFIX)->second, asset.uri); + if (asset.uri.find(ObjectStore::STRING_PREFIX) != std::string::npos) { + asset.uri = asset.uri.substr(ObjectStore::STRING_PREFIX_LEN); + } + assets.push_back(asset); + assetKey.insert(assetPrefix); + } + return assets; +} + +void ObjectStoreManager::DoNotify(uint32_t tokenId, const CallbackInfo& value, + const std::map>>& data) +{ + for (const auto& observer : value.observers_) { + auto it = data.find(observer.first); + if (it == data.end()) { + continue; + } + observer.second->Completed((*it).second); + } } void ObjectStoreManager::SetData(const std::string &dataDir, const std::string &userId) @@ -703,6 +777,18 @@ std::string ObjectStoreManager::GetBundleName(const std::string &key) return result; } +std::string ObjectStoreManager::GetNetworkId(const std::string& key) +{ + std::stringstream keyStream(key); + std::string sourceDeviceUdId; + for (int i = 0; getline(keyStream, sourceDeviceUdId, *SEPERATOR); i++) { + if (i == SOURCE_DEVICE_ID_INDEX) { + return DmAdaper::GetInstance().ToNetworkID(sourceDeviceUdId); + } + } + return {}; +} + void ObjectStoreManager::SetThreadPool(std::shared_ptr executors) { executors_ = executors; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.h b/datamgr_service/services/distributeddataservice/service/object/object_manager.h index c3f15def3144c206a7521fc0b6c0678d6184539f..31ff24fc8b91f896b68fd6c146e9fe9bec2806cf 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.h @@ -101,6 +101,7 @@ private: constexpr static const char *USERID = "USERID"; constexpr static int8_t MAX_OBJECT_SIZE_PER_APP = 16; constexpr static int8_t DECIMAL_BASE = 10; + constexpr static int8_t SOURCE_DEVICE_ID_INDEX = 2; struct CallbackInfo { pid_t pid; std::map> observers_; @@ -127,14 +128,21 @@ private: std::string GetPropertyName(const std::string &key); std::string GetSessionId(const std::string &key); std::string GetBundleName(const std::string &key); + std::string GetNetworkId(const std::string& key); int64_t GetTime(const std::string &key); void ProcessOldEntry(const std::string &appId); void ProcessSyncCallback(const std::map &results, const std::string &appId, const std::string &sessionId, const std::string &deviceId); void SaveUserToMeta(); std::string GetCurrentUser(); - void TransferAssets( - std::map>& results, int32_t userId, const std::string& bundleName); + void DoNotify(uint32_t tokenId, const CallbackInfo& value, + const std::map>>& data); + std::map> GetAssetsFromStore( + const std::map>& 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); 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/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index 3cafdc81578c4c80ccb237366ca7e6c094c83c14..1994053d7a6b65acf01cb75ada940bf2a9e2eb39 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -30,6 +30,7 @@ #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" +#include "object_asset_loader.h" #include "permission/permission_validator.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" @@ -386,6 +387,7 @@ int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo) { executors_ = bindInfo.executors; ObjectStoreManager::GetInstance()->SetThreadPool(executors_); + ObjectAssetLoader::GetInstance()->SetThreadPool(executors_); return 0; } } // namespace OHOS::DistributedObject diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index ef6b2edadae7f14caa8edb1cfffb253933baa0cc..da1bfa6de5b28162366a650efdd59a5aeca798b2 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -13,7 +13,11 @@ * limitations under the License. */ #define LOG_TAG "RdbGeneralStore" + #include "rdb_general_store.h" + +#include +#include #include "cache_cursor.h" #include "cloud/asset_loader.h" #include "cloud/cloud_db.h" @@ -39,6 +43,7 @@ using namespace DistributedData; using namespace DistributedDB; using namespace NativeRdb; using namespace CloudData; +using namespace std::chrono; using DBField = DistributedDB::Field; using DBTable = DistributedDB::TableSchema; using DBSchema = DistributedDB::DataBaseSchema; @@ -46,6 +51,10 @@ using ClearMode = DistributedDB::ClearMode; using DBStatus = DistributedDB::DBStatus; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +constexpr const char *INSERT = "INSERT INTO "; +constexpr const char *REPLACE = "REPLACE INTO "; +constexpr const char *VALUES = " VALUES "; + RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) { observer_.storeId_ = meta.storeId; @@ -194,11 +203,13 @@ int32_t RdbGeneralStore::Execute(const std::string &table, const std::string &sq { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed!"); + ZLOGE("Database already closed! database:%{public}s, table:%{public}s, sql:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(table).c_str(), + Anonymous::Change(sql).c_str()); return GeneralError::E_ERROR; } std::vector changedData; - auto status = delegate_->ExecuteSql({ sql, {} }, changedData); + auto status = delegate_->ExecuteSql({ sql, {}, false }, changedData); if (status != DBStatus::OK) { ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu", status, Anonymous::Change(sql).c_str(), changedData.size()); @@ -227,12 +238,8 @@ size_t RdbGeneralStore::SqlConcatenate(VBucket &value, std::string &strColumnSql int32_t RdbGeneralStore::Insert(const std::string &table, VBuckets &&values) { - if (table.empty()) { - ZLOGE("Insert: table can't be empty!"); - return GeneralError::E_INVALID_ARGS; - } - if (values.size() == 0) { - ZLOGE("Insert: values size error, can't be 0!"); + if (table.empty() || values.size() == 0) { + ZLOGE("Insert:table maybe empty:%{public}d,value size is:%{public}d", table.empty(), values.size()); return GeneralError::E_INVALID_ARGS; } @@ -258,24 +265,44 @@ int32_t RdbGeneralStore::Insert(const std::string &table, VBuckets &&values) strValueSql += strRowValueSql + ","; } strValueSql.pop_back(); - std::string sql = "INSERT INTO " + table + strColumnSql + " VALUES " + strValueSql; + std::string sql = INSERT + table + strColumnSql + VALUES + strValueSql; std::vector changedData; std::vector bindArgs = ValueProxy::Convert(std::move(args)); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed!"); + ZLOGE("Database already closed! database:%{public}s, table:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(table).c_str()); return GeneralError::E_ERROR; } - auto status = delegate_->ExecuteSql({ sql, std::move(bindArgs) }, changedData); + auto status = delegate_->ExecuteSql({ sql, std::move(bindArgs), false }, changedData); if (status != DBStatus::OK) { - ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu", status, Anonymous::Change(sql).c_str(), - changedData.size()); + if (IsPrintLog(status)) { + auto time = + static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu times %{public}" PRIu64 ".", + status, Anonymous::Change(sql).c_str(), changedData.size(), time); + } return GeneralError::E_ERROR; } return GeneralError::E_OK; } +bool RdbGeneralStore::IsPrintLog(DBStatus status) +{ + bool isPrint = false; + if (status == lastError_) { + if (++lastErrCnt_ % PRINT_ERROR_CNT == 0) { + isPrint = true; + } + } else { + isPrint = true; + lastErrCnt_ = 0; + lastError_ = status; + } + return isPrint; +} + /** * This function does not support batch updates in rdb, it only supports single data updates. */ @@ -308,10 +335,11 @@ int32_t RdbGeneralStore::Update(const std::string &table, const std::string &set std::vector bindArgs = ValueProxy::Convert(std::move(args)); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed!"); + ZLOGE("Database already closed! database:%{public}s, table:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(table).c_str()); return GeneralError::E_ERROR; } - auto status = delegate_->ExecuteSql({ sqlIn, std::move(bindArgs) }, changedData); + auto status = delegate_->ExecuteSql({ sqlIn, std::move(bindArgs), false }, changedData); if (status != DBStatus::OK) { ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu", status, Anonymous::Change(sqlIn).c_str(), changedData.size()); @@ -320,6 +348,37 @@ int32_t RdbGeneralStore::Update(const std::string &table, const std::string &set return GeneralError::E_OK; } +int32_t RdbGeneralStore::Replace(const std::string &table, VBucket &&value) +{ + if (table.empty() || value.size() == 0) { + return GeneralError::E_INVALID_ARGS; + } + std::string columnSql; + std::string valueSql; + SqlConcatenate(value, columnSql, valueSql); + std::string sql = REPLACE + table + columnSql + VALUES + valueSql; + + Values args; + for (auto &[k, v] : value) { + args.emplace_back(std::move(v)); + } + std::vector changedData; + std::vector bindArgs = ValueProxy::Convert(std::move(args)); + 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(table).c_str()); + return GeneralError::E_ERROR; + } + auto status = delegate_->ExecuteSql({ sql, std::move(bindArgs) }, changedData); + if (status != DBStatus::OK) { + ZLOGE("Replace failed! ret:%{public}d, table:%{public}s, sql:%{public}s, fields:%{public}s", + status, Anonymous::Change(table).c_str(), Anonymous::Change(sql).c_str(), columnSql.c_str()); + return GeneralError::E_ERROR; + } + return GeneralError::E_OK; +} + int32_t RdbGeneralStore::Delete(const std::string &table, const std::string &sql, Values &&args) { return 0; @@ -330,10 +389,10 @@ std::shared_ptr RdbGeneralStore::Query(__attribute__((unused))const std: { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed!"); + ZLOGE("Database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); return nullptr; } - std::vector records = ExecuteSql(sql, std::move(args)); + std::vector records = QuerySql(sql, std::move(args)); return std::make_shared(std::move(records)); } @@ -347,7 +406,8 @@ std::shared_ptr RdbGeneralStore::Query(const std::string &table, GenQuer } std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed! tables name:%{public}s", Anonymous::Change(table).c_str()); + ZLOGE("Database already closed! database:%{public}s, table:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(table).c_str()); return nullptr; } if (rdbQuery->IsRemoteQuery()) { @@ -364,7 +424,8 @@ int32_t RdbGeneralStore::MergeMigratedData(const std::string& tableName, VBucket { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed! tables name:%{public}s", Anonymous::Change(tableName).c_str()); + 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; } @@ -421,10 +482,10 @@ std::shared_ptr RdbGeneralStore::PreSharing(GenQuery& query) { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed!"); + ZLOGE("Database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); return nullptr; } - values = ExecuteSql(sql, rdbQuery->GetBindArgs()); + values = QuerySql(sql, rdbQuery->GetBindArgs()); } if (rdbCloud_ == nullptr || values.empty()) { ZLOGW("rdbCloud is %{public}s, values size:%{public}zu", rdbCloud_ == nullptr ? "nullptr" : "not nullptr", @@ -628,7 +689,8 @@ int32_t RdbGeneralStore::SetDistributedTables(const std::vector &ta { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed! tables size:%{public}zu, type:%{public}d", tables.size(), type); + ZLOGE("Database already closed! database:%{public}s, tables size:%{public}zu, type:%{public}d", + Anonymous::Change(storeInfo_.storeName).c_str(), tables.size(), type); return GeneralError::E_ALREADY_CLOSED; } for (const auto &table : tables) { @@ -657,7 +719,8 @@ int32_t RdbGeneralStore::SetTrackerTable(const std::string& tableName, const std { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { - ZLOGE("database already closed! tables name:%{public}s", tableName.c_str()); + ZLOGE("database already closed! database:%{public}s, tables name:%{public}s", + Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(tableName).c_str()); return GeneralError::E_ALREADY_CLOSED; } auto status = delegate_->SetTrackerTable({ tableName, extendColName, trackerColNames }); @@ -719,11 +782,11 @@ int32_t RdbGeneralStore::UnregisterDetailProgressObserver() return GenErr::E_OK; } -VBuckets RdbGeneralStore::ExecuteSql(const std::string& sql, Values &&args) +VBuckets RdbGeneralStore::QuerySql(const std::string& sql, Values &&args) { std::vector changedData; std::vector bindArgs = ValueProxy::Convert(std::move(args)); - auto status = delegate_->ExecuteSql({ sql, std::move(bindArgs) }, changedData); + auto status = delegate_->ExecuteSql({ sql, std::move(bindArgs), true }, changedData); if (status != DBStatus::OK) { ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu", status, Anonymous::Change(sql).c_str(), changedData.size()); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h index d3625562365fe8ca1c5b3b7cc57548fbb04019f4..d10754be4c23dea4dd31de11a8396238699dc2a1 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -58,6 +58,7 @@ public: 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; + int32_t Replace(const std::string &table, VBucket &&value) override; int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; std::shared_ptr Query(const std::string &table, GenQuery &query) override; @@ -113,10 +114,11 @@ private: const DistributedDB::RemoteCondition &remoteCondition); std::string BuildSql(const std::string& table, const std::string& statement, const std::vector& columns) const; - VBuckets ExecuteSql(const std::string& sql, Values &&args); + VBuckets QuerySql(const std::string& sql, Values &&args); VBuckets ExtractExtend(VBuckets& values) const; size_t SqlConcatenate(VBucket &value, std::string &strColumnSql, std::string &strRowValueSql); - + bool IsPrintLog(DistributedDB::DBStatus status); + ObserverProxy observer_; RdbManager manager_; RdbDelegate *delegate_ = nullptr; @@ -131,6 +133,10 @@ private: BindAssets snapshots_; DistributedData::StoreInfo storeInfo_; + + DistributedDB::DBStatus lastError_ = DistributedDB::DBStatus::OK; + static constexpr uint32_t PRINT_ERROR_CNT = 150; + uint32_t lastErrCnt_ = 0; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index 3dd9b0bcd1abcf1d1e558ceb663cfcd0f393d5a9..1ba52d4c739ff855d4a0015f981a06c24cc1f28e 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -269,16 +269,24 @@ int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const return RDB_ERROR; } auto meta = GetStoreMetaData(param); - StoreMetaData syncMeta; - StoreMetaData localMeta; - bool isCreatedSync = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), syncMeta); - bool isCreatedLocal = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), localMeta, true); - if (isCreatedLocal && (!isCreatedSync || localMeta != syncMeta)) { - ZLOGD("save sync meta. bundle:%{public}s store:%{public}s type:%{public}d->%{public}d " - "encrypt:%{public}d->%{public}d , area:%{public}d->%{public}d", - meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), syncMeta.storeType, meta.storeType, - syncMeta.isEncrypt, meta.isEncrypt, syncMeta.area, meta.area); - MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), localMeta); + + if (type == DistributedRdb::DistributedTableType::DISTRIBUTED_DEVICE) { + StoreMetaData localMeta; + bool isCreatedLocal = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), localMeta, true); + if (!isCreatedLocal) { + ZLOGE("no meta. bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + StoreMetaData syncMeta; + bool isCreatedSync = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), syncMeta); + if (!isCreatedSync || localMeta != syncMeta) { + ZLOGI("save sync meta. bundle:%{public}s store:%{public}s type:%{public}d->%{public}d " + "encrypt:%{public}d->%{public}d , area:%{public}d->%{public}d", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), syncMeta.storeType, meta.storeType, + syncMeta.isEncrypt, meta.isEncrypt, syncMeta.area, meta.area); + MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), localMeta); + } } auto store = GetStore(param); if (store == nullptr) { diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index 1cc7038dd484ba9b60946832fe5eff630390c02a..c1e32f9468af69a46bd2bd7d4087f2e26a888e41 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -72,6 +72,30 @@ ohos_unittest("CloudDataTest") { ] } +ohos_unittest("CloudTest") { + module_out_path = module_output_path + sources = [ "cloud_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${kv_store_distributeddb_path}:distributeddb", + "../../adapter:distributeddata_adapter", + "../../framework:distributeddatasvcfwk", + "../../service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ohos_unittest("ValueProxyTest") { module_out_path = module_output_path sources = [ @@ -361,6 +385,7 @@ group("unittest") { deps += [ ":CloudDataTest", + ":CloudTest", ":CryptoManagerTest", ":DeviceMatrixTest", ":DirectoryManagerTest", diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp index 1242139bb98c67e0309cd9fd8a7f64eabef5e1e1..6b8c965a22942e3e438f8edc4a28d028cae79972 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -135,7 +135,8 @@ void CloudDataTest::InitSchemaMeta() void CloudDataTest::SetUpTestCase(void) { - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, [](const auto &, auto) { + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); + MetaDataManager::GetInstance().SetSyncer([](const auto &, auto) { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); }); diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd87a48e51bd9eaa827898a0d3c6787d2db8edee --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp @@ -0,0 +1,160 @@ +/* +* 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 "CloudTest" +#include + +#include "account/account_delegate.h" +#include "cloud/cloud_server.h" +#include "cloud/sync_event.h" +#include "gtest/gtest.h" +#include "ipc_skeleton.h" +using namespace testing::ext; +using namespace OHOS::DistributedData; +namespace OHOS::Test { +class CloudTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; + +protected: + static constexpr const char* testCloudBundle = "test_cloud_bundleName"; + static constexpr const char* testCloudStore = "test_cloud_database_name"; +}; + +/** +* @tc.name: EventInfo +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudTest, EventInfo, TestSize.Level1) +{ + const int32_t mode = 1; + const int32_t wait = 10; + const bool retry = true; + std::shared_ptr query = nullptr; + int sign = 0; + auto async = [&sign](const GenDetails& details) { + ++sign; + }; + SyncEvent::EventInfo eventInfo1(mode, wait, retry, query, async); + SyncEvent::EventInfo eventInfo2(std::move(eventInfo1)); + SyncEvent::EventInfo eventInfo3 = std::move(eventInfo2); + CloudEvent::StoreInfo storeInfo{ IPCSkeleton::GetCallingTokenID(), testCloudBundle, testCloudStore, 0 }; + SyncEvent evt(storeInfo, eventInfo3); + EXPECT_EQ(evt.GetMode(), mode); + EXPECT_EQ(evt.GetWait(), wait); + EXPECT_EQ(evt.AutoRetry(), retry); + EXPECT_EQ(evt.GetQuery(), query); + evt.GetAsyncDetail()(GenDetails()); + EXPECT_NE(0, sign); +} + +/** +* @tc.name: Serializable_Marshal +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudTest, Serializable_Marshal, TestSize.Level1) +{ + SchemaMeta schemaMeta; + bool ret = schemaMeta.IsValid(); + EXPECT_EQ(false, ret); + + SchemaMeta::Database database; + database.name = testCloudStore; + database.alias = "database_alias_test"; + + schemaMeta.version = 1; + schemaMeta.bundleName = testCloudBundle; + schemaMeta.databases.emplace_back(database); + ret = schemaMeta.IsValid(); + EXPECT_EQ(true, ret); + + Serializable::json node = schemaMeta.Marshall(); + SchemaMeta schemaMeta2; + schemaMeta2.Unmarshal(node); + + EXPECT_EQ(schemaMeta.version, schemaMeta2.version); + EXPECT_EQ(schemaMeta.bundleName, schemaMeta2.bundleName); + Database database2 = schemaMeta2.GetDataBase(testCloudStore); + EXPECT_EQ(database.alias, database2.alias); +} + +/** +* @tc.name: Field_Marshal +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudTest, Field_Marshal, TestSize.Level1) +{ + Field field; + field.colName = "field_name1_test"; + field.alias = "field_alias1_test"; + field.type = 1; + field.primary = true; + field.nullable = false; + + Serializable::json node = field.Marshall(); + Field field2; + field2.Unmarshal(node); + + EXPECT_EQ(field.colName, field2.colName); + EXPECT_EQ(field.alias, field2.alias); + EXPECT_EQ(field.type, field2.type); + EXPECT_EQ(field.primary, field2.primary); + EXPECT_EQ(field.nullable, field2.nullable); +} + +/** +* @tc.name: Database_Marshal +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudTest, Database_Marshal, TestSize.Level1) +{ + SchemaMeta::Table table1; + table1.name = "test_cloud_table_name1"; + table1.alias = "test_cloud_table_alias1"; + SchemaMeta::Table table2; + table2.name = "test_cloud_table_name2"; + table2.alias = "test_cloud_table_alias2"; + + SchemaMeta::Database database1; + database1.name = testCloudStore; + database1.alias = "test_cloud_database_alias"; + database1.tables.emplace_back(table1); + database1.tables.emplace_back(table2); + + Serializable::json node = database1.Marshall(); + SchemaMeta::Database database2; + database2.Unmarshal(node); + + EXPECT_EQ(database1.name, database2.name); + EXPECT_EQ(database1.alias, database2.alias); + std::vector tableNames1 = database1.GetTableNames(); + std::vector tableNames2 = database2.GetTableNames(); + EXPECT_EQ(tableNames1.size(), tableNames2.size()); + for (uint32_t i = 0; i < tableNames1.size(); ++i) { + EXPECT_EQ(tableNames1[i], tableNames2[i]); + } +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp b/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp index c286e6e89648e79c4a809f9fb165e002cdc42e0f..d92ccf2e39ca03c9f16452df1a1b0e168e691b44 100644 --- a/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp @@ -81,8 +81,7 @@ HWTEST_F(ConfigFactoryTest, CheckerConfig, TestSize.Level0) { auto *checker = ConfigFactory::GetInstance().GetCheckerConfig(); ASSERT_NE(checker, nullptr); - std::vector checkers{"SystemChecker", "BundleChecker", "PackageChecker", - "ExternalChecker"}; + std::vector checkers{"SystemChecker", "BundleChecker"}; ASSERT_EQ(checker->checkers, checkers); ASSERT_EQ(checker->trusts[0].bundleName, "bundle_manager_service"); ASSERT_EQ(checker->trusts[0].appId, "bundle_manager_service"); @@ -110,4 +109,4 @@ HWTEST_F(ConfigFactoryTest, NetworkConfig, TestSize.Level0) ASSERT_EQ(networks->protocols[0].name, "OHOS softbus"); ASSERT_EQ(networks->protocols[0].address, "ohos.distributeddata"); ASSERT_EQ(networks->protocols[0].transport, "softbus"); -} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp index 39f99ca5958b7dd9cf476d6bb8b0da36ef48da69..ab03d50ce715464fad0d5c5ddb46ed0e891985c5 100644 --- a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp @@ -61,7 +61,8 @@ std::shared_ptr DeviceMatrixTest::dbStoreMock_ = std::make_shared DBStoreMock::GetWatermarkInfo(const std::string &device) +{ + WatermarkInfo mark; + return { DBStatus::OK, mark }; +} + DBStatus DBStoreMock::Reset() { return USER_CHANGED; diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h index 8d219c2b023132d64800379de9ca9ec4f6648b99..056b1639b53e20ba521cd07086f6e4ad43d18819 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h @@ -37,6 +37,7 @@ public: using RemotePushFinishedNotifier = DistributedDB::RemotePushFinishedNotifier; using PushDataInterceptor = DistributedDB::PushDataInterceptor; using UpdateKeyCallback = DistributedDB::UpdateKeyCallback; + using WatermarkInfo = DistributedDB::WatermarkInfo; DBStatus Get(const Key &key, Value &value) const override; DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const override; DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const override; @@ -89,8 +90,8 @@ public: DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const override; size_t GetSyncDataSize(const std::string &device) const override; DBStatus UpdateKey(const UpdateKeyCallback &callback) override; + std::pair GetWatermarkInfo(const std::string &device) override; DBStatus Reset(); - private: static const uint32_t DEFAULT_SIZE = 0; DBStatus Get(ConcurrentMap &store, const Key &key, Value &value) const; diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp index beba4a6bbcd8dd376aebab2e7691095e0e0af0df..bc4730b9832d4a1fbd3cede391d1203ab5be74fe 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp @@ -144,6 +144,10 @@ int32_t GeneralStoreMock::MergeMigratedData(const std::string& tableName, VBucke { return 0; } +int32_t GeneralStoreMock::Replace(const std::string& table, VBucket&& value) +{ + return 0; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h index 9d503c3682e41628267c511c9c0772597e64c0ba..67283d1c37ffb03f4dc10ca049a094f99327d823 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h @@ -57,6 +57,7 @@ public: int32_t Close() override; int32_t AddRef() override; int32_t Release() override; + int32_t Replace(const std::string &table, VBucket &&value) override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; diff --git a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp index 9348ad99b16f9b67b55a203e09245fd07cf2afaa..296fc94cecbe4e5f9782016e2bc4b326d934f9b1 100644 --- a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp @@ -19,8 +19,9 @@ #include -#include "log_print.h" #include "snapshot/machine_status.h" +#include "object_asset_loader.h" +#include "executor_pool.h" using namespace testing::ext; using namespace OHOS::DistributedObject; @@ -73,18 +74,20 @@ void ObjectAssetMachineTest::SetUp() storeInfo_ = storeInfo; ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); changedAssets_[uri_] = changedAssetInfo; + auto executors = std::make_shared(1, 0); + ObjectAssetLoader::GetInstance()->SetThreadPool(executors); } void ObjectAssetMachineTest::TearDown() {} /** -* @tc.name: StatusTransfer -* @tc.desc: . +* @tc.name: StatusTransfer001 +* @tc.desc: Transfer event. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -95,33 +98,46 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer, TestSize.Level0) .hash = "modifyTime1_size1", }; std::pair changedAsset{ "device_1", asset }; + changedAssets_[uri_].status = STATUS_STABLE; machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - // A TRANSFER_FINISHED event will be posted in the callback of the migrated file, therefore, the state will be - // STATUS_STABLE. - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); + ASSERT_EQ(changedAssets_[uri_].deviceId, changedAsset.first); + ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); +} - changedAsset.first = "device_2"; - changedAsset.second.hash = "modifyTime2_size2"; +/** +* @tc.name: StatusTransfer002 +* @tc.desc: Remote changed when transferring. +* @tc.type: FUNC +* @tc.require: +* @tc.author: whj +*/ +HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) +{ + auto machine = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime2", + .size = "size2", + .hash = "modifyTime2_size2", + }; + std::pair changedAsset{ "device_2", asset }; + changedAssets_[uri_].status = STATUS_TRANSFERRING; machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].asset.hash, "modifyTime2_size2"); - ASSERT_EQ(changedAssets_[uri_].deviceId, "device_2"); - - machine->DFAPostEvent(TRANSFER_FINISHED, changedAssets_[uri_], asset); - - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); - - machine->DFAPostEvent(TRANSFER_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); + ASSERT_EQ(changedAssets_[uri_].deviceId, changedAsset.first); + ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); } /** -* @tc.name: StatusTransfer001 -* @tc.desc: No conflict scenarios. Normal object Migration and cloud synchronization processes. +* @tc.name: StatusTransfer003 +* @tc.desc: Compensate transfer in conflict scenario. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -132,20 +148,46 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) .hash = "modifyTime1_size1", }; std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); - ASSERT_EQ(changedAssets_[uri_].deviceId, "device_1"); + 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.desc: Transfer finished. +* @tc.type: FUNC +* @tc.require: +* @tc.author: whj +*/ +HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) +{ + auto machine = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime2", + .size = "size2", + .hash = "modifyTime2_size2", + }; + std::pair changedAsset{ "device_2", asset }; + changedAssets_[uri_].status = STATUS_TRANSFERRING; + machine->DFAPostEvent(TRANSFER_FINISHED, changedAssets_[uri_], asset, changedAsset); ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); } /** -* @tc.name: StatusTransfer002 +* @tc.name: StatusUpload001 * @tc.desc: No conflict scenarios: normal cloud sync. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusUpload001, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -164,13 +206,13 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) } /** -* @tc.name: StatusTransfer003 +* @tc.name: StatusUpload002 * @tc.desc: Conflict scenario: Upload before transfer. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusUpload002, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -187,9 +229,8 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); - ASSERT_EQ(changedAssets_[uri_].deviceId, "device_1"); machine->DFAPostEvent(UPLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); } } // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp index 8dc6e121ee266f3ac63b94335f3ec2bd689abbc6..0bc7579af1adc0c56b12a61f6561523fb13bbb3f 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp @@ -83,7 +83,13 @@ public: { return true; } + bool SetDistrustInfo(const CheckerManager::Distrust &distrust) override { + return true; + }; + bool IsDistrust(const CheckerManager::StoreInfo &info) override { + return true; + } private: static TestChecker instance_; }; @@ -157,7 +163,7 @@ void RdbServiceImplTest::SetUpTestCase(void) { AutoCache::GetInstance().RegCreator(RDB_DEVICE_COLLABORATION, [](const StoreMetaData &metaData) -> GeneralStore* { return new (std::nothrow) GeneralStoreMock(metaData); }); - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); std::vector checks{ CHECK_NAME }; CheckerManager::GetInstance().LoadCheckers(checks); FeatureSystem::GetInstance().GetCreator("relational_store")(); diff --git a/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/cloud_data_test.cpp b/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/cloud_data_test.cpp index 5f73785b7b4489143bdf3e9cafafcf20f8a92564..1923bf4355e7e52dc1763562ac787d3dfd47cbf9 100644 --- a/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/cloud_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/cloud_data_test.cpp @@ -147,7 +147,7 @@ StoreMetaData CloudDataTest::GetStoreMetaData() void CloudDataTest::SetUpTestCase(void) { - MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, nullptr); + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); FeatureSystem::GetInstance().GetCreator("cloud")(); FeatureSystem::GetInstance().GetCreator("relational_store")(); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 8902a1b1ea5c70fd2d2ac688fb3840bdc95d157c..844c2ac9190356cd0b0d0001695a5234be5851e2 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -380,31 +380,48 @@ Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vector &entries) { - size_t size = entries.size(); - DBStatus status; - for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector dbEntries( - entries.begin() + index, entries.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->PutBatch(dbEntries); + DBStatus status = kvStore_->StartTransaction(); + if (status != DBStatus::OK) { + ZLOGE("start transaction failed, status: %{public}d.", status); + return E_DB_ERROR; + } + status = kvStore_->PutBatch(entries); + if (status != DBStatus::OK) { + ZLOGE("putBatch failed, status: %{public}d.", status); + status = kvStore_->Rollback(); if (status != DBStatus::OK) { - ZLOGE("KvStore putBatch failed, status: %{public}d.", status); - return E_DB_ERROR; + ZLOGE("rollback failed, status: %{public}d.", status); } + return E_DB_ERROR; + } + status = kvStore_->Commit(); + if (status != DBStatus::OK) { + ZLOGE("commit failed, status: %{public}d.", status); + return E_DB_ERROR; } return E_OK; } Status RuntimeStore::DeleteEntries(const std::vector &keys) { - size_t size = keys.size(); - DBStatus status; - for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector dbKeys(keys.begin() + index, keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->DeleteBatch(dbKeys); + DBStatus status = kvStore_->StartTransaction(); + if (status != DBStatus::OK) { + ZLOGE("start transaction failed, status: %{public}d.", status); + return E_DB_ERROR; + } + status = kvStore_->DeleteBatch(keys); + if (status != DBStatus::OK) { + ZLOGE("deleteBatch failed, status: %{public}d.", status); + status = kvStore_->Rollback(); if (status != DBStatus::OK) { - ZLOGE("KvStore deleteBatch failed, status: %{public}d.", status); - return E_DB_ERROR; + ZLOGE("rollback failed, status: %{public}d.", status); } + return E_DB_ERROR; + } + status = kvStore_->Commit(); + if (status != DBStatus::OK) { + ZLOGE("commit failed, status: %{public}d.", status); + return E_DB_ERROR; } return E_OK; } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 220050529ec633348913ff32384f8ca8828904ce..110319038a80f8f6d39faf7644a5d2382f7bc6c6 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -472,6 +472,38 @@ int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vectorGet(query.key, unifiedData) != E_OK) { + ZLOGE("Store get unifiedData failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + std::shared_ptr runtime = unifiedData.GetRuntime(); + if (runtime == nullptr) { + ZLOGE("Store get runtime failed, key: %{public}s.", query.key.c_str()); + return E_DB_ERROR; + } + + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + if (localDeviceId != runtime->deviceId) { + result = true; + } + return E_OK; +} + int32_t UdmfServiceImpl::OnInitialize() { ZLOGD("start"); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h index aac010bcef2acb5bde5cdef4c64dc928a0dbeacb..c1225340434989589b978542254d057b19e6604b 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -45,6 +45,7 @@ public: int32_t GetSummary(const QueryOption &query, Summary &summary) override; int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; int32_t Sync(const QueryOption &query, const std::vector &devices) override; + int32_t IsRemoteData(const QueryOption &query, bool &result) override; int32_t OnInitialize() override; int32_t OnBind(const BindInfo &bindInfo) override; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index 018fe837292fba6c5e7c40b51fbbab934dafe585..94a4f6af203ada690a8b6241ce475ecf63b02a4a 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -200,5 +200,21 @@ int32_t UdmfServiceStub::OnSync(MessageParcel &data, MessageParcel &reply) } return E_OK; } + +int32_t UdmfServiceStub::OnIsRemoteData(MessageParcel &data, MessageParcel &reply) +{ + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + ZLOGE("Unmarshal query failed"); + return E_READ_PARCEL_ERROR; + } + bool result = false; + int32_t status = IsRemoteData(query, result); + if (!ITypesUtil::Marshal(reply, status, result)) { + ZLOGE("Marshal IsRemoteData result failed, key: %{public}s", query.key.c_str()); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h index 908d64cafae4c094d4a114ba1bc1b2d3038b61f7..90967b432899f5a8f13b98864c6fde1f961deeb1 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -44,6 +44,7 @@ private: int32_t OnGetSummary(MessageParcel &data, MessageParcel &reply); int32_t OnAddPrivilege(MessageParcel &data, MessageParcel &reply); int32_t OnSync(MessageParcel &data, MessageParcel &reply); + int32_t OnIsRemoteData(MessageParcel &data, MessageParcel &reply); using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { @@ -54,7 +55,8 @@ private: &UdmfServiceStub::OnDeleteData, &UdmfServiceStub::OnGetSummary, &UdmfServiceStub::OnAddPrivilege, - &UdmfServiceStub::OnSync + &UdmfServiceStub::OnSync, + &UdmfServiceStub::OnIsRemoteData }; }; } // namespace UDMF diff --git a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp index f8ecffbb5e11b3c091e076bb8a367fed87fc8da0..31944b7757fc09ce9a3710f4232b334051b851f9 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp @@ -155,7 +155,7 @@ CustomUtdCfgs CustomUtdInstaller::GetModuleCustomUtdTypes(const std::string &bun auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, moduleName, jsonStr, user); if (status != NO_ERROR) { - ZLOGE("get json profile failed, bundleName: %{public}s.", bundleName.c_str()); + ZLOGD("get json profile failed, bundleName: %{public}s.", bundleName.c_str()); return typeCfgs; } if (jsonStr.empty()) { diff --git a/interface_sdk/api/@ohos.data.relationalStore.d.ts b/interface_sdk/api/@ohos.data.relationalStore.d.ts index 3c368e9d8594dda68cafd17270f85fb11ec0a57d..3186ffdca769aa86196f0f5d7ada028b4dfa5905 100644 --- a/interface_sdk/api/@ohos.data.relationalStore.d.ts +++ b/interface_sdk/api/@ohos.data.relationalStore.d.ts @@ -3101,6 +3101,21 @@ declare namespace relationalStore { */ executeSql(sql: string, bindArgs?: Array): Promise; + /** + * Executes a SQL statement that contains specified parameters and returns a value of ValueType. + * + * @param { string } sql - Indicates the SQL statement to execute. + * @param { Array } args - Indicates the {@link ValueType} values of the parameters in the SQL statement. The values are strings. + * @returns { Promise } The promise returned by the function. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 14800011 - Failed to open database by database corrupted. + * @throws { BusinessError } 14800047 - The WAL file size exceeds the default limit. + * @throws { BusinessError } 14800000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + execute(sql: string, args?: Array): Promise; + /** * BeginTransaction before execute your sql. * diff --git a/kv_store/CMakeLists.txt b/kv_store/CMakeLists.txt index 00a795362abb62e6e2cc3266f84955982272666d..797eeddba2a9c24eebf2dbf708a05aa28b612d6b 100644 --- a/kv_store/CMakeLists.txt +++ b/kv_store/CMakeLists.txt @@ -3,4 +3,5 @@ project(kv_store) add_subdirectory(frameworks/libs) add_subdirectory(frameworks/libs/distributeddb/gaussdb_rd) -add_subdirectory(frameworks) \ No newline at end of file +add_subdirectory(frameworks) +add_subdirectory(databaseutils) \ No newline at end of file diff --git a/kv_store/bundle.json b/kv_store/bundle.json index a1e55e77215458aae61c0dbb495021078ff40ac0..24e256fcd29499d68fa28ca094c28e6fa26e8974 100644 --- a/kv_store/bundle.json +++ b/kv_store/bundle.json @@ -86,7 +86,8 @@ "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/jskits/distributeddata:build_module", "//foundation/distributeddatamgr/kv_store/interfaces/jskits/distributedkvstore:build_module", "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/jskits/distributedkvstore:build_module", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_client_sync" + "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_client_sync", + "//foundation/distributeddatamgr/kv_store/databaseutils:database_utils" ], "inner_kits": [ { @@ -194,6 +195,15 @@ ], "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include/distributeddb" } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/databaseutils:database_utils", + "header": { + "header_files": [ + "acl.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/databaseutils/include" + } } ], "test": [ @@ -204,7 +214,8 @@ "//foundation/distributeddatamgr/kv_store/test/unittest/distributeddata:unittest", "//foundation/distributeddatamgr/kv_store/test/unittest/distributedKVStore:unittest", "//foundation/distributeddatamgr/kv_store/frameworks/common/test:unittest", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/test:unittest" + "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/test:unittest", + "//foundation/distributeddatamgr/kv_store/databaseutils/test:unittest" ] } } diff --git a/kv_store/databaseutils/BUILD.gn b/kv_store/databaseutils/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..a58428473c48c9fdee38f4a6bd51ee3f51a5bbc8 --- /dev/null +++ b/kv_store/databaseutils/BUILD.gn @@ -0,0 +1,47 @@ +# 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/kv_store/kv_store.gni") + +config("database_utils_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "${kv_store_base_path}/frameworks/common", + ] +} + +config("database_utils_public_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +base_sources = [ "src/acl.cpp" ] + +ohos_shared_library("database_utils") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = base_sources + + configs = [ ":database_utils_config" ] + cflags_cc = [ "-fvisibility=hidden" ] + public_configs = [ ":database_utils_public_config" ] + external_deps = [ "hilog:libhilog" ] + public_external_deps = [ "bounds_checking_function:libsec_shared" ] + subsystem_name = "distributeddatamgr" + part_name = "kv_store" +} diff --git a/kv_store/databaseutils/CMakeLists.txt b/kv_store/databaseutils/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..997988f65ad67ed834d10d6f5cbb7375f753bb77 --- /dev/null +++ b/kv_store/databaseutils/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.11.2) +project(kvdb) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -fno-rtti -fvisibility=default -D_GNU_SOURCE") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -fPIC -fpic -ffunction-sections -D_GLIBC_MOCK") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-as-needed -ldl") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=0 -Wattributes") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") +set(MOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../mock) +add_definitions(-DNAPI_EXPERIMENTAL) + +# 设置名为databaseUtilsSrc的源代码目录 +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src databaseUtilsSrc) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include(${MOCK_DIR}/include/CMakeLists.txt) + +# 创建一个名为databaseUtils的共享库,源代码路径是${databaseUtilsSrc} +add_library(databaseUtils SHARED ${databaseUtilsSrc}) + +# 对外暴露的头文件,Public表示我依赖,外部依赖本so以后也可以直接引头文件,private表示不能 +target_include_directories(databaseUtils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(databaseUtils PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../frameworks/common/) + +# 前者依赖后者,后边有多个时表示第一个依赖后边所有的 +target_link_libraries(databaseUtils mock) diff --git a/kv_store/databaseutils/include/acl.h b/kv_store/databaseutils/include/acl.h new file mode 100644 index 0000000000000000000000000000000000000000..dc60ca9c2641e276aaf4108961e3bbbdbc62b2cf --- /dev/null +++ b/kv_store/databaseutils/include/acl.h @@ -0,0 +1,174 @@ +/* + * 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_DATABASE_UTILS_ACL_H +#define OHOS_DISTRIBUTED_DATA_DATABASE_UTILS_ACL_H + +#include +#include +#include +#include +#include + +#include "visibility.h" +namespace OHOS { +namespace DATABASE_UTILS { +/* + * ACL tag values + */ +enum class ACL_TAG : uint16_t { + UNDEFINED = 0x00, + USER_OBJ = 0x01, + USER = 0x02, + GROUP_OBJ = 0x04, + GROUP = 0x08, + MASK = 0x10, + OTHER = 0x20, +}; + +/* + * ACL perm values + */ +class ACL_PERM { +public: + uint16_t value_ = 0; + enum Value : uint16_t { + READ = 0x04, + WRITE = 0x02, + EXECUTE = 0x01, + }; + +public: + ACL_PERM() = default; + ACL_PERM(const uint16_t x) + { + value_ = (x & READ) | (x & WRITE) | (x & EXECUTE); + } + void SetR() { value_ |= READ; } + void SetW() { value_ |= WRITE; } + void SetE() { value_ |= EXECUTE; } + bool IsReadable() const { return (value_ & READ) == READ; } + bool IsWritable() const { return (value_ & WRITE) == WRITE; } + bool IsExecutable() const { return (value_ & EXECUTE) == EXECUTE; } + void Merge(const ACL_PERM &acl_perm) { value_ |= acl_perm.value_; } +}; + + +/* + * ACL data structure + */ +struct AclXattrHeader { + static constexpr uint32_t ACL_EA_VERSION = 0x0002; + uint32_t version = ACL_EA_VERSION; +}; + +struct AclXattrEntry { + static constexpr uint32_t ACL_UNDEFINED_ID = static_cast(-1); + ACL_TAG tag_ = ACL_TAG::UNDEFINED; + ACL_PERM perm_ = {}; + uint32_t id_ = ACL_UNDEFINED_ID; + + AclXattrEntry(const ACL_TAG tag, const uint32_t id, const ACL_PERM mode) : tag_(tag), perm_(mode), id_(id) + { + } + + bool IsValid() const + { + if (tag_ == ACL_TAG::USER || tag_ == ACL_TAG::GROUP) { + return id_ != ACL_UNDEFINED_ID; + } + return tag_ != ACL_TAG::UNDEFINED; + } + + bool operator<(const AclXattrEntry &rhs) const + { + if (tag_ == rhs.tag_) { + return id_ < rhs.id_; + } + return tag_ < rhs.tag_; + } + + bool operator==(const AclXattrEntry &rhs) const + { + return tag_ == rhs.tag_ && perm_.value_ == rhs.perm_.value_ && id_ == rhs.id_; + } + + friend inline bool operator<(const AclXattrEntry &lhs, const ACL_TAG &rhs) + { + return lhs.tag_ < rhs; + } + + friend inline bool operator<(const ACL_TAG &lhs, const AclXattrEntry &rhs) + { + return lhs < rhs.tag_; + } +}; + +class Acl { +public: + static constexpr uint16_t R_RIGHT = 4; + static constexpr uint16_t W_RIGHT = 2; + static constexpr uint16_t E_RIGHT = 1; + + API_EXPORT Acl(const std::string &path); + Acl(); + API_EXPORT ~Acl(); + API_EXPORT int32_t SetDefaultGroup(const uint32_t gid, const uint16_t mode); + API_EXPORT int32_t SetDefaultUser(const uint32_t uid, const uint16_t mode); + // just for Acl Test + bool HasEntry(const AclXattrEntry &entry); + +private: + /* + * ACL extended attributes (xattr) names + */ + static constexpr const char *ACL_XATTR_DEFAULT = "system.posix_acl_default"; + static constexpr int32_t E_OK = 0; + static constexpr int32_t E_ERROR = -1; + static constexpr int32_t USER_OFFSET = 6; + static constexpr int32_t GROUP_OFFSET = 3; + static constexpr int32_t BUF_SIZE = 400; + static constexpr size_t ENTRIES_MAX_NUM = 100; // just heuristic + static constexpr size_t BUF_MAX_SIZE = sizeof(AclXattrHeader) + sizeof(AclXattrEntry) * ENTRIES_MAX_NUM; + bool IsEmpty(); + int32_t SetDefault(); + void AclFromMode(); + void AclFromDefault(); + void CompareInsertEntry(const AclXattrEntry &entry); + ACL_PERM ReCalcMaskPerm(); + std::unique_ptr Serialize(int32_t &bufSize); + int DeSerialize(const char *p, int32_t bufSize); + int InsertEntry(const AclXattrEntry &entry); + AclXattrHeader header_; + /* + * Only one entry should exist for the following types: + * ACL_USER_OBJ + * ACL_GROUP_OBJ + * ACL_MASK + * ACL_OTHER + * While for these types, multiple entries could exist, but one entry + * for each id (i.e. uid/gid): + * ACL_USER + * ACL_GROUP + */ + std::set> entries_; + unsigned maskDemand_ = 0; + std::string path_; + bool hasError_ = false; +}; +} // DATABASE_UTILS +} // namespace OHOS + +#endif // OHOS_DISTRIBUTED_DATA_DATABASE_UTILS_ACL_H \ No newline at end of file diff --git a/kv_store/databaseutils/src/acl.cpp b/kv_store/databaseutils/src/acl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f33429697fe28017abe627432f97c69b52e3d5b --- /dev/null +++ b/kv_store/databaseutils/src/acl.cpp @@ -0,0 +1,219 @@ +/* + * 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 "DataBaseUtilsAcl" +#include "acl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log_print.h" +#include "securec.h" + +namespace OHOS { +namespace DATABASE_UTILS { +using namespace DistributedKv; +Acl::Acl(const std::string &path) : path_(path), hasError_(false) +{ + /* init acl from file's defaule or mode*/ + AclFromDefault(); +} + +Acl::Acl() +{ +} + +ACL_PERM Acl::ReCalcMaskPerm() +{ + ACL_PERM perm; + for (const auto &e : entries_) { + if (e.tag_ == ACL_TAG::USER || e.tag_ == ACL_TAG::GROUP_OBJ || e.tag_ == ACL_TAG::GROUP) { + perm.Merge(e.perm_); + } + } + return perm; +} + +bool Acl::IsEmpty() +{ + return entries_.empty(); +} + +void Acl::CompareInsertEntry(const AclXattrEntry &entry) +{ + if (entries_.count(entry)) { + auto it = entries_.find(entry); + entries_.erase(it); + } + if (entry.perm_.IsReadable() || entry.perm_.IsWritable() || + entry.perm_.IsExecutable()) { + entries_.insert(entry); + } +} + +int Acl::InsertEntry(const AclXattrEntry &entry) +{ + if (entries_.size() >= ENTRIES_MAX_NUM) { + return E_ERROR; + } + CompareInsertEntry(entry); // must before ReCalcMaskPerm() + + maskDemand_++; + /* + * In either case there's no or already one ACL_MASK entry in the set, + * we need to re-calculate MASK's permission and *insert* it (to replace + * the old one in latter case since we can't change std::set's element + * in-place). So do the following unconditionally. + * + * Be warned: do _NOT_ combine the following into one line, otherwise + * you can't pass the !!genius!! CI coding style check. + */ + CompareInsertEntry(AclXattrEntry(ACL_TAG::MASK, AclXattrEntry::ACL_UNDEFINED_ID, ReCalcMaskPerm())); + return E_OK; +} + +std::unique_ptr Acl::Serialize(int32_t &bufSize) +{ + bufSize = sizeof(AclXattrHeader) + sizeof(AclXattrEntry) * entries_.size(); + if (bufSize > static_cast(BUF_MAX_SIZE)) { + bufSize = 0; + return nullptr; + } + auto buf = std::make_unique(bufSize); + auto err = memcpy_s(buf.get(), bufSize, &header_, sizeof(AclXattrHeader)); + if (err != EOK) { + bufSize = 0; + return nullptr; + } + + int32_t restSize = bufSize - sizeof(AclXattrHeader); + AclXattrEntry *ptr = reinterpret_cast(buf.get() + sizeof(AclXattrHeader)); + for (const auto &e : entries_) { + auto err = memcpy_s(ptr++, restSize, &e, sizeof(AclXattrEntry)); + if (err != EOK) { + bufSize = 0; + return nullptr; + } + restSize -= sizeof(AclXattrEntry); + } + return buf; +} + +int Acl::DeSerialize(const char *p, int32_t bufSize) +{ + header_ = *reinterpret_cast(p); + bufSize -= sizeof(AclXattrHeader); + p += sizeof(AclXattrHeader); + + /* + * `e->tag != ACL_TAG::UNDEFINED` is unreliable outside the buffer, so check + * it after checking the size of remaining buffer. + */ + for (const AclXattrEntry *e = reinterpret_cast(p); + bufSize >= static_cast(sizeof(AclXattrEntry)) && e->tag_ != ACL_TAG::UNDEFINED; + e++) { + InsertEntry(*e); + bufSize -= sizeof(AclXattrEntry); + } + if (bufSize < 0) { + entries_.clear(); + header_ = { 0 }; + return -1; + } + + return 0; +} + +void Acl::AclFromDefault() +{ + char buf[BUF_SIZE] = { 0 }; + ssize_t len = getxattr(path_.c_str(), ACL_XATTR_DEFAULT, buf, BUF_SIZE); + if (len != -1) { + DeSerialize(buf, BUF_SIZE); + } else if (errno == ENODATA) { + AclFromMode(); + } else { + hasError_ = true; + ZLOGW("getxattr failed. error %{public}s path %{public}s", std::strerror(errno), path_.c_str()); + } +} + +void Acl::AclFromMode() +{ + struct stat st; + if (stat(path_.c_str(), &st) == -1) { + return; + } + + InsertEntry(AclXattrEntry(ACL_TAG::USER_OBJ, AclXattrEntry::ACL_UNDEFINED_ID, + (st.st_mode & S_IRWXU) >> USER_OFFSET)); + InsertEntry(AclXattrEntry(ACL_TAG::GROUP_OBJ, AclXattrEntry::ACL_UNDEFINED_ID, + (st.st_mode & S_IRWXG) >> GROUP_OFFSET)); + InsertEntry(AclXattrEntry(ACL_TAG::OTHER, AclXattrEntry::ACL_UNDEFINED_ID, + (st.st_mode & S_IRWXO))); +} + +int32_t Acl::SetDefault() +{ + if (IsEmpty()) { + ZLOGE("Failed to generate ACL from file's mode: %{public}s", std::strerror(errno)); + return E_ERROR; + } + + /* transform to binary and write to file */ + int32_t bufSize; + auto buf = Serialize(bufSize); + if (buf == nullptr) { + ZLOGE("Failed to serialize ACL into binary: %{public}s", std::strerror(errno)); + return E_ERROR; + } + if (setxattr(path_.c_str(), ACL_XATTR_DEFAULT, buf.get(), bufSize, 0) == -1) { + ZLOGE("Failed to write into file's xattr: %{public}s", std::strerror(errno)); + return E_ERROR; + } + return E_OK; +} + +int32_t Acl::SetDefaultGroup(const uint32_t gid, const uint16_t mode) +{ + return InsertEntry(AclXattrEntry(ACL_TAG::GROUP, gid, mode)); +} + +int32_t Acl::SetDefaultUser(const uint32_t uid, const uint16_t mode) +{ + return InsertEntry(AclXattrEntry(ACL_TAG::USER, uid, mode)); +} + +Acl::~Acl() +{ + if (!hasError_) { + SetDefault(); + } +} + +bool Acl::HasEntry(const AclXattrEntry &Acl) +{ + return entries_.find(Acl) != entries_.end(); +} +} +} \ No newline at end of file diff --git a/kv_store/databaseutils/test/BUILD.gn b/kv_store/databaseutils/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..805e13f5764071e2e19d937f8f0b5a696d146396 --- /dev/null +++ b/kv_store/databaseutils/test/BUILD.gn @@ -0,0 +1,47 @@ +# 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/test.gni") +import("//foundation/distributeddatamgr/kv_store/kv_store.gni") + +module_output_path = "kv_store/databaseutils" +config("database_utils_config") { + visibility = [ ":*" ] + + include_dirs = [ + "../include", + "${kv_store_base_path}/frameworks/common", + ] +} + +ohos_unittest("DataBaseUtilsTest") { + module_out_path = module_output_path + + sources = [ "acl_test.cpp" ] + sources += [ "../src/acl.cpp" ] + + configs = [ ":database_utils_config" ] + + external_deps = [ "hilog:libhilog" ] + public_external_deps = [ + "bounds_checking_function:libsec_shared", + "googletest:gtest", + ] +} + +group("unittest") { + testonly = true + + deps = [] + deps += [ ":DataBaseUtilsTest" ] +} +############################################################################### diff --git a/kv_store/databaseutils/test/acl_test.cpp b/kv_store/databaseutils/test/acl_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa83c9733f2843cbf53b0ea7cd2bfbf0dca269fa --- /dev/null +++ b/kv_store/databaseutils/test/acl_test.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "acl.h" + +#include +#include +#include +#include +#include +#include "gtest/gtest.h" +#include "securec.h" +using namespace testing::ext; +namespace OHOS::Test { +using namespace DATABASE_UTILS; +class AclTest : public testing::Test { +public: + static constexpr const char *PATH_ABC = "/data/test/abc"; + static constexpr const char *PATH_ABC_XIAOMING = "/data/test/abc/xiaoming"; + static constexpr const char *PATH_ABC_XIAOMING_TEST = "/data/test/abc/xiaoming/test.txt"; + static constexpr const char *DATA = "SetDefaultUserTest"; + static constexpr int UID = 2024; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + void PreOperation() const; +}; + +void AclTest::SetUpTestCase(void) +{ +} + +void AclTest::TearDownTestCase(void) +{ +} + +// input testcase setup step,setup invoked before each testcases +void AclTest::SetUp(void) +{ + (void)remove(PATH_ABC); +} + +// input testcase teardown step,teardown invoked after each testcases +void AclTest::TearDown(void) +{ + (void)remove(PATH_ABC); +} + +void AclTest::PreOperation() const +{ + mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771 + int res = mkdir(PATH_ABC, mode); + EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno); + + Acl acl(PATH_ABC); + acl.SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT); + acl.SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT); + + res = mkdir(PATH_ABC_XIAOMING, mode); + EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno); + + int fd = open(PATH_ABC_XIAOMING_TEST, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + EXPECT_NE(fd, -1) << "open file failed." << std::strerror(errno); + res = write(fd, DATA, strlen(DATA)); + EXPECT_NE(res, -1) << "write failed." << std::strerror(errno); + res = fsync(fd); + EXPECT_NE(res, -1) << "fsync failed." << std::strerror(errno); + close(fd); +} + +/** +* @tc.name: SetDefaultGroup001 +* @tc.desc: Set default extended properties for groups. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Jiaxing Chang +*/ +HWTEST_F(AclTest, SetDefaultGroup001, TestSize.Level0) +{ + mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771 + int res = mkdir(PATH_ABC, mode); + EXPECT_EQ(res, 0) << "directory creation failed."; + int rc = Acl(PATH_ABC).SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT); + EXPECT_EQ(rc, 0); + + Acl aclNew(PATH_ABC); + AclXattrEntry entry(ACL_TAG::GROUP, UID, Acl::R_RIGHT | Acl::W_RIGHT); + ASSERT_TRUE(aclNew.HasEntry(entry)); +} + +/** +* @tc.name: SetDefaultpUser001 +* @tc.desc: Set default extended properties for user. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Jiaxing Chang +*/ +HWTEST_F(AclTest, SetDefaultUser001, TestSize.Level0) +{ + mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771 + int res = mkdir(PATH_ABC, mode); + EXPECT_EQ(res, 0) << "directory creation failed."; + int rc = Acl(PATH_ABC).SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT); + EXPECT_EQ(rc, 0); + + Acl aclNew(PATH_ABC); + AclXattrEntry entry(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT); + ASSERT_TRUE(aclNew.HasEntry(entry)); +} + +/** +* @tc.name: SetDefaultUser002 +* @tc.desc: After the main process extends the uid attribute, set this uid to the uid and gid of the child process, +* and the child process can access the files created by the main process normally. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Jiaxing Chang +*/ +HWTEST_F(AclTest, SetDefaultUser002, TestSize.Level0) +{ + PreOperation(); + int fd[2]; + pid_t pid; + char buf[100]; + int res = pipe(fd); + ASSERT_TRUE(res >= 0) << "create pipe failed." << std::strerror(errno); + pid = fork(); + ASSERT_TRUE(pid >= 0) << "fork failed." << std::strerror(errno); + if (pid == 0) { // subprocess + // close the read end of the pipeline. + close(fd[0]); + // redirect standard output to the write end of the pipeline + dup2(fd[1], STDOUT_FILENO); + auto exitFun = [&fd](const std::string &str, bool isErr) { + std::cout << str << (isErr ? std::strerror(errno) : "") << std::endl; + close(fd[1]); + _exit(0); + }; + if (setuid(UID) != 0) { + exitFun("setuid failed.", true); + } + if (setgid(UID) != 0) { + exitFun("setgid failed.", true); + } + int file = open(PATH_ABC_XIAOMING_TEST, O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (file == -1) { + exitFun("open file failed.", true); + } + if (read(file, buf, sizeof(buf)) == -1) { + close(file); + exitFun("read failed.", true); + } + close(file); + exitFun(buf, false); + } else { // main process + // close the write end of the pipeline. + close(fd[1]); + int status; + res = waitpid(pid, &status, 0); + EXPECT_NE(res, -1) << "waitpid falied." << std::strerror(errno); + res = memset_s(buf, sizeof(buf), 0, sizeof(buf)); + EXPECT_EQ(res, EOK) << "memset_s falied." << std::strerror(errno); + res = read(fd[0], buf, sizeof(buf)); + EXPECT_NE(res, -1) << "read falied." << std::strerror(errno); + EXPECT_EQ(std::string(buf, buf + strlen(buf) - 1), std::string(DATA)) << "buffer:[" << buf << "]"; + close(fd[0]); + } +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/CMakeLists.txt b/kv_store/frameworks/CMakeLists.txt index a78af1d470112c44ef8ee18dcfcb7a3744898861..33ed5518a761b4bfcc8c24c5c7fff7beac4c6433 100644 --- a/kv_store/frameworks/CMakeLists.txt +++ b/kv_store/frameworks/CMakeLists.txt @@ -16,7 +16,6 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/kvdb/src kvdbSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/jskitsimpl/distributedkvstore/src jsKVSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/jskitsimpl/distributeddata/src jsDataSrc) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../utils_native/base/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../utils_native/safwk/native/include) include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) @@ -25,9 +24,10 @@ set(links secure mock distributeddb) add_library(kvdb SHARED ${kvdbSrc}) add_library(jskvdb SHARED ${jsKVSrc}) add_library(jsolddb SHARED ${jsDataSrc}) -target_link_libraries(kvdb ${links}) +target_link_libraries(kvdb ${links} databaseUtils) target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/innerkits/distributeddata/include) target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/innerkits/distributeddatamgr/include) +target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../databaseutils/include) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/include) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatasvc/include) diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn index dc43f1adaec3661e4aca8ee8ffeac88b88c058ba..da2bc0c87c9fdcec714e2662f13138aa42f81637 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn @@ -45,6 +45,9 @@ ohos_source_set("distributeddatafwk_src_file") { testonly = true old_sources = [ + "../../distributeddatasvc/src/datamgr_service_proxy.cpp", + "../../distributeddatasvc/src/distributed_data_mgr.cpp", + "../../distributeddatasvc/src/kvstore_data_service_mgr.cpp", "../src/blob.cpp", "../src/change_notification.cpp", "../src/data_query.cpp", @@ -70,6 +73,8 @@ ohos_source_set("distributeddatafwk_src_file") { "../../kvdb/src/kv_types_util.cpp", "../../kvdb/src/kvdb_service_client.cpp", "../../kvdb/src/observer_bridge.cpp", + "../../kvdb/src/process_communication_impl.cpp", + "../../kvdb/src/process_system_api_adapter_impl.cpp", "../../kvdb/src/security_manager.cpp", "../../kvdb/src/single_store_impl.cpp", "../../kvdb/src/store_factory.cpp", @@ -85,6 +90,7 @@ ohos_source_set("distributeddatafwk_src_file") { configs = [ ":module_private_config" ] deps = [ + "../../../../databaseutils:database_utils", "../../../../interfaces/innerkits/distributeddatamgr:distributeddata_mgr", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp:devicemanagersdk", @@ -325,6 +331,49 @@ ohos_unittest("KvstoreDatashareBridgeTest") { ] } +ohos_unittest("DistributedDataMgrTest") { + module_out_path = module_output_path + + sources = [ "unittest/distributed_data_mgr_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ + ":distributeddatafwk_src_file", + "//third_party/googletest:gtest_main", + ] +} + +ohos_unittest("EndPointTest") { + module_out_path = module_output_path + + sources = [ "unittest/end_point_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ + ":distributeddatafwk_src_file", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -334,8 +383,10 @@ group("unittest") { deps += [ ":BlobTest", ":DeviceKvStoreTest", + ":DistributedDataMgrTest", ":DistributedKvDataManagerEncryptTest", ":DistributedKvDataManagerTest", + ":EndPointTest", ":KvUtilTest", ":KvstoreDatashareBridgeTest", ":LocalSubscribeDeviceStoreTest", diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a90678861194d5f913d91830618902aea047834f --- /dev/null +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp @@ -0,0 +1,117 @@ +/* + * 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 "distributed_data_mgr.h" +#include +#include +#include "types.h" +#include "accesstoken_kit.h" +#include "nativetoken_kit.h" +#include "token_setproc.h" + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +using namespace OHOS::Security::AccessToken; +namespace OHOS::Test { +class DistributedDataMgrTest : public testing::Test { +public: + static DistributedDataMgr manager; + static void SetUpTestCase(void) {}; + static void TearDownTestCase(void) {}; + void SetUp(); + void TearDown(); + static constexpr int32_t TEST_USERID = 100; + static constexpr int32_t APP_INDEX = 0; + NativeTokenInfoParams infoInstance {0}; +}; +DistributedDataMgr DistributedDataMgrTest::manager; + +void DistributedDataMgrTest::SetUp(void) +{ + 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 = "ohos.test.demo", + .instIndex = 0, + .appIDDesc = "ohos.test.demo" + }; + PermissionDef infoManagerTestPermDef = { + .permissionName = "ohos.permission.test", + .bundleName = "ohos.test.demo", + .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 DistributedDataMgrTest::TearDown(void) +{ + auto tokenId = AccessTokenKit::GetHapTokenID(TEST_USERID, "ohos.test.demo", 0); + AccessTokenKit::DeleteToken(tokenId); +} + +/** +* @tc.name: ClearAppStorage +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DistributedDataMgrTest, ClearAppStorage001, TestSize.Level1) +{ + auto tokenId = AccessTokenKit::GetHapTokenID(TEST_USERID, "ohos.test.demo", 0); + auto ret = manager.ClearAppStorage("ohos.test.demo", TEST_USERID, APP_INDEX, tokenId); + EXPECT_EQ(ret, Status::SUCCESS); +} + +/** +* @tc.name: ClearAppStorage +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DistributedDataMgrTest, ClearAppStorage002, TestSize.Level1) +{ + auto tokenId = AccessTokenKit::GetHapTokenID(TEST_USERID, "ohos.test.fail", 0); + auto ret = manager.ClearAppStorage("ohos.test.demo", TEST_USERID, APP_INDEX, tokenId); + EXPECT_EQ(ret, Status::ERROR); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp index 1a2c9d8aeaf78708d7aa8a9a53b8c1da7ae05707..9acca9e6496af6a99bbb8331c299ad16e859a5f9 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp @@ -20,11 +20,14 @@ #include "kvstore_death_recipient.h" #include "log_print.h" #include "types.h" + using namespace testing::ext; using namespace OHOS::DistributedKv; namespace OHOS::Test { class DistributedKvDataManagerTest : public testing::Test { public: + static constexpr size_t NUM_MIN = 5; + static constexpr size_t NUM_MAX = 12; static DistributedKvDataManager manager; static Options create; static Options noCreate; @@ -79,6 +82,9 @@ void DistributedKvDataManagerTest::RemoveAllStore(DistributedKvDataManager &mana } void DistributedKvDataManagerTest::SetUpTestCase(void) { + auto executors = std::make_shared(NUM_MAX, NUM_MIN); + manager.SetExecutors(executors); + userId.userId = "account0"; appId.appId = "ohos.kvdatamanager.test"; create.createIfMissing = true; diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b5a1cbb772a1e189aadb27aa1d64611c3ca2fc5 --- /dev/null +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp @@ -0,0 +1,215 @@ +/* + * 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 +#include +#include +#include +#include +#include "dev_manager.h" +#include "distributed_kv_data_manager.h" +#include "file_ex.h" +#include "types.h" + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +namespace OHOS::Test { +class EndPointTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static std::string GetKey(const std::string &key); + static std::shared_ptr kvStore_; // declare kvstore instance. + static Status status_; + static std::string deviceId_; + static Options options_; +}; + +const std::string VALID_SCHEMA = "{\"SCHEMA_VERSION\":\"1.0\"," + "\"SCHEMA_MODE\":\"STRICT\"," + "\"SCHEMA_SKIPSIZE\":0," + "\"SCHEMA_DEFINE\":{" + "\"age\":\"INTEGER, NOT NULL\"" + "}," + "\"SCHEMA_INDEXES\":[\"$.age\"]}"; + +std::shared_ptr EndPointTest::kvStore_ = nullptr; +Status EndPointTest::status_ = Status::ERROR; +std::string EndPointTest::deviceId_; +Options EndPointTest::options_; + +void EndPointTest::SetUpTestCase(void) +{ + DistributedKvDataManager manager; + options_.area = EL1; + options_.baseDir = std::string("/data/service/el1/public/database/odmf"); + options_.securityLevel = S1; + mkdir(options_.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + AppId appId = { "odmf" }; + StoreId storeId = { "student_device" }; // define kvstore(database) name. + // [create and] open and initialize kvstore instance. + status_ = manager.GetSingleKvStore(options_, appId, storeId, kvStore_); + auto deviceInfo = DevManager::GetInstance().GetLocalDevice(); + deviceId_ = deviceInfo.networkId; +} + +void EndPointTest::TearDownTestCase(void) +{ + DistributedKvDataManager manager; + AppId appId = { "odmf" }; + manager.DeleteAllKvStore(appId, options_.baseDir); + (void)remove("/data/service/el1/public/database/odmf/key"); + (void)remove("/data/service/el1/public/database/odmf/kvdb"); + (void)remove("/data/service/el1/public/database/odmf"); +} + +void EndPointTest::SetUp(void) +{} + +void EndPointTest::TearDown(void) +{} + +std::string EndPointTest::GetKey(const std::string& key) +{ + std::ostringstream oss; + oss << std::setfill('0') << std::setw(sizeof(uint32_t)) << deviceId_.length(); + oss << deviceId_ << std::string(key.begin(), key.end()); + return oss.str(); +} + +class EndpointMock : public Endpoint { +public: + EndpointMock() {} + virtual ~EndpointMock() {} + + Status Start() override + { + return Status::SUCCESS; + } + + Status Stop() override + { + return Status::SUCCESS; + } + + Status RegOnDataReceive(const RecvHandler &callback) override + { + return Status::SUCCESS; + } + + Status SendData(const std::string &dtsIdentifier, const uint8_t *data, uint32_t length) override + { + return Status::SUCCESS; + } + + uint32_t GetMtuSize(const std::string &identifier) override + { + return 1 * 1024 * 1024; // 1 * 1024 * 1024 Byte. + } + + std::string GetLocalDeviceInfos() override + { + return "Mock Device"; + } + + bool IsSaferThanDevice(int securityLevel, const std::string &devId) override + { + return true; + } + + bool HasDataSyncPermission(const StoreBriefInfo ¶m, uint8_t flag) override + { + return true; + } +}; + +/** +* @tc.name: SetEndpoint001 +* @tc.desc: test the SetEndpoint(std::shared_ptr endpoint) +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(EndPointTest, SetEndpoint001, TestSize.Level1) +{ + DistributedKvDataManager manager; + std::shared_ptr endpoint = nullptr; + Status status = manager.SetEndpoint(endpoint); + ASSERT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: SetEndpoint002 +* @tc.desc: test the SetEndpoint(std::shared_ptr endpoint) +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(EndPointTest, SetEndpoint002, TestSize.Level1) +{ + DistributedKvDataManager manager; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** + * @tc.name: SetIdentifier001 + * desc: test the Status set identifier function. + * type: FUNC + * require: + * author:SQL + */ +HWTEST_F(EndPointTest, SetIdentifier001, TestSize.Level1) +{ + DistributedKvDataManager manager; + EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; + AppId appId = { "odmf" }; + StoreId storeId = { "test_storeid" }; + std::vector targetDev = {"devicid1", "devicid2"}; + std::string accountId = "testAccount"; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + auto testStatus = kvStore_->SetIdentifier(accountId, appId, storeId, targetDev); + EXPECT_EQ(testStatus, Status::SUCCESS); +} + +/** + * @tc.name: SetIdentifier002 + * desc: test the Status set identifier function. + * type: FUNC + * require: + * author:SQL + */ +HWTEST_F(EndPointTest, SetIdentifier002, TestSize.Level1) +{ + DistributedKvDataManager manager; + EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; + AppId appId = { "" }; + StoreId storeId = { "" }; + std::vector targetDev = {"devicid1", "devicid2"}; + std::string accountId = "testAccount"; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + auto testStatus = kvStore_->SetIdentifier(accountId, appId, storeId, targetDev); + EXPECT_NE(testStatus, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp index fce33602f25ce60d7dce64610ed021b7c9d4d4eb..b1e9bfd721fd590dd0d00e08734ab7e48f60c101 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp @@ -1007,4 +1007,42 @@ HWTEST_F(SingleKvStoreClientQueryTest, DataQueryDeviceIdValidField, TestSize.Lev query.DeviceId(deviceId); EXPECT_TRUE(query.ToString().length() == 0); } -} // namespace \ No newline at end of file + +/** +* @tc.name: DataQuery +* @tc.desc: the predicate is between, the value is invalid. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(SingleKvStoreClientQueryTest, DataQueryBetweenInvalid, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .encrypt = true, .autoSync = true, + .kvStoreType = KvStoreType::SINGLE_VERSION, .schema = VALID_SCHEMA_STRICT_DEFINE }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = "/data/service/el1/public/database/SingleKvStoreClientQueryTest"; + AppId appId = { "SingleKvStoreClientQueryTest" }; + StoreId storeId = { "SingleKvStoreClientQueryTestStoreId3" }; + statusGetKvStore = manager.GetSingleKvStore(options, appId, storeId, singleKvStore); + EXPECT_NE(singleKvStore, nullptr) << "kvStorePtr is null."; + singleKvStore->Put("test_key_1", "{\"name\":1}"); + singleKvStore->Put("test_key_2", "{\"name\":2}"); + singleKvStore->Put("test_key_3", "{\"name\":3}"); + + DataQuery query; + query.Between({}, {}); + std::vector results1; + Status status = singleKvStore->GetEntries(query, results1); + EXPECT_EQ(status, NOT_SUPPORT); + + singleKvStore->Delete("test_key_1"); + singleKvStore->Delete("test_key_2"); + singleKvStore->Delete("test_key_3"); + status = manager.CloseAllKvStore(appId); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.DeleteAllKvStore(appId, options.baseDir); + EXPECT_EQ(status, Status::SUCCESS); +} +} // namespace diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h index 0b071cf22d3440ae739bf2e290f2eec637669912..3aea619c9536e879bc2e2796b253d806fd57b971 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h @@ -39,6 +39,7 @@ enum class KVDBServiceInterfaceCode : uint32_t { TRANS_SUB, TRANS_UNSUB, TRANS_GET_PASSWORD, + TRANS_SYNC_EXT, TRANS_BUTT }; } // namespace OHOS::DistributedKv diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index c536a468e861be6447cb3ff4403a6011629784e5..16168dfc8535436523fc92bc0b544eb242de5dee 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -49,6 +49,7 @@ public: const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) = 0; virtual Status Delete(const AppId &appId, const StoreId &storeId) = 0; virtual Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; + virtual Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; virtual Status RegisterSyncCallback(const AppId &appId, sptr callback) = 0; virtual Status UnregisterSyncCallback(const AppId &appId) = 0; virtual Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) = 0; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index 1efb48a4e19610815e51c01de5aefcf35cfcbd06..0739491246c8dff04ba45542ae1a8855b46a59c6 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -36,6 +36,7 @@ public: const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId) override; Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback(const AppId &appId, sptr callback) override; Status UnregisterSyncCallback(const AppId &appIdd) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index cb5d44ed689744d3d972bcf0a7d01f32f3eff130..2ba7f5c315560658aff31f7a71b277bc17a26c21 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -57,6 +57,7 @@ public: Status SubscribeKvStore(SubscribeType type, std::shared_ptr observer) override; Status UnSubscribeKvStore(SubscribeType type, std::shared_ptr observer) override; Status Get(const Key &key, Value &value) override; + Status Get(const Key &key, const std::string &networkId, Value &value) override; Status GetEntries(const Key &prefix, std::vector &entries) const override; Status GetEntries(const DataQuery &query, std::vector &entries) const override; Status GetResultSet(const Key &prefix, std::shared_ptr &resultSet) const override; @@ -94,30 +95,36 @@ protected: std::shared_ptr TakeOut(uint32_t &realType, std::shared_ptr observer); private: + using Time = ExecutorPool::Time; + using Duration = ExecutorPool::Duration; + static constexpr size_t MAX_VALUE_LENGTH = 4 * 1024 * 1024; static constexpr size_t MAX_OBSERVER_SIZE = 8; + static constexpr Duration SYNC_DURATION = std::chrono::seconds(60); + static constexpr int32_t INTERVAL = 500; // ms Status GetResultSet(const DBQuery &query, std::shared_ptr &resultSet) const; Status GetEntries(const DBQuery &query, std::vector &entries) const; Status RetryWithCheckPoint(std::function lambda); std::function BridgeReleaser(); Status DoSync(const SyncInfo &syncInfo, std::shared_ptr observer); + Status DoSyncExt(const SyncInfo &syncInfo, std::shared_ptr observer); Status DoClientSync(const SyncInfo &syncInfo, std::shared_ptr observer); void DoAutoSync(); void Register(); bool autoSync_ = false; bool isClientSync_ = false; - int32_t ref_ = 1; mutable std::shared_mutex rwMutex_; const Convertor &convertor_; std::string appId_; std::string storeId_; + int32_t ref_ = 1; uint32_t roleType_ = 0; + uint64_t taskId_ = 0; std::shared_ptr dbStore_ = nullptr; std::shared_ptr syncObserver_ = nullptr; ConcurrentMap>> observers_; - static constexpr int32_t INTERVAL = 500; // ms - uint64_t taskId_ = 0; + ConcurrentMap> timePoints_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index 37e468eafceab5eb1cfb204966750fd661f1ddae..d8713b7186bbee0de9e247507f75e4d0bd48c314 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -164,6 +164,18 @@ Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const return static_cast(status); } +Status KVDBServiceClient::SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +{ + MessageParcel reply; + int32_t status = IPC_SEND(static_cast(KVDBServiceInterfaceCode::TRANS_SYNC_EXT), reply, appId, + storeId, syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query); + if (status != SUCCESS) { + ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, sequenceId:%{public}" PRIu64, + status, appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(), syncInfo.seqId); + } + return static_cast(status); +} + Status KVDBServiceClient::RegisterSyncCallback(const AppId &appId, sptr callback) { MessageParcel reply; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index 254bddf9e6a64efac4a06afe806d0fd85d096126..c16df6c6b5c28caea4eaecf47575e1f343b62368 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -330,6 +330,49 @@ Status SingleStoreImpl::Get(const Key &key, Value &value) return status; } +Status SingleStoreImpl::Get(const Key &key, const std::string &networkId, Value &value) +{ + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + auto clientUuid = DevManager::GetInstance().ToUUID(networkId); + if (clientUuid.empty()) { + return INVALID_ARGUMENT; + } + auto status = Get(key, value); + if (status != NOT_FOUND) { + return status; + } + { + std::shared_lock lock(rwMutex_); + auto watermark = dbStore_->GetWatermarkInfo(clientUuid); + if (StoreUtil::ConvertStatus(watermark.first) != SUCCESS + || (watermark.second.sendMark != 0 && watermark.second.receiveMark != 0)) { + ZLOGD("Do not need sync, dbStatus:%{public}d", watermark.first); + return status; + } + } + timePoints_.Compute(clientUuid, [this, &networkId, &status](const auto &key, auto &value) { + auto now = std::chrono::steady_clock::now(); + if (value.first != 0 && now < value.second) { + status = SYNC_ACTIVATED; + return true; + } + KVDBService::SyncInfo syncInfo; + syncInfo.seqId = StoreUtil::GenSequenceId(); + syncInfo.devices = { networkId }; + auto result = DoSyncExt(syncInfo, nullptr); + if (result != SUCCESS) { + ZLOGE("sync ext failed, result:%{public}d networkId:%{public}s app:%{public}s store:%{public}s", result, + StoreUtil::Anonymous(networkId).c_str(), appId_.c_str(), StoreUtil::Anonymous(storeId_).c_str()); + status = ERROR; + return false; + } + value.first = syncInfo.seqId; + value.second = now + SYNC_DURATION; + return true; + }); + return status; +} + Status SingleStoreImpl::GetEntries(const Key &prefix, std::vector &entries) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); @@ -614,6 +657,7 @@ int32_t SingleStoreImpl::Close(bool isForce) return ref_; } + timePoints_.Clear(); observers_.Clear(); syncObserver_->Clean(); std::unique_lock lock(rwMutex_); @@ -773,6 +817,9 @@ Status SingleStoreImpl::GetEntries(const DBQuery &query, std::vector &ent Status SingleStoreImpl::DoClientSync(const SyncInfo &syncInfo, std::shared_ptr observer) { auto complete = [observer](const std::map &devicesMap) { + if (observer == nullptr) { + return; + } std::map result; for (auto &[key, dbStatus] : devicesMap) { result[key] = StoreUtil::ConvertStatus(dbStatus); @@ -824,6 +871,26 @@ Status SingleStoreImpl::DoSync(const SyncInfo &syncInfo, std::shared_ptr observer) +{ + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + auto syncAgent = service->GetSyncAgent({ appId_ }); + if (syncAgent == nullptr) { + ZLOGE("failed! invalid agent app:%{public}s store:%{public}s!", + appId_.c_str(), StoreUtil::Anonymous(storeId_).c_str()); + return ILLEGAL_STATE; + } + syncAgent->AddSyncCallback(observer, syncInfo.seqId); + auto status = service->SyncExt({ appId_ }, { storeId_ }, syncInfo); + if (status != Status::SUCCESS) { + syncAgent->DeleteSyncCallback(syncInfo.seqId); + } + return status; +} + void SingleStoreImpl::DoAutoSync() { if (!autoSync_) { diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp index b5c404a5220b74debfab26469fd1b8ad5daeeb7f..c7d209765fa7325ec30cc10e3ac85166d3cb1241 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp @@ -20,13 +20,16 @@ #include #include "log_print.h" #include "types.h" +#include "acl.h" namespace OHOS::DistributedKv { +using namespace DATABASE_UTILS; constexpr mode_t DEFAULT_UMASK = 0002; constexpr int32_t HEAD_SIZE = 3; constexpr int32_t END_SIZE = 3; constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; constexpr const char *REPLACE_CHAIN = "***"; constexpr const char *DEFAULT_ANONYMOUS = "******"; +constexpr int32_t SERVICE_GID = 3012; std::atomic StoreUtil::sequenceId_ = 0; StoreUtil::DBSecurity StoreUtil::GetDBSecurity(int32_t secLevel) { @@ -163,6 +166,9 @@ bool StoreUtil::InitPath(const std::string &path) ZLOGE("mkdir error:%{public}d, path:%{public}s", errno, path.c_str()); return false; } + Acl acl(path); + acl.SetDefaultUser(getuid(), Acl::R_RIGHT | Acl::W_RIGHT); + acl.SetDefaultGroup(SERVICE_GID, Acl::R_RIGHT | Acl::W_RIGHT); return true; } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn index e067f62f959f7557afe80bdcf061d7a33a3c3043..adc18d6d2bb4a6b3d69af90e9f79a80e3469cfa3 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn @@ -88,6 +88,7 @@ ohos_source_set("kvdb_src_file") { configs = [ ":module_private_config" ] deps = [ + "../../../../databaseutils:database_utils", "../../../../interfaces/innerkits/distributeddatamgr:distributeddata_mgr", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp:devicemanagersdk", diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index a39069d6eebec2a0831f8e953604d917626b8d6c..a15e33c971af30db3bbb5d80d43e9a476efccc9d 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -155,6 +155,11 @@ HWTEST_F(SingleStoreImplTest, Put, TestSize.Level0) status = kvStore_->Get({ "Put Test" }, value); ASSERT_EQ(status, SUCCESS); ASSERT_EQ(value.ToString(), "Put2 Value"); + Value value1; + status = kvStore_->Get({ "Put Test" }, "networkId", value1); + ASSERT_EQ(status, INVALID_ARGUMENT); + status = kvStore_->Get({ "Put Test" }, "", value1); + ASSERT_EQ(status, INVALID_ARGUMENT); } /** diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/include/uv_queue.h b/kv_store/frameworks/jskitsimpl/distributeddata/include/uv_queue.h index b5b96ea7426f6ec2b288995d88cf193c902c4638..43f6ff6cb088782a51879c88676a1839bf6d9e05 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/include/uv_queue.h +++ b/kv_store/frameworks/jskitsimpl/distributeddata/include/uv_queue.h @@ -31,6 +31,7 @@ public: napi_env GetEnv(); void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator()); private: + static void Work(uv_work_t* work, int uvStatus); struct UvEntry { napi_env env; NapiCallbackGetter callback; diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp index 095f2d6c99fb63581a22b20f42f0dec062f768e9..2aae9bc3cc41f795f1507b54ad6e89438e6cc337 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp @@ -937,6 +937,7 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, DistributedKv::Options CHECK_RETURN(status == napi_ok, "get encrypt param failed", napi_invalid_arg); status = GetNamedProperty(env, in, "backup", options.backup, true); CHECK_RETURN(status == napi_ok, "get backup param failed", napi_invalid_arg); + options.autoSync = false; status = GetNamedProperty(env, in, "autoSync", options.autoSync, true); CHECK_RETURN(status == napi_ok, "get autoSync param failed", napi_invalid_arg); diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp index 53d07bd79c3f2ecc80f11551762dfffc643c3d13..a59535c7054298a44d388b88389f7d7c01e15cfc 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp @@ -115,7 +115,7 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, delete actx; }, reinterpret_cast(aCtx), &aCtx->work); - auto status = napi_queue_async_work(env, aCtx->work); + auto status = napi_queue_async_work_with_qos(env, aCtx->work, napi_qos_user_initiated); if (status != napi_ok) { napi_get_undefined(env, &promise); delete aCtx; @@ -154,4 +154,4 @@ void NapiQueue::GenerateOutput(AsyncContext &ctx, napi_value output) napi_call_function(ctx.env, nullptr, callback, RESULT_ALL, result, &callbackResult); } } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp index a54641eff80b4cd8e007123def36d78489526a95..76e9038aab8cc54d8230df576d0fb4b39a8d960b 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp @@ -46,41 +46,55 @@ void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) return; } work->data = new UvEntry{ env_, getter, std::move(genArgs) }; - uv_queue_work( - loop_, work, [](uv_work_t* work) {}, - [](uv_work_t* work, int uvstatus) { - std::shared_ptr entry(static_cast(work->data), [work](UvEntry *data) { - delete data; - delete work; - }); - napi_handle_scope scope = nullptr; - napi_open_handle_scope(entry->env, &scope); - napi_value method = entry->callback(entry->env); - if (method == nullptr) { - ZLOGE("the callback is invalid, maybe is cleared!"); - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - return ; - } - int argc = 0; - napi_value argv[ARGC_MAX] = { nullptr }; - if (entry->args) { - argc = ARGC_MAX; - entry->args(entry->env, argc, argv); - } - ZLOGD("queue uv_after_work_cb"); - napi_value global = nullptr; - napi_get_global(entry->env, &global); - napi_value result; - napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); - if (status != napi_ok) { - ZLOGE("notify data change failed status:%{public}d.", status); - } - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - }); + if (work->data == nullptr) { + ZLOGE("no memory for UvEntry"); + delete work; + work = nullptr; + return; + } + int retVal = uv_queue_work( + loop_, work, [](uv_work_t* work) {}, UvQueue::Work); + if (retVal != 0) { + delete (reinterpret_cast(work->data)); + work->data = nullptr; + delete work; + work = nullptr; + } +} + +void UvQueue::Work(uv_work_t* work, int uvStatus) +{ + std::shared_ptr entry(static_cast(work->data), [work](UvEntry* data) { + delete data; + delete work; + }); + napi_handle_scope scope = nullptr; + napi_open_handle_scope(entry->env, &scope); + napi_value method = entry->callback(entry->env); + if (method == nullptr) { + ZLOGE("the callback is invalid, maybe is cleared!"); + if (scope != nullptr) { + napi_close_handle_scope(entry->env, scope); + } + return; + } + int argc = 0; + napi_value argv[ARGC_MAX] = { nullptr }; + if (entry->args) { + argc = ARGC_MAX; + entry->args(entry->env, argc, argv); + } + ZLOGD("queue uv_after_work_cb"); + napi_value global = nullptr; + napi_get_global(entry->env, &global); + napi_value result; + napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); + if (status != napi_ok) { + ZLOGE("notify data change failed status:%{public}d.", status); + } + if (scope != nullptr) { + napi_close_handle_scope(entry->env, scope); + } } napi_env UvQueue::GetEnv() diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h index f467a763d997fc263a15308632c0c3f65209fd7c..67da9bd6f23207a879361565dd62d07e27435fc5 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h @@ -31,6 +31,7 @@ public: napi_env GetEnv(); void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator()); private: + static void Work(uv_work_t* work, int uvStatus); struct UvEntry { napi_env env; NapiCallbackGetter callback; diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp index 50baa878d6db8b9cc65508f795d2d93cd41e32be..3bec6fa97c9045bd06b3114bca48fa96d7ace5a5 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp @@ -1008,6 +1008,7 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, DistributedKv::O ASSERT(statusMsg.status == napi_ok, "get encrypt param failed", statusMsg); statusMsg = GetNamedProperty(env, in, "backup", options.backup, true); ASSERT(statusMsg.status == napi_ok, "get backup param failed", statusMsg); + options.autoSync = false; statusMsg = GetNamedProperty(env, in, "autoSync", options.autoSync, true); ASSERT(statusMsg.status == napi_ok, "get autoSync param failed", statusMsg); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp index c37c898b2a6ccd6d4cee2a927342d5095935bb8d..e58961f25818f8fdb23af1f4a10de9eeb051eec5 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp @@ -115,7 +115,7 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, delete actx; }, reinterpret_cast(aCtx), &aCtx->work); - auto status = napi_queue_async_work(env, aCtx->work); + auto status = napi_queue_async_work_with_qos(env, aCtx->work, napi_qos_user_initiated); if (status != napi_ok) { napi_get_undefined(env, &promise); delete aCtx; @@ -162,4 +162,4 @@ void NapiQueue::GenerateOutput(AsyncContext &ctx, napi_value output) napi_call_function(ctx.env, nullptr, callback, RESULT_ALL, result, &callbackResult); } } -} // namespace OHOS::DistributedKVStore +} // namespace OHOS::DistributedKVStore \ No newline at end of file diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp index 2397918dee214236dae8cdbe54ed01dca5cf4880..240e611f0db2de221e3567bbd91cb9dfc1f6ea83 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp @@ -46,41 +46,55 @@ void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) return; } work->data = new UvEntry{ env_, getter, std::move(genArgs) }; - uv_queue_work( - loop_, work, [](uv_work_t* work) {}, - [](uv_work_t* work, int uvstatus) { - std::shared_ptr entry(static_cast(work->data), [work](UvEntry *data) { - delete data; - delete work; - }); - napi_handle_scope scope = nullptr; - napi_open_handle_scope(entry->env, &scope); - napi_value method = entry->callback(entry->env); - if (method == nullptr) { - ZLOGE("the callback is invalid, maybe is cleared!"); - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - return ; - } - int argc = 0; - napi_value argv[ARGC_MAX] = { nullptr }; - if (entry->args) { - argc = ARGC_MAX; - entry->args(entry->env, argc, argv); - } - ZLOGD("queue uv_after_work_cb"); - napi_value global = nullptr; - napi_get_global(entry->env, &global); - napi_value result; - napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); - if (status != napi_ok) { - ZLOGE("notify data change failed status:%{public}d.", status); - } - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - }); + if (work->data == nullptr) { + ZLOGE("no memory for UvEntry"); + delete work; + work = nullptr; + return; + } + int retVal = uv_queue_work( + loop_, work, [](uv_work_t* work) {}, UvQueue::Work); + if (retVal != 0) { + delete (reinterpret_cast(work->data)); + work->data = nullptr; + delete work; + work = nullptr; + } +} + +void UvQueue::Work(uv_work_t* work, int uvStatus) +{ + std::shared_ptr entry(static_cast(work->data), [work](UvEntry* data) { + delete data; + delete work; + }); + napi_handle_scope scope = nullptr; + napi_open_handle_scope(entry->env, &scope); + napi_value method = entry->callback(entry->env); + if (method == nullptr) { + ZLOGE("the callback is invalid, maybe is cleared!"); + if (scope != nullptr) { + napi_close_handle_scope(entry->env, scope); + } + return; + } + int argc = 0; + napi_value argv[ARGC_MAX] = { nullptr }; + if (entry->args) { + argc = ARGC_MAX; + entry->args(entry->env, argc, argv); + } + ZLOGD("queue uv_after_work_cb"); + napi_value global = nullptr; + napi_get_global(entry->env, &global); + napi_value result; + napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); + if (status != napi_ok) { + ZLOGE("notify data change failed status:%{public}d.", status); + } + if (scope != nullptr) { + napi_close_handle_scope(entry->env, scope); + } } napi_env UvQueue::GetEnv() diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h index 29693f4b8e8185d2d4b1c0f6c59960871a9748c1..0710c58a4cec5e587b1b1601a0b4fc9512375889 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h @@ -33,6 +33,7 @@ public: static constexpr const char *REFERENCE_FIELD = "#_reference"; static constexpr const char *VERSION_FIELD = "#_version"; static constexpr const char *ERROR_FIELD = "#_error"; + static constexpr const char *SHARING_RESOURCE_FIELD = "#_sharing_resource"; static constexpr const char *ROW_ID_FIELD_NAME = "rowid"; static constexpr const char *ASSET = "asset"; static constexpr const char *ASSETS = "assets"; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h index 406c1321289759de2a26c20d2a41b42064c519da..2775893abecef39db12a01aa13839e8a072ac1db 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h @@ -108,6 +108,10 @@ public: static bool IsRecordError(const VBucket &record); static bool IsRecordIgnored(const VBucket &record); + + static std::string GenerateHashLabel(const DBInfo &dbInfo); + + static uint64_t EraseBit(uint64_t origin, uint64_t eraseBit); private: static void InsertNodesByScore(const std::map> &graph, const std::vector &generateNodes, const std::map &scoreGraph, diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h index 892026fa416f1f79efb5f793af0b530a0bf58740..41efc2ca4b2c5c7d0967d6d6e2b28ea380c113c6 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h @@ -26,6 +26,7 @@ public: static constexpr size_t MAX_BATCH_SIZE = 128; static constexpr size_t MAX_DEV_LENGTH = 128; static constexpr size_t MAX_TRANSACTION_ENTRY_SIZE = 128; + static constexpr size_t MAX_TRANSACTION_KEY_VALUE_LENS = 512 * 1024 * 1024; // 512M static constexpr size_t MAX_DATA_DIR_LENGTH = 512; @@ -163,6 +164,7 @@ public: static constexpr const char *LOG_TABLE_VERSION_5 = "5.0"; static constexpr const char *LOG_TABLE_VERSION_5_1 = "5.01"; static constexpr const char *LOG_TABLE_VERSION_5_2 = "5.02"; // fix failure caused by comparing NULL using <> + static constexpr const char *LOG_TABLE_VERSION_5_3 = "5.03"; // add sharing_resource field static const std::string LOG_TABLE_VERSION_CURRENT; static const std::string LOG_TABLE_VERSION_KEY; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h index 42606c2b56ab77d417b028941904e944447c29ec..a1a001c4b6822a5a4dc566fec0c0035a4a715809 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h @@ -140,6 +140,8 @@ constexpr int E_TASK_PAUSED = (E_BASE + 119); // the task was paused, don't fini constexpr int E_CLOUD_VERSION_CONFLICT = (E_BASE + 120); // cloud failed to update version constexpr int E_CLOUD_RECORD_EXIST_CONFLICT = (E_BASE + 121); // record conflict when upload/download constexpr int E_REMOVE_ASSETS_FAILED = (E_BASE + 122); // remove local assets failed +constexpr int E_ABILITY_SYNC_FINISHED = (E_BASE + 123); // add at 108 version, use for machine check ability sync finish +constexpr int E_NEED_TIME_SYNC = (E_BASE + 124); // time sync has not done // Num 150+ is reserved for schema related errno, since it may be added regularly constexpr int E_JSON_PARSE_FAIL = (E_BASE + 150); // Parse json fail in grammatical level constexpr int E_JSON_INSERT_PATH_EXIST = (E_BASE + 151); // Path already exist before insert diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h index ab8f2b827ba49e3bce543142e45594f41c7c16e7..3169d9af621cc3232c5a7e93de83c729027f3856 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h @@ -173,5 +173,11 @@ enum class SortType { TIMESTAMP_ASC, TIMESTAMP_DESC }; + +struct DeviceTimeInfo { + Timestamp recordTime = 0; // info generate time + TimeOffset systemTimeOffset = 0; // raw system time offset + int64_t rtt = 0; +}; } // namespace DistributedDB #endif // DISTRIBUTEDDB_TYPES_H diff --git a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h index c972a42c8fb3b52b595633ed49cb55c7703c38d5..c4e275416c7c3cd40e9b16370f1e4b53f05ce716 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h @@ -23,6 +23,7 @@ #include "auto_launch.h" #include "auto_launch_export.h" #include "cloud/icloud_data_translate.h" +#include "db_info_handle.h" #include "icommunicator_aggregator.h" #include "iprocess_system_api_adapter.h" #include "ithread_pool.h" @@ -30,6 +31,7 @@ #include "kvdb_properties.h" #include "macro_utils.h" #include "notification_chain.h" +#include "query_sync_object.h" #include "types_export.h" namespace DistributedDB { @@ -146,6 +148,30 @@ public: virtual void StopTimeTickMonitorIfNeed() = 0; + virtual void SetDBInfoHandle(const std::shared_ptr &handle) = 0; + + virtual void NotifyDBInfos(const DeviceInfos &devInfos, const std::vector &dbInfos) = 0; + + virtual void RecordRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, + const QuerySyncObject &query) = 0; + + virtual void RemoveRemoteSubscribe(const DeviceID &deviceId) = 0; + + virtual void RemoveRemoteSubscribe(const DBInfo &dbInfo) = 0; + + virtual void RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId) = 0; + + virtual void RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, + const QuerySyncObject &query) = 0; + + virtual void GetSubscribeQuery(const DBInfo &dbInfo, + std::map> &subscribeQuery) = 0; + + virtual bool IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId, + const std::string &devInfo) = 0; + + virtual void SetRemoteOptimizeCommunication(const std::string &dev, bool optimize) = 0; + virtual void SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) = 0; virtual int TranslateDeviceId(const std::string &deviceId, @@ -162,6 +188,14 @@ public: virtual int AssetsToBlob(const Assets &assets, std::vector &blob) = 0; virtual int BlobToAsset(const std::vector &blob, Asset &asset) = 0; virtual int BlobToAssets(const std::vector &blob, Assets &assets) = 0; + + virtual std::pair GetDeviceTimeInfo(const std::string &device) const = 0; + virtual void SetDeviceTimeInfo(const std::string &device, const DeviceTimeInfo &deviceTimeInfo) = 0; + virtual void ClearDeviceTimeInfo(const std::string &device) = 0; + virtual void ClearAllDeviceTimeInfo() = 0; + virtual void RecordAllTimeChange() = 0; + virtual void ResetDBTimeChangeStatus(const std::vector &dbId) = 0; + virtual bool CheckDBTimeChange(const std::vector &dbId) = 0; protected: RuntimeContext() = default; virtual ~RuntimeContext() {} diff --git a/kv_store/frameworks/libs/distributeddb/common/include/version.h b/kv_store/frameworks/libs/distributeddb/common/include/version.h index 1429350dc8408be102a27ef304658571638f0916..8cfc4c787df212f2d07a0ab24b2d30fc4b0abb37 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/version.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/version.h @@ -39,9 +39,15 @@ constexpr uint32_t SOFTWARE_VERSION_RELEASE_4_0 = SOFTWARE_VERSION_BASE + 4; // constexpr uint32_t SOFTWARE_VERSION_RELEASE_5_0 = SOFTWARE_VERSION_BASE + 5; // 5 for fifth released version constexpr uint32_t SOFTWARE_VERSION_RELEASE_6_0 = SOFTWARE_VERSION_BASE + 6; // 6 for sixth released version // check both device has security label at 107 -constexpr uint32_t SOFTWARE_VERSION_RELEASE_7_0 = SOFTWARE_VERSION_BASE + 7; // 7 for sixth released version +constexpr uint32_t SOFTWARE_VERSION_RELEASE_7_0 = SOFTWARE_VERSION_BASE + 7; // 7 for seventh released version +// kv ability sync with 2 packet at 108 +constexpr uint32_t SOFTWARE_VERSION_RELEASE_8_0 = SOFTWARE_VERSION_BASE + 8; // 8 for eighth released version +// 109 version add field in request packet +// add schema version in ability request +// add schema version, system time offset, sender local time offset in data request +constexpr uint32_t SOFTWARE_VERSION_RELEASE_9_0 = SOFTWARE_VERSION_BASE + 9; // 9 for ninth released version constexpr uint32_t SOFTWARE_VERSION_EARLIEST = SOFTWARE_VERSION_RELEASE_1_0; -constexpr uint32_t SOFTWARE_VERSION_CURRENT = SOFTWARE_VERSION_RELEASE_7_0; +constexpr uint32_t SOFTWARE_VERSION_CURRENT = SOFTWARE_VERSION_RELEASE_9_0; constexpr int VERSION_INVALID = INT32_MAX; // Storage Related Version diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp index a9cf311f0b6c71f73fd0dc9ca03a53689f32e958..f7950a032c7277ccdd6be834d2deb759169dfe40 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -620,4 +620,17 @@ bool DBCommon::IsRecordIgnored(const VBucket &record) auto status = std::get(record.at(CloudDbConstant::ERROR_FIELD)); return status == static_cast(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); } + +std::string DBCommon::GenerateHashLabel(const DBInfo &dbInfo) +{ + if (dbInfo.syncDualTupleMode) { + return DBCommon::TransferHashString(dbInfo.appId + "-" + dbInfo.storeId); + } + return DBCommon::TransferHashString(dbInfo.userId + "-" + dbInfo.appId + "-" + dbInfo.storeId); +} + +uint64_t DBCommon::EraseBit(uint64_t origin, uint64_t eraseBit) +{ + return origin & (~eraseBit); +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp index 99b81fe0c0f96d3d5aa34a44986e64530a0fdc5d..4bad00ae369a069f4202f361bb14fc3d48560c0e 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp @@ -75,7 +75,7 @@ const std::string DBConstant::LOG_POSTFIX = "_log"; const std::string DBConstant::LOG_TABLE_VERSION_1 = "1.0"; const std::string DBConstant::LOG_TABLE_VERSION_2 = "2.0"; -const std::string DBConstant::LOG_TABLE_VERSION_CURRENT = LOG_TABLE_VERSION_5_2; +const std::string DBConstant::LOG_TABLE_VERSION_CURRENT = LOG_TABLE_VERSION_5_3; const std::string DBConstant::LOG_TABLE_VERSION_KEY = "log_table_version"; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp index d21d40ad72d84268a6907a48694cc6db30405b5b..e5a6fc9997721d9cb7b4ff970316880e2e36b38e 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -36,7 +36,9 @@ RuntimeContextImpl::RuntimeContextImpl() timeTickMonitor_(nullptr), systemApiAdapter_(nullptr), lockStatusObserver_(nullptr), - currentSessionId_(1) + currentSessionId_(1), + dbStatusAdapter_(nullptr), + subscribeRecorder_(nullptr) { } @@ -63,6 +65,8 @@ RuntimeContextImpl::~RuntimeContextImpl() delete lockStatusObserver_; lockStatusObserver_ = nullptr; userChangeMonitor_ = nullptr; + dbStatusAdapter_ = nullptr; + subscribeRecorder_ = nullptr; SetThreadPool(nullptr); } @@ -100,6 +104,7 @@ int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter) int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator) { outAggregator = nullptr; + const std::shared_ptr statusAdapter = GetDBStatusAdapter(); std::lock_guard lock(communicatorLock_); if (communicatorAggregator_ != nullptr) { outAggregator = communicatorAggregator_; @@ -117,7 +122,7 @@ int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outA return -E_OUT_OF_MEMORY; } - int errCode = communicatorAggregator_->Initialize(adapter_); + int errCode = communicatorAggregator_->Initialize(adapter_, statusAdapter); if (errCode != E_OK) { LOGE("CommunicatorAggregator init failed, err = %d!", errCode); RefObject::KillAndDecObjRef(communicatorAggregator_); @@ -781,6 +786,144 @@ void RuntimeContextImpl::StopTimeTickMonitorIfNeed() LOGD("[RuntimeContext] TimeTickMonitor can not stop because listener is not empty"); } +void RuntimeContextImpl::SetDBInfoHandle(const std::shared_ptr &handle) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr) { + dbStatusAdapter->SetDBInfoHandle(handle); + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RemoveAllSubscribe(); + } +} + +void RuntimeContextImpl::NotifyDBInfos(const DeviceInfos &devInfos, const std::vector &dbInfos) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr) { + dbStatusAdapter->NotifyDBInfos(devInfos, dbInfos); + } +} + +std::shared_ptr RuntimeContextImpl::GetDBStatusAdapter() +{ + std::lock_guard autoLock(statusAdapterMutex_); + if (dbStatusAdapter_ == nullptr) { + dbStatusAdapter_ = std::make_unique(); + } + if (dbStatusAdapter_ == nullptr) { + LOGE("[RuntimeContextImpl] DbStatusAdapter create failed!"); + } + return dbStatusAdapter_; +} + +void RuntimeContextImpl::RecordRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, + const QuerySyncObject &query) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RecordSubscribe(dbInfo, deviceId, query); + } +} + +void RuntimeContextImpl::RemoveRemoteSubscribe(const DeviceID &deviceId) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RemoveRemoteSubscribe(deviceId); + } +} + +void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RemoveRemoteSubscribe(dbInfo); + } +} + +void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RemoveRemoteSubscribe(dbInfo, deviceId); + } +} + +void RuntimeContextImpl::RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, + const QuerySyncObject &query) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->RemoveRemoteSubscribe(dbInfo, deviceId, query); + } +} + +void RuntimeContextImpl::GetSubscribeQuery(const DBInfo &dbInfo, + std::map> &subscribeQuery) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter != nullptr && dbStatusAdapter->IsSendLabelExchange()) { + return; + } + std::shared_ptr subscribeRecorder = GetSubscribeRecorder(); + if (subscribeRecorder != nullptr) { + subscribeRecorder->GetSubscribeQuery(dbInfo, subscribeQuery); + } +} + +std::shared_ptr RuntimeContextImpl::GetSubscribeRecorder() +{ + std::lock_guard autoLock(subscribeRecorderMutex_); + if (subscribeRecorder_ == nullptr) { + subscribeRecorder_ = std::make_unique(); + } + if (subscribeRecorder_ == nullptr) { + LOGE("[RuntimeContextImpl] SubscribeRecorder create failed!"); + } + return subscribeRecorder_; +} + +bool RuntimeContextImpl::IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId, + const std::string &devInfo) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter == nullptr) { + return true; + } + return dbStatusAdapter->IsNeedAutoSync(userId, appId, storeId, devInfo); +} + +void RuntimeContextImpl::SetRemoteOptimizeCommunication(const std::string &dev, bool optimize) +{ + std::shared_ptr dbStatusAdapter = GetDBStatusAdapter(); + if (dbStatusAdapter == nullptr) { + return; + } + dbStatusAdapter->SetRemoteOptimizeCommunication(dev, optimize); +} + void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) { std::lock_guard autoLock(translateToDeviceIdLock_); @@ -999,4 +1142,56 @@ int RuntimeContextImpl::BlobToAssets(const std::vector &blob, Assets &a assets = dataTranslate_->BlobToAssets(blob); return E_OK; } + +std::pair RuntimeContextImpl::GetDeviceTimeInfo(const std::string &device) const +{ + std::pair res; + auto &[errCode, info] = res; + std::lock_guard autoLock(deviceTimeInfoLock_); + if (deviceTimeInfos_.find(device) == deviceTimeInfos_.end()) { + errCode = -E_NOT_FOUND; + } else { + info = deviceTimeInfos_.at(device); + errCode = E_OK; + } + return res; +} + +void RuntimeContextImpl::SetDeviceTimeInfo(const std::string &device, const DeviceTimeInfo &deviceTimeInfo) +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + deviceTimeInfos_[device] = deviceTimeInfo; +} + +void RuntimeContextImpl::ClearDeviceTimeInfo(const std::string &device) +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + deviceTimeInfos_.erase(device); +} + +void RuntimeContextImpl::ClearAllDeviceTimeInfo() +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + deviceTimeInfos_.clear(); +} + +void RuntimeContextImpl::RecordAllTimeChange() +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + for (auto &item : dbTimeChange_) { + item.second = true; + } +} + +void RuntimeContextImpl::ResetDBTimeChangeStatus(const std::vector &dbId) +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + dbTimeChange_[dbId] = false; +} + +bool RuntimeContextImpl::CheckDBTimeChange(const std::vector &dbId) +{ + std::lock_guard autoLock(deviceTimeInfoLock_); + return dbTimeChange_[dbId]; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h index c3afcf9800b681b00b75f91e4be00a247af7e356..72d8f31572b32f1f728fb7c8acd04c890b8b9df1 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h @@ -21,10 +21,12 @@ #include #include "auto_launch.h" +#include "db_status_adapter.h" #include "evloop/src/ievent.h" #include "evloop/src/ievent_loop.h" #include "icommunicator_aggregator.h" #include "lock_status_observer.h" +#include "subscribe_recorder.h" #include "task_pool.h" #include "time_tick_monitor.h" #include "user_change_monitor.h" @@ -131,6 +133,28 @@ public: void StopTimeTickMonitorIfNeed() override; + void SetDBInfoHandle(const std::shared_ptr &handle) override; + + void NotifyDBInfos(const DeviceInfos &devInfos, const std::vector &dbInfos) override; + + void RecordRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, const QuerySyncObject &query) override; + + void RemoveRemoteSubscribe(const DeviceID &deviceId) override; + + void RemoveRemoteSubscribe(const DBInfo &dbInfo) override; + + void RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId) override; + + void RemoveRemoteSubscribe(const DBInfo &dbInfo, const DeviceID &deviceId, const QuerySyncObject &query) override; + + void GetSubscribeQuery(const DBInfo &dbInfo, + std::map> &subscribeQuery) override; + + bool IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId, + const std::string &devInfo) override; + + void SetRemoteOptimizeCommunication(const std::string &dev, bool optimize) override; + void SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) override; int TranslateDeviceId(const std::string &deviceId, @@ -147,6 +171,14 @@ public: int AssetsToBlob(const Assets &assets, std::vector &blob) override; int BlobToAsset(const std::vector &blob, Asset &asset) override; int BlobToAssets(const std::vector &blob, Assets &assets) override; + + std::pair GetDeviceTimeInfo(const std::string &device) const override; + void SetDeviceTimeInfo(const std::string &device, const DeviceTimeInfo &deviceTimeInfo) override; + void ClearDeviceTimeInfo(const std::string &device) override; + void ClearAllDeviceTimeInfo() override; + void RecordAllTimeChange() override; + void ResetDBTimeChangeStatus(const std::vector &dbId) override; + bool CheckDBTimeChange(const std::vector &dbId) override; private: static constexpr int MAX_TP_THREADS = 10; // max threads of the task pool. static constexpr int MIN_TP_THREADS = 1; // min threads of the task pool. @@ -155,6 +187,8 @@ private: int PrepareLoop(IEventLoop *&loop); int PrepareTaskPool(); int AllocTimerId(IEvent *evTimer, TimerId &timerId); + std::shared_ptr GetDBStatusAdapter(); + std::shared_ptr GetSubscribeRecorder(); int ScheduleTaskByThreadPool(const TaskAction &task) const __attribute__((no_sanitize("cfi"))); @@ -221,6 +255,12 @@ private: mutable std::shared_mutex permissionConditionLock_; PermissionConditionCallback permissionConditionCallback_; + mutable std::mutex statusAdapterMutex_; + std::shared_ptr dbStatusAdapter_; + + mutable std::mutex subscribeRecorderMutex_; + std::shared_ptr subscribeRecorder_; + mutable std::mutex translateToDeviceIdLock_; TranslateToDeviceIdCallback translateToDeviceIdCallback_; std::map> deviceIdCache_; // cache > @@ -234,6 +274,10 @@ private: mutable std::shared_mutex dataTranslateLock_; std::shared_ptr dataTranslate_; + + mutable std::mutex deviceTimeInfoLock_; + std::map deviceTimeInfos_; + std::map, bool> dbTimeChange_; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h index 9cf86ec70e27a4e5bd91fe23112284b12c404c43..8b43fae52b9ff10b12194d268ede2e070a4e5a39 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h @@ -54,7 +54,7 @@ public: DISABLE_COPY_ASSIGN_MOVE(CommunicatorAggregator); // See ICommunicatorAggregator for detail - int Initialize(IAdapter *inAdapter) override; + int Initialize(IAdapter *inAdapter, const std::shared_ptr &statusAdapter) override; // Must not call any other functions if Finalize had been called. In fact, Finalize has no chance to be called. void Finalize() override; @@ -135,6 +135,12 @@ private: // Record the protocol version of remote target. void SetRemoteCommunicatorVersion(const std::string &target, uint16_t version); + void OnRemoteDBStatusChange(const std::string &devInfo, const std::vector &dbInfos); + + void NotifyConnectChange(const std::string &srcTarget, const std::map &changedLabels); + + void RegDBChangeCallback(); + void InitSendThread(); void SendOnceData(); @@ -196,6 +202,8 @@ private: Finalizer onConnectFinalizer_; mutable std::mutex onConnectMutex_; + std::shared_ptr dbStatusAdapter_; + std::atomic useExclusiveThread_ = false; bool sendTaskStart_ = false; mutable std::mutex scheduleSendTaskMutex_; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/db_status_adapter.h b/kv_store/frameworks/libs/distributeddb/communicator/include/db_status_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..35b5cc3fe1c292f38ac3be0bfd6348d3a6cdf4c0 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/db_status_adapter.h @@ -0,0 +1,73 @@ +/* + * 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 DB_STATUS_ADAPTER_H +#define DB_STATUS_ADAPTER_H + +#include "db_info_handle.h" +#include +#include "macro_utils.h" + +namespace DistributedDB { +using RemoteDBChangeCallback = std::function &dbInfos)>; +using LocalDBChangeCallback = std::function; +using RemoteSupportChangeCallback = std::function; +class DBStatusAdapter { +public: + DBStatusAdapter(); + ~DBStatusAdapter() = default; + DISABLE_COPY_ASSIGN_MOVE(DBStatusAdapter); + + void SetDBInfoHandle(const std::shared_ptr &dbInfoHandle); + bool IsSupport(const std::string &devInfo); + int GetLocalDBInfos(std::vector &dbInfos); + void SetDBStatusChangeCallback(const RemoteDBChangeCallback &remote, const LocalDBChangeCallback &local, + const RemoteSupportChangeCallback &supportCallback); + void NotifyDBInfos(const DeviceInfos &devInfos, const std::vector &dbInfos); + void TargetOffline(const std::string &device); + bool IsNeedAutoSync(const std::string &userId, const std::string &appId, const std::string &storeId, + const std::string &devInfo); + void SetRemoteOptimizeCommunication(const std::string &dev, bool optimize); + bool IsSendLabelExchange(); +private: + std::shared_ptr GetDBInfoHandle() const; + bool LoadIntoCache(bool isLocal, const DeviceInfos &devInfos, const std::vector &dbInfos); + void ClearAllCache(); + void NotifyRemoteOffline(); + + static int GetLocalDeviceId(std::string &deviceId); + static bool IsLocalDeviceId(const std::string &deviceId); + static bool MergeDBInfos(const std::vector &srcDbInfos, std::vector &dstDbInfos); + mutable std::mutex handleMutex_; + std::shared_ptr dbInfoHandle_ = nullptr; + + mutable std::mutex callbackMutex_; + RemoteDBChangeCallback remoteCallback_; + LocalDBChangeCallback localCallback_; + RemoteSupportChangeCallback supportCallback_; + + mutable std::mutex localInfoMutex_; + std::vector localDBInfos_; + + mutable std::mutex remoteInfoMutex_; + std::map> remoteDBInfos_; // key: device uuid, value: all db which has notified + + mutable std::mutex supportMutex_; + bool localSendLabelExchange_; + bool cacheLocalSendLabelExchange_; + std::map remoteOptimizeInfo_; // key: device uuid, value: is support notified by user +}; +} +#endif // DB_STATUS_ADAPTER_H diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/icommunicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/communicator/include/icommunicator_aggregator.h index 06ae9e7c1e91e74188cf57540be44690eb309fe8..70ee63cf8f1b09bc74c00931df7a31a36c9f4145 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/icommunicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/icommunicator_aggregator.h @@ -18,6 +18,7 @@ #include #include "communicator_type_define.h" +#include "db_status_adapter.h" #include "iadapter.h" #include "ref_object.h" @@ -32,7 +33,7 @@ public: // The caller is the owner of inAdapter and responsible for manage its lifecycle. // The ICommunicatorAggregator is only the user of inAdapter // If Initialize fail, the ICommunicatorAggregator will rollback what had done to inAdapter so it can be reuse. - virtual int Initialize(IAdapter *inAdapter) = 0; + virtual int Initialize(IAdapter *inAdapter, const std::shared_ptr &statusAdapter) = 0; // Call this method after Initialize successfully and before destroy the ICommunicatorAggregator // Emphasize again : DO NOT CALL Finalize IF Initialize FAIL. diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/parse_result.h b/kv_store/frameworks/libs/distributeddb/communicator/include/parse_result.h index 99d0cebd6137e708a567e4d7fc116d7f5a4c7729..2186bbb9601ae5304df4913e3462b35b20c034bd 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/parse_result.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/parse_result.h @@ -47,6 +47,10 @@ public: { frameType_ = inFrameType; } + void SetSendLabelExchange(bool sendLabelExchange) + { + sendLabelExchange_ = sendLabelExchange; + } void SetFrameLen(uint32_t inFrameLen) { frameLen_ = inFrameLen; @@ -104,6 +108,10 @@ public: { return frameType_; } + bool IsSendLabelExchange() const + { + return sendLabelExchange_; + } uint32_t GetFrameLen() const { return frameLen_; @@ -154,6 +162,7 @@ private: uint8_t paddingLen_ = 0; bool isFragment_ = false; FrameType frameType_ = FrameType::INVALID_MAX_FRAME_TYPE; + bool sendLabelExchange_ = true; // For CommPhyOptHeader uint32_t frameLen_ = 0; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp index a5bfbd2c1eeda1cfa0cd2ceb63e4a355a5aa8cfd..2db196df70705548969f23e944d881afe74e66dd 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -52,7 +52,7 @@ CommunicatorAggregator::~CommunicatorAggregator() commLinker_ = nullptr; } -int CommunicatorAggregator::Initialize(IAdapter *inAdapter) +int CommunicatorAggregator::Initialize(IAdapter *inAdapter, const std::shared_ptr &statusAdapter) { if (inAdapter == nullptr) { return -E_INVALID_ARGS; @@ -64,7 +64,7 @@ int CommunicatorAggregator::Initialize(IAdapter *inAdapter) scheduler_.Initialize(); int errCode; - commLinker_ = new (std::nothrow) CommunicatorLinker(this); + commLinker_ = new (std::nothrow) CommunicatorLinker(this, statusAdapter); if (commLinker_ == nullptr) { errCode = -E_OUT_OF_MEMORY; goto ROLL_BACK; @@ -85,6 +85,8 @@ int CommunicatorAggregator::Initialize(IAdapter *inAdapter) shutdown_ = false; InitSendThread(); + dbStatusAdapter_ = statusAdapter; + RegDBChangeCallback(); return E_OK; ROLL_BACK: UnRegCallbackFromAdapter(); @@ -129,6 +131,7 @@ void CommunicatorAggregator::Finalize() commLinker_ = nullptr; retainer_.Finalize(); combiner_.Finalize(); + dbStatusAdapter_ = nullptr; } ICommunicator *CommunicatorAggregator::AllocCommunicator(uint64_t commLabel, int &outErrorNo) @@ -303,7 +306,12 @@ int CommunicatorAggregator::ScheduleSendTask(const std::string &dstTarget, Seria LOGE("[CommAggr][Create] Exit ok but discard since localSourceId zero, thread=%s.", GetThreadId().c_str()); return E_OK; // Returns E_OK here to indicate this buffer was accepted though discard immediately } - PhyHeaderInfo info{localSourceId_, incFrameId_.fetch_add(1, std::memory_order_seq_cst), inType}; + bool sendLabelExchange = true; + if (dbStatusAdapter_ != nullptr) { + sendLabelExchange = dbStatusAdapter_->IsSendLabelExchange(); + } + PhyHeaderInfo info{localSourceId_, incFrameId_.fetch_add(1, std::memory_order_seq_cst), inType, + sendLabelExchange}; int errCode = ProtocolProto::SetPhyHeader(inBuff, info); if (errCode != E_OK) { LOGE("[CommAggr][Create] Set phyHeader fail, thread=%s, errCode=%d", GetThreadId().c_str(), errCode); @@ -484,6 +492,9 @@ void CommunicatorAggregator::OnBytesReceive(const std::string &srcTarget, const // Update version of remote target SetRemoteCommunicatorVersion(srcTarget, packetResult.GetDbVersion()); + if (dbStatusAdapter_ != nullptr) { + dbStatusAdapter_->SetRemoteOptimizeCommunication(srcTarget, !packetResult.IsSendLabelExchange()); + } if (packetResult.GetFrameTypeInfo() == FrameType::EMPTY) { // Empty frame will never be fragmented LOGI("[CommAggr][Receive] Empty frame, just ignore in this version of distributeddb."); return; @@ -608,24 +619,7 @@ int CommunicatorAggregator::OnCommLayerFrameReceive(const std::string &srcTarget LOGE("[CommAggr][CommReceive] Receive LabelExchange Fail."); return errCode; } - if (!commLinker_->IsRemoteTargetOnline(srcTarget)) { - LOGW("[CommAggr][CommReceive] Receive LabelExchange from offline target=%s{private}.", srcTarget.c_str()); - for (const auto &entry : changedLabels) { - LOGW("[CommAggr][CommReceive] REMEMBER: label=%.3s, inOnline=%d.", VEC_TO_STR(entry.first), - entry.second); - } - return E_OK; - } - // Do target change notify - std::lock_guard commMapLockGuard(commMapMutex_); - for (auto &entry : changedLabels) { - // Ignore nonactivated communicator - if (commMap_.count(entry.first) != 0 && commMap_.at(entry.first).second) { - LOGI("[CommAggr][CommReceive] label=%.3s, srcTarget=%s{private}, isOnline=%d.", - VEC_TO_STR(entry.first), srcTarget.c_str(), entry.second); - commMap_.at(entry.first).first->OnConnectChange(srcTarget, entry.second); - } - } + NotifyConnectChange(srcTarget, changedLabels); } return E_OK; } @@ -763,6 +757,9 @@ void CommunicatorAggregator::UnRegCallbackFromAdapter() adapterHandle_->RegBytesReceiveCallback(nullptr, nullptr); adapterHandle_->RegTargetChangeCallback(nullptr, nullptr); adapterHandle_->RegSendableCallback(nullptr, nullptr); + if (dbStatusAdapter_ != nullptr) { + dbStatusAdapter_->SetDBStatusChangeCallback(nullptr, nullptr, nullptr); + } } void CommunicatorAggregator::GenerateLocalSourceId() @@ -874,6 +871,62 @@ std::shared_ptr CommunicatorAggregator::GetExtendHeaderHandl return adapterHandle_->GetExtendHeaderHandle(paramInfo); } +void CommunicatorAggregator::OnRemoteDBStatusChange(const std::string &devInfo, const std::vector &dbInfos) +{ + std::map changedLabels; + for (const auto &dbInfo: dbInfos) { + std::string label = DBCommon::GenerateHashLabel(dbInfo); + LabelType labelType(label.begin(), label.end()); + changedLabels[labelType] = dbInfo.isNeedSync; + } + if (commLinker_ != nullptr) { + commLinker_->UpdateOnlineLabels(devInfo, changedLabels); + } + NotifyConnectChange(devInfo, changedLabels); +} + +void CommunicatorAggregator::NotifyConnectChange(const std::string &srcTarget, + const std::map &changedLabels) +{ + if (commLinker_ != nullptr && !commLinker_->IsRemoteTargetOnline(srcTarget)) { + LOGW("[CommAggr][NotifyConnectChange] from offline target=%s{private}.", srcTarget.c_str()); + for (const auto &entry : changedLabels) { + LOGW("[CommAggr] REMEMBER: label=%s, inOnline=%d.", VEC_TO_STR(entry.first), entry.second); + } + return; + } + // Do target change notify + std::lock_guard commMapLockGuard(commMapMutex_); + for (auto &entry : changedLabels) { + // Ignore nonactivated communicator + if (commMap_.count(entry.first) != 0 && commMap_.at(entry.first).second) { + LOGI("[CommAggr][NotifyConnectChange] label=%s, srcTarget=%s{private}, isOnline=%d.", + VEC_TO_STR(entry.first), srcTarget.c_str(), entry.second); + commMap_.at(entry.first).first->OnConnectChange(srcTarget, entry.second); + } + } +} + +void CommunicatorAggregator::RegDBChangeCallback() +{ + if (dbStatusAdapter_ != nullptr) { + dbStatusAdapter_->SetDBStatusChangeCallback( + [this](const std::string &devInfo, const std::vector &dbInfos) { + OnRemoteDBStatusChange(devInfo, dbInfos); + }, + [this]() { + if (commLinker_ != nullptr) { + (void)commLinker_->TriggerLabelExchangeEvent(false); + } + }, + [this](const std::string &dev) { + if (commLinker_ != nullptr) { + std::set relatedLabels; + (void)commLinker_->TargetOnline(dev, relatedLabels); + } + }); + } +} void CommunicatorAggregator::InitSendThread() { if (RuntimeContext::GetInstance()->GetThreadPool() != nullptr) { diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp index 42a232f70daf2780fc87e37b4ab7ff8bf641ed5b..96f358942c4af7cdfb86d73ed2aba76cbecd7824 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp @@ -14,7 +14,10 @@ */ #include "communicator_linker.h" + +#include #include "communicator_aggregator.h" +#include "db_common.h" #include "db_errno.h" #include "hash.h" #include "log_print.h" @@ -29,10 +32,12 @@ constexpr uint32_t RETRANSMIT_LIMIT = 20; // Currently we do at most 20 retransm constexpr uint32_t RETRANSMIT_LIMIT_EQUAL_INTERVAL = 5; // First 5 retransmission will be equal interval } -CommunicatorLinker::CommunicatorLinker(CommunicatorAggregator *inAggregator) +CommunicatorLinker::CommunicatorLinker(CommunicatorAggregator *inAggregator, + std::shared_ptr statusAdapter) : incSequenceId_(0), incAckTriggerId_(0) { aggregator_ = inAggregator; + statusAdapter_ = std::move(statusAdapter); RefObject::IncObjRef(aggregator_); // The linker rely on CommunicatorAggregator } @@ -40,6 +45,7 @@ CommunicatorLinker::~CommunicatorLinker() { RefObject::DecObjRef(aggregator_); // The linker no longer rely on CommunicatorAggregator aggregator_ = nullptr; + statusAdapter_ = nullptr; } void CommunicatorLinker::Initialize() @@ -75,6 +81,9 @@ int CommunicatorLinker::TargetOnline(const std::string &inTarget, std::set