From b45a8a13243af3e79a361db2e90861b4fa8957e0 Mon Sep 17 00:00:00 2001 From: zph Date: Tue, 19 Aug 2025 10:33:52 +0800 Subject: [PATCH 1/3] update Signed-off-by: zph --- .../service/udmf/udmf_service_impl.cpp | 46 ++++++++++++++----- .../service/udmf/udmf_service_impl.h | 7 +++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 668f65a0a..41011805a 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -67,6 +67,7 @@ constexpr const char *DEVICE_PHONE_TAG = "phone"; constexpr const char *DEVICE_DEFAULT_TAG = "default"; constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"}; constexpr uint32_t FOUNDATION_UID = 5523; +constexpr uint32_t WAIT_TIME = 1; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -174,12 +175,26 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD std::string bundleName; if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { msg.appId = "unknown"; - res = E_ERROR; - } else { - msg.appId = bundleName; + Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg); + return E_ERROR; + } + + msg.appId = bundleName; + bool isDelayLoad = dataLoadCallback_.ComputeIfPresent(key, [&unifiedData](auto &key, BlockDelayData &val) { + blockDelayDataCache_.ComputeIfAbsent(query.key, [&query](auto &key) { + auto blockData = std::make_shared>>(WAIT_TIME); + return BlockDelayData { blockData, query.tokenId }; + }); + auto data = val.blockData->GetValue(); + if (data != std::nullopt) { + unifiedData = *data; + return false; + } + return true; + }); + if (!isDelayLoad) { res = RetrieveData(query, unifiedData); } - TransferToEntriesIfNeed(query, unifiedData); auto errFind = ERROR_MAP.find(res); msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; for (const auto &record : unifiedData.GetRecords()) { @@ -259,6 +274,7 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni privilegeCache_.erase(query.key); } PreProcessUtils::SetRemoteData(unifiedData); + TransferToEntriesIfNeed(query, unifiedData); return E_OK; } @@ -1184,6 +1200,12 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptr(IPCSkeleton::GetCallingTokenID()); @@ -1196,13 +1218,9 @@ int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unif ZLOGW("SetRemoteUri failed, ret:%{public}d, key:%{public}s.", ret, key.c_str()); } - auto it = delayDataCallback_.Find(key); - if (!it.first) { - ZLOGE("DelayData callback no exist, key:%{public}s", key.c_str()); - return E_ERROR; - } QueryOption query; - query.tokenId = it.second.tokenId; + query.tokenId = isDataLoading ? delayDataCallback_.Find(key).second.tokenId : + blockDelayDataCache_.Find(key).second.tokenId; query.key = key; if (option.tokenId != query.tokenId && !IsPermissionInCache(query)) { ZLOGE("No permission"); @@ -1218,9 +1236,13 @@ int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unif privilegeCache_.erase(key); } PreProcessUtils::SetRemoteData(unifiedData); - TransferToEntriesIfNeed(query, unifiedData); - return HandleDelayDataCallback(it.second, unifiedData, key); + + if (!isDataLoading) { + blockDelayDataCache_.Find(key).second.blockData->SetValue(unifiedData); + return E_OK; + } + return HandleDelayDataCallback(delayDataCallback_.Find(key).second, unifiedData, key); } int32_t UdmfServiceImpl::HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData, diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 0dafbfd52..51df264e0 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -22,6 +22,7 @@ #include "metadata/store_meta_data.h" #include "checker_manager.h" #include "udmf_notifier_proxy.h" +#include "block_data.h" namespace OHOS { namespace UDMF { /* @@ -109,6 +110,12 @@ private: std::unordered_map asyncProcessInfoMap_; ConcurrentMap> dataLoadCallback_; ConcurrentMap delayDataCallback_; + + struct BlockDelayData { + std::shared_ptr>> blockData; + uint32_t tokenId; + }; + ConcurrentMap blockDelayDataCache_; }; } // namespace UDMF } // namespace OHOS -- Gitee From 50d90325e5cd391b4b73c6f5ee0fa6be06bf82ba Mon Sep 17 00:00:00 2001 From: zph Date: Tue, 19 Aug 2025 10:47:19 +0800 Subject: [PATCH 2/3] update Signed-off-by: zph --- .../service/udmf/udmf_service_impl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 0e14376c5..a738cc04d 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -108,15 +108,15 @@ private: std::shared_ptr executors_; std::mutex mutex_; - std::unordered_map asyncProcessInfoMap_; - ConcurrentMap> dataLoadCallback_; - ConcurrentMap delayDataCallback_; + std::unordered_map asyncProcessInfoMap_ {}; + ConcurrentMap> dataLoadCallback_ {}; + ConcurrentMap delayDataCallback_ {}; struct BlockDelayData { + uint32_t tokenId {0}; std::shared_ptr>> blockData; - uint32_t tokenId; }; - ConcurrentMap blockDelayDataCache_; + ConcurrentMap blockDelayDataCache_ {}; }; } // namespace UDMF } // namespace OHOS -- Gitee From cdb3f3b13077ca77a1190a8608d5c9b732ac71df Mon Sep 17 00:00:00 2001 From: zph Date: Tue, 19 Aug 2025 17:41:47 +0800 Subject: [PATCH 3/3] update Signed-off-by: zph --- .../service/test/udmf_service_impl_test.cpp | 153 ++++++++++++++++++ .../service/udmf/udmf_service_impl.cpp | 68 +++++--- .../service/udmf/udmf_service_impl.h | 11 +- 3 files changed, 201 insertions(+), 31 deletions(-) diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index 9a32e1587..d5ae9fab1 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -676,5 +676,158 @@ HWTEST_F(UdmfServiceImplTest, VerifyDataAccessPermission002, TestSize.Level1) EXPECT_EQ(runtime->privileges[0].tokenId, query.tokenId); EXPECT_EQ(result, OHOS::UDMF::E_OK); } + +/** + * @tc.name: HandleDelayLoad001 + * @tc.desc: Returns true when data not arrives + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, HandleDelayLoad001, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = 123; + + UnifiedData result; + int32_t res = UDMF::E_OK; + + UdmfServiceImpl service; + service.dataLoadCallback_.Insert(query.key, nullptr); + + using CacheData = BlockData, std::chrono::milliseconds>; + UdmfServiceImpl::BlockDelayData data; + data.tokenId = query.tokenId; + data.blockData = std::make_shared(100); + service.blockDelayDataCache_.Insert(query.key, data); + + bool handled = service.HandleDelayLoad(query, result, res); + + service.dataLoadCallback_.Erase(query.key); + service.blockDelayDataCache_.Erase(query.key); + + EXPECT_TRUE(handled); + EXPECT_EQ(res, UDMF::E_NOT_FOUND); +} + +/** + * @tc.name: HandleDelayLoad002 + * @tc.desc: Returns false when not exist + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, HandleDelayLoad002, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = 123; + + UnifiedData result; + int32_t res = UDMF::E_OK; + + UdmfServiceImpl service; + bool handled = service.HandleDelayLoad(query, result, res); + + EXPECT_FALSE(handled); +} + +/** + * @tc.name: HandleDelayLoad003 + * @tc.desc: Returns true when data arrives + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, HandleDelayLoad003, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = 123; + + UnifiedData result; + int32_t res = UDMF::E_OK; + + UnifiedData insertedData; + insertedData.AddRecord(std::make_shared()); + + UdmfServiceImpl service; + service.dataLoadCallback_.Insert(query.key, nullptr); + + using CacheData = BlockData, std::chrono::milliseconds>; + UdmfServiceImpl::BlockDelayData data; + data.tokenId = query.tokenId; + data.blockData = std::make_shared(100); + service.blockDelayDataCache_.Insert(query.key, data); + + data.blockData->SetValue(insertedData); + bool handled = service.HandleDelayLoad(query, result, res); + + EXPECT_TRUE(handled); + EXPECT_EQ(res, UDMF::E_OK); +} + +/** + * @tc.name: PushDelayData002 + * @tc.desc: DelayData callback and block cache not exist + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, PushDelayData002, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = 123; + UnifiedData insertedData; + insertedData.AddRecord(std::make_shared()); + + UdmfServiceImpl service; + auto status = service.PushDelayData(query.key, insertedData); + EXPECT_EQ(status, UDMF::E_ERROR); +} + +/** + * @tc.name: PushDelayData003 + * @tc.desc: No permission + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, PushDelayData003, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = 123; + + using CacheData = BlockData, std::chrono::milliseconds>; + UdmfServiceImpl::BlockDelayData data; + data.tokenId = query.tokenId; + data.blockData = std::make_shared(100); + UdmfServiceImpl service; + service.blockDelayDataCache_.Insert(query.key, data); + + UnifiedData insertedData; + auto status = service.PushDelayData(query.key, insertedData); + EXPECT_EQ(status, UDMF::E_NO_PERMISSION); +} + +/** + * @tc.name: PushDelayData004 + * @tc.desc: PushDelayData success + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, PushDelayData004, TestSize.Level1) +{ + QueryOption query; + query.key = "k1"; + query.tokenId = IPCSkeleton::GetSelfTokenID(); + + using CacheData = BlockData, std::chrono::milliseconds>; + UdmfServiceImpl::BlockDelayData data; + data.tokenId = query.tokenId; + data.blockData = std::make_shared(100); + UdmfServiceImpl service; + service.blockDelayDataCache_.Insert(query.key, data); + + Privilege privilege; + privilege.tokenId = query.tokenId; + service.privilegeCache_[query.key] = privilege; + + UnifiedData insertedData; + auto status = service.PushDelayData(query.key, insertedData); + EXPECT_EQ(status, UDMF::E_OK); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 631d033c8..0611b796f 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -67,7 +67,7 @@ constexpr const char *DEVICE_PHONE_TAG = "phone"; constexpr const char *DEVICE_DEFAULT_TAG = "default"; constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"}; constexpr uint32_t FOUNDATION_UID = 5523; -constexpr uint32_t WAIT_TIME = 1; +constexpr uint32_t WAIT_TIME = 800; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -176,23 +176,13 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { msg.appId = "unknown"; Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg); + ZLOGE("Failed to get bundle name by token, token:%{public}d", query.tokenId); return E_ERROR; } - msg.appId = bundleName; - bool isDelayLoad = dataLoadCallback_.ComputeIfPresent(key, [&unifiedData](auto &key, BlockDelayData &val) { - blockDelayDataCache_.ComputeIfAbsent(query.key, [&query](auto &key) { - auto blockData = std::make_shared>>(WAIT_TIME); - return BlockDelayData { blockData, query.tokenId }; - }); - auto data = val.blockData->GetValue(); - if (data != std::nullopt) { - unifiedData = *data; - return false; - } - return true; - }); - if (!isDelayLoad) { + + bool handledByDelay = HandleDelayLoad(query, unifiedData, res); + if (!handledByDelay) { res = RetrieveData(query, unifiedData); } auto errFind = ERROR_MAP.find(res); @@ -205,9 +195,36 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD msg.dataType = types; msg.dataSize = unifiedData.GetSize(); Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg); + if (res != E_OK) { + ZLOGE("GetData failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); + } return res; } +bool UdmfServiceImpl::HandleDelayLoad(const QueryOption &query, UnifiedData &unifiedData, int32_t &res) +{ + return dataLoadCallback_.ComputeIfPresent(query.key, [&](const auto &key, auto &callback) { + std::shared_ptr, std::chrono::milliseconds>> blockData; + auto [found, cache] = blockDelayDataCache_.Find(key); + if (!found) { + blockData = std::make_shared, std::chrono::milliseconds>>(WAIT_TIME); + blockDelayDataCache_.Insert(key, BlockDelayData{query.tokenId, blockData}); + callback->HandleDelayObserver(key, DataLoadInfo()); + } else { + blockData = cache.blockData; + } + ZLOGI("Start waiting for data, key:%{public}s", key.c_str()); + auto dataOpt = blockData->GetValue(); + if (dataOpt.has_value()) { + unifiedData = *dataOpt; + blockDelayDataCache_.Erase(key); + return false; + } + res = E_NOT_FOUND; + return true; + }); +} + bool UdmfServiceImpl::CheckDragParams(UnifiedKey &key, const QueryOption &query) { if (!key.IsValid()) { @@ -262,11 +279,9 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni return E_NO_PERMISSION; } } - if (!IsReadAndKeep(runtime->privileges, query)) { - if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) { - ZLOGE("Remove data failed:%{public}s", key.intention.c_str()); - return E_DB_ERROR; - } + if (!IsReadAndKeep(runtime->privileges, query) && LifeCycleManager::GetInstance().OnGot(key) != E_OK) { + ZLOGE("Remove data failed:%{public}s", key.intention.c_str()); + return E_DB_ERROR; } { @@ -1214,8 +1229,10 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrSetValue(unifiedData); + blockIt.second.blockData->SetValue(unifiedData); return E_OK; } - return HandleDelayDataCallback(delayDataCallback_.Find(key).second, unifiedData, key); + return HandleDelayDataCallback(delayIt.second, unifiedData, key); } int32_t UdmfServiceImpl::HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData, diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index a738cc04d..beef4dda4 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -16,13 +16,13 @@ #ifndef UDMF_SERVICE_IMPL_H #define UDMF_SERVICE_IMPL_H -#include "store_cache.h" -#include "udmf_service_stub.h" +#include "block_data.h" +#include "checker_manager.h" #include "kv_store_delegate_manager.h" #include "metadata/store_meta_data.h" -#include "checker_manager.h" +#include "store_cache.h" #include "udmf_notifier_proxy.h" -#include "block_data.h" +#include "udmf_service_stub.h" namespace OHOS { namespace UDMF { /* @@ -93,6 +93,7 @@ private: std::vector ProcessResult(const std::map &results); DistributedData::StoreMetaData BuildMeta(const std::string &storeId, int userId); int32_t VerifyUpdatePermission(const QueryOption &query, UnifiedData &unifiedData, std::string &bundleName); + bool HandleDelayLoad(const QueryOption &query, UnifiedData &unifiedData, int32_t &res); class Factory { public: @@ -114,7 +115,7 @@ private: struct BlockDelayData { uint32_t tokenId {0}; - std::shared_ptr>> blockData; + std::shared_ptr, std::chrono::milliseconds>> blockData; }; ConcurrentMap blockDelayDataCache_ {}; }; -- Gitee