diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 9b359e5aa7403c2de5dab19fa3a08745571c26f7..2d53f985019aec24e5dc809fa77b69d1d6d6a832 100755 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -909,6 +909,8 @@ ohos_unittest("UdmfRunTimeStoreTest") { "${data_service_path}/app/src", "${data_service_path}/service/kvdb", "${data_service_path}/service/udmf", + "${data_service_path}/service/udmf/store", + "${data_service_path}/service/udmf/preprocess", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", @@ -942,6 +944,11 @@ ohos_unittest("UdmfRunTimeStoreTest") { "//third_party/googletest:gtest_main", "//third_party/openssl:libcrypto_shared", ] + + defines = [ + "private=public", + "protected=public", + ] } ohos_unittest("DataShareServiceImplTest") { diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index ec7fb210ab6927ec422e01bf588186b7495d885d..d8d440cf33a44187d7f4dcbb8b1d93e5eda7c45f 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -25,11 +25,10 @@ #include "kvstore_meta_manager.h" #include "metadata/meta_data_manager.h" #include "nativetoken_kit.h" +#include "preprocess_utils.h" +#include "runtime_store.h" #include "text.h" #include "token_setproc.h" -#define private public -#include "store/runtime_store.h" -#undef private using namespace testing::ext; using namespace OHOS::DistributedData; @@ -501,7 +500,7 @@ HWTEST_F(UdmfRunTimeStoreTest, GetDetailsFromUData, TestSize.Level1) details1.insert({ "udmf_key", "udmf_value" }); auto records = data1.GetRecords(); EXPECT_EQ(records.size(), 0); - status = store->GetDetailsFromUData(data1, details1); + status = PreProcessUtils::GetDetailsFromUData(data1, details1); EXPECT_FALSE(status); status = store->Delete(KEY_PREFIX); @@ -548,7 +547,7 @@ HWTEST_F(UdmfRunTimeStoreTest, GetDetailsFromUData01, TestSize.Level1) auto outputRecords = outputData.GetRecords(); ASSERT_EQ(inputRecords.size(), 512); ASSERT_EQ(0, outputRecords.size()); - status = store->GetDetailsFromUData(inputData, details1); + status = PreProcessUtils::GetDetailsFromUData(inputData, details1); EXPECT_FALSE(status); } @@ -572,7 +571,8 @@ HWTEST_F(UdmfRunTimeStoreTest, GetSummary, TestSize.Level1) data.AddRecord(text); Summary summary; - auto status = store->GetSummary(KEY_PREFIX, summary); + UnifiedKey key(KEY_PREFIX); + auto status = store->GetSummary(key, summary); ASSERT_EQ(status, E_DB_ERROR); } }; // namespace DistributedDataTest diff --git a/services/distributeddataservice/service/udmf/preprocess/data_handler.h b/services/distributeddataservice/service/udmf/preprocess/data_handler.h index 3be27dfa34bab235852fc67e59bee7a5fea3ec92..b3e89721f7566e619726a0f70eadf68c8d825d40 100644 --- a/services/distributeddataservice/service/udmf/preprocess/data_handler.h +++ b/services/distributeddataservice/service/udmf/preprocess/data_handler.h @@ -16,6 +16,7 @@ #define DATA_HANDLER_H #include "unified_data.h" +#include "tlv_util.h" #include "types_export.h" namespace OHOS::UDMF { @@ -26,6 +27,10 @@ public: static Status MarshalToEntries(const UnifiedData &unifiedData, std::vector &entries); static Status UnmarshalEntries(const std::string &key, const std::vector &entries, UnifiedData &unifiedData); + template + static Status MarshalToEntries(const T &data, Value &value, TAG tag); + template + static Status UnmarshalEntries(const Value &value, T &data, TAG tag); private: static Status BuildEntries(const std::vector> &records, @@ -34,5 +39,25 @@ private: const std::string &key, std::map> &records, std::map> &innerEntries); }; + +template +Status DataHandler::MarshalToEntries(const T &data, Value &value, TAG tag) +{ + auto tlvObject = TLVObject(value); + if (!TLVUtil::Writing(data, tlvObject, tag)) { + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +template +Status DataHandler::UnmarshalEntries(const Value &value, T &data, TAG tag) +{ + auto tlvObject = TLVObject(const_cast &>(value)); + if (!TLVUtil::ReadTlv(data, tlvObject, tag)) { + return E_READ_PARCEL_ERROR; + } + return E_OK; +} } // namespace UDMF::OHOS #endif // DATA_HANDLER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp index fcb2eb437b485ae45b01b2f2a14fabd88dff7551..069609aba289fdbb03bf3515a72a5bad8c87551f 100644 --- a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -40,6 +40,11 @@ constexpr const char *FILE_SCHEME_PREFIX = "file://"; constexpr const char *DOCS_LOCAL_TAG = "/docs/"; static constexpr uint32_t DOCS_LOCAL_PATH_SUBSTR_START_INDEX = 1; static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500; +constexpr const char *TEMP_UNIFIED_DATA_FLAG = "temp_udmf_file_flag"; +static constexpr size_t TEMP_UDATA_RECORD_SIZE = 1; +static constexpr uint32_t PREFIX_LEN = 24; +static constexpr uint32_t INDEX_LEN = 8; +static constexpr const char PLACE_HOLDER = '0'; using namespace OHOS::DistributedDataDfx; using namespace Security::AccessToken; using namespace OHOS::AppFileService::ModuleRemoteFileShare; @@ -66,6 +71,7 @@ int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption & runtime.deviceId = GetLocalDeviceId(); runtime.recordTotalNum = static_cast(data.GetRecords().size()); runtime.tokenId = option.tokenId; + runtime.sdkVersion = data.GetSdkVersion(); data.SetRuntime(runtime); return E_OK; } @@ -401,5 +407,68 @@ void PreProcessUtils::ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, b PreProcessUtils::ClearHtmlDfsUris(data); } } + +void PreProcessUtils::SetRecordUid(UnifiedData &data) +{ + uint32_t index = 0; + auto prefix = PreProcessUtils::GenerateId().substr(0, PREFIX_LEN); + for (const auto &record : data.GetRecords()) { + std::ostringstream oss; + oss << std::setw(INDEX_LEN) << std::setfill(PLACE_HOLDER) << index; + record->SetUid(prefix + oss.str()); + index++; + } +} + +bool PreProcessUtils::GetDetailsFromUData(const UnifiedData &data, UDDetails &details) +{ + auto records = data.GetRecords(); + if (records.size() != TEMP_UDATA_RECORD_SIZE) { + ZLOGE("Records size error.size:%{public}zu", records.size()); + return false; + } + if (records[0] == nullptr) { + ZLOGE("First record is null."); + return false; + } + if (records[0]->GetType() != UDType::FILE) { + ZLOGE("First record is not file."); + return false; + } + auto value = records[0]->GetOriginValue(); + auto obj = std::get_if>(&value); + if (obj == nullptr || *obj == nullptr) { + ZLOGE("ValueType is not Object!"); + return false; + } + std::shared_ptr detailObj; + (*obj)->GetValue(DETAILS, detailObj); + if (detailObj == nullptr) { + ZLOGE("Not contain details for object!"); + return false; + } + auto result = ObjectUtils::ConvertToUDDetails(detailObj); + if (result.find(TEMP_UNIFIED_DATA_FLAG) == result.end()) { + ZLOGE("Not find temp file."); + return false; + } + details = std::move(result); + return true; +} + +Status PreProcessUtils::GetSummaryFromDetails(const UDDetails &details, Summary &summary) +{ + for (auto &item : details) { + if (item.first == TEMP_UNIFIED_DATA_FLAG) { + continue; + } + auto int64Value = std::get_if(&item.second); + if (int64Value != nullptr) { + summary.summary[item.first] = *int64Value; + summary.totalSize += *int64Value; + } + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h index e57061af750155aeb28d4a01fe2767b2677d3c8e..6d613007813bcf338963c5c1b332cd04960424a6 100644 --- a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -39,6 +39,9 @@ public: static void ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); static void ProcessRecord(std::shared_ptr record, uint32_t tokenId, bool isLocal, std::vector &uris); + static void SetRecordUid(UnifiedData &data); + static bool GetDetailsFromUData(const UnifiedData &data, UDDetails &details); + static Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); private: static bool CheckUriAuthorization(const std::vector& uris, uint32_t tokenId); static int32_t GetDfsUrisFromLocal(const std::vector &uris, int32_t userId, UnifiedData &data); diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index a8dd78f5d7c7124d8af633f699eeb0e41e6acfa4..9b7bfd49e06363676a04b4b32881edaafbd86adb 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -28,6 +28,7 @@ #include "bootstrap.h" #include "directory/directory_manager.h" #include "utils/anonymous.h" +#include "preprocess_utils.h" namespace OHOS { namespace UDMF { @@ -36,8 +37,7 @@ using namespace DistributedDB; using Anonymous = OHOS::DistributedData::Anonymous; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; -constexpr const char *TEMP_UNIFIED_DATA_FLAG = "temp_udmf_file_flag"; -static constexpr size_t TEMP_UDATA_RECORD_SIZE = 1; +constexpr const char *SUMMARY_SUFIX = "#summary"; RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_(storeId) { @@ -99,6 +99,10 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) { UpdateTime(); std::vector entries; + std::string intention = unifiedData.GetRuntime()->key.intention; + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + PutSummary(unifiedData, entries); + } auto status = DataHandler::MarshalToEntries(unifiedData, entries); if (status != E_OK) { return status; @@ -121,63 +125,89 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) return DataHandler::UnmarshalEntries(key, entries, unifiedData); } -bool RuntimeStore::GetDetailsFromUData(UnifiedData &data, UDDetails &details) +Status RuntimeStore::PutSummary(const UnifiedData &data, std::vector &entries) { - auto records = data.GetRecords(); - if (records.size() != TEMP_UDATA_RECORD_SIZE) { - return false; - } - if (records[0] == nullptr || records[0]->GetType() != UDType::FILE) { - return false; - } - auto obj = std::get>(records[0]->GetOriginValue()); - if (obj == nullptr) { - ZLOGE("ValueType is not Object!"); - return false; + UpdateTime(); + UDDetails details {}; + Summary summary; + if (PreProcessUtils::GetDetailsFromUData(data, details)) { + PreProcessUtils::GetSummaryFromDetails(details, summary); + } else { + UnifiedDataHelper::GetSummary(data, summary); } - std::shared_ptr detailObj; - obj->GetValue(DETAILS, detailObj); - if (detailObj == nullptr) { - ZLOGE("Not contain details for object!"); - return false; - } - auto result = ObjectUtils::ConvertToUDDetails(detailObj); - if (result.find(TEMP_UNIFIED_DATA_FLAG) == result.end()) { - return false; + + auto propertyKey = data.GetRuntime()->key.GetPropertyKey(); + Value value; + auto status = DataHandler::MarshalToEntries(summary, value, TAG::TAG_SUMMARY); + if (status != E_OK) { + ZLOGE("Marshal summary failed, key: %{public}s, status:%{public}d", propertyKey.c_str(), status); + return status; } - details = result; - return true; + auto summaryKey = propertyKey + SUMMARY_SUFIX; + entries.push_back({{summaryKey.begin(), summaryKey.end()}, value}); + return E_OK; } -Status RuntimeStore::GetSummaryFromDetails(const UDDetails &details, Summary &summary) +Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) { - for (auto &item : details) { - if (item.first != TEMP_UNIFIED_DATA_FLAG) { - auto int64Value = std::get_if(&item.second); - if (int64Value != nullptr) { - auto size = std::get(item.second); - summary.summary[item.first] = size; - summary.totalSize += size; - } + UpdateTime(); + Value value; + auto summaryKey = key.GetPropertyKey() + SUMMARY_SUFIX; + auto res = kvStore_->Get({summaryKey.begin(), summaryKey.end()}, value); + if (res != OK || value.empty()) { + ZLOGW("Get stored summary failed, key: %{public}s, status:%{public}d", summaryKey.c_str(), res); + UnifiedData unifiedData; + auto udKey = key.GetUnifiedKey(); + if (Get(udKey, unifiedData) != E_OK) { + ZLOGE("Get unified data failed, key: %{public}s", udKey.c_str()); + return E_DB_ERROR; } + UDDetails details {}; + if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { + return PreProcessUtils::GetSummaryFromDetails(details, summary); + } + UnifiedDataHelper::GetSummary(unifiedData, summary); + return E_OK; + } + auto status = DataHandler::UnmarshalEntries(value, summary, TAG::TAG_SUMMARY); + if (status != E_OK) { + ZLOGE("Unmarshal summary failed, key: %{public}s, status:%{public}d", summaryKey.c_str(), status); + return status; } return E_OK; } -Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) +Status RuntimeStore::PutRuntime(const std::string &key, const Runtime &runtime) { UpdateTime(); - UnifiedData unifiedData; - if (Get(key, unifiedData) != E_OK) { - ZLOGE("Get unified data failed, dataPrefix: %{public}s", key.c_str()); + Value value; + auto status = DataHandler::MarshalToEntries(runtime, value, TAG::TAG_RUNTIME); + if (status != E_OK) { + ZLOGE("Marshal runtime failed, key: %{public}s, status:%{public}d", key.c_str(), status); + return status; + } + auto res = kvStore_->Put({key.begin(), key.end()}, value); + if (res != OK) { + ZLOGE("Put failed, key:%{public}s, status:%{public}d", key.c_str(), res); return E_DB_ERROR; } + return E_OK; +} - UDDetails details {}; - if (GetDetailsFromUData(unifiedData, details)) { - return GetSummaryFromDetails(details, summary); +Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) +{ + UpdateTime(); + Value value; + auto res = kvStore_->Get({key.begin(), key.end()}, value); + if (res != OK || value.empty()) { + ZLOGE("Get failed, key: %{public}s, status:%{public}d", key.c_str(), res); + return E_DB_ERROR; + } + auto status = DataHandler::UnmarshalEntries(value, runtime, TAG::TAG_RUNTIME); + if (status != E_OK) { + ZLOGE("Unmarshal runtime failed, key: %{public}s, status:%{public}d", key.c_str(), status); + return status; } - UnifiedDataHelper::GetSummary(unifiedData, summary); return E_OK; } diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index 623b9204cff2ecc041fcddab7ba0cec8474c9c88..eb83a3503cefebf22a1a7ce15f9f801508ff7228 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -30,7 +30,7 @@ public: ~RuntimeStore(); Status Put(const UnifiedData &unifiedData) override; Status Get(const std::string &key, UnifiedData &unifiedData) override; - Status GetSummary(const std::string &key, Summary &summary) override; + Status GetSummary(UnifiedKey &key, Summary &summary) override; Status Update(const UnifiedData &unifiedData) override; Status Delete(const std::string &key) override; Status DeleteBatch(const std::vector &unifiedKeys) override; @@ -41,6 +41,8 @@ public: Status PutLocal(const std::string &key, const std::string &value) override; Status GetLocal(const std::string &key, std::string &value) override; Status DeleteLocal(const std::string &key) override; + Status PutRuntime(const std::string &key, const Runtime &runtime) override; + Status GetRuntime(const std::string &key, Runtime &runtime) override; void Close() override; bool Init() override; @@ -59,11 +61,10 @@ private: Status DeleteEntries(const std::vector &keys); Status UnmarshalEntries( const std::string &key, std::vector &entries, UnifiedData &unifiedData); - bool GetDetailsFromUData(UnifiedData &data, UDDetails &details); - Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); bool BuildMetaDataParam(DistributedData::StoreMetaData &metaData); void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, const DevNameMap &deviceNameMap); + Status PutSummary(const UnifiedData &data, std::vector &entries); }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/store/store.h b/services/distributeddataservice/service/udmf/store/store.h index 1a728c3747b053c6d29edae9b2a6096771c00387..aaf6fade14404514789d4b98cedfbe8b1afbcff9 100644 --- a/services/distributeddataservice/service/udmf/store/store.h +++ b/services/distributeddataservice/service/udmf/store/store.h @@ -26,7 +26,7 @@ public: using Time = std::chrono::steady_clock::time_point; virtual Status Put(const UnifiedData &unifiedData) = 0; virtual Status Get(const std::string &key, UnifiedData &unifiedData) = 0; - virtual Status GetSummary(const std::string &key, Summary &summary) = 0; + virtual Status GetSummary(UnifiedKey &key, Summary &summary) = 0; virtual Status Update(const UnifiedData &unifiedData) = 0; virtual Status Delete(const std::string &key) = 0; virtual Status DeleteBatch(const std::vector &unifiedKeys) = 0; @@ -37,6 +37,8 @@ public: virtual Status PutLocal(const std::string &key, const std::string &value) = 0; virtual Status GetLocal(const std::string &key, std::string &value) = 0; virtual Status DeleteLocal(const std::string &key) = 0; + virtual Status PutRuntime(const std::string &key, const Runtime &runtime) = 0; + virtual Status GetRuntime(const std::string &key, Runtime &runtime) = 0; virtual bool Init() = 0; virtual void Close() = 0; diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index fc75e80b05d5272c71e5e30deb559f85a64320f3..2d0cdacbc0f0b74640bc5ead48f8788d56440114 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -34,6 +34,7 @@ #include "bootstrap.h" #include "metadata/store_meta_data.h" #include "metadata/meta_data_manager.h" +#include "unified_data_helper.h" namespace OHOS { namespace UDMF { @@ -133,10 +134,7 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData return ret; } } - - for (const auto &record : unifiedData.GetRecords()) { - record->SetUid(PreProcessUtils::GenerateId()); - } + PreProcessUtils::SetRecordUid(unifiedData); auto store = StoreCache::GetInstance().GetStore(intention); if (store == nullptr) { @@ -399,9 +397,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi } runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); unifiedData.SetRuntime(*runtime); - for (auto &record : unifiedData.GetRecords()) { - record->SetUid(PreProcessUtils::GenerateId()); - } + PreProcessUtils::SetRecordUid(unifiedData); if (store->Update(unifiedData) != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); return E_DB_ERROR; @@ -462,7 +458,7 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) return E_DB_ERROR; } - if (store->GetSummary(query.key, summary) != E_OK) { + if (store->GetSummary(key, summary) != E_OK) { ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); return E_DB_ERROR; } @@ -500,26 +496,23 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi return E_DB_ERROR; } - UnifiedData data; - int32_t res = store->Get(query.key, data); + Runtime runtime; + auto res = store->GetRuntime(query.key, runtime); if (res == E_NOT_FOUND) { privilegeCache_[query.key] = privilege; ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); return E_OK; } if (res != E_OK) { - ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str()); + ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); return res; } - if (data.GetRuntime() == nullptr) { - return E_DB_ERROR; - } - data.GetRuntime()->privileges.emplace_back(privilege); - if (store->Update(data) != E_OK) { - ZLOGE("Update unified data failed:%{public}s", key.intention.c_str()); - return E_DB_ERROR; + runtime.privileges.emplace_back(privilege); + res = store->PutRuntime(query.key, runtime); + if (res != E_OK) { + ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); } - return E_OK; + return res; } int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices)