From 1f6ff98b502078d4586c8e05a2caf7a4d8d37c5d Mon Sep 17 00:00:00 2001 From: q30042978 Date: Tue, 30 May 2023 21:56:21 +0800 Subject: [PATCH] =?UTF-8?q?Description:UDMF=E6=8F=90=E4=BE=9B=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=AE=A1=E7=90=86=E6=8E=A5=E5=8F=A3=20Team:OTHERS=20F?= =?UTF-8?q?eature=20or=20Bugfix:Feature=20Binary=20Source:No=20PrivateCode?= =?UTF-8?q?(Yes/No):No?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: q30042978 --- framework/common/udmf_types_util.cpp | 16 +- .../innerkitsimpl/client/udmf_client.cpp | 56 +++- .../innerkitsimpl/common/unified_key.cpp | 2 +- .../innerkitsimpl/common/unified_meta.cpp | 19 ++ .../test/unittest/udmf_client_test.cpp | 304 +++++++++++++++++- .../jskitsimpl/common/napi_data_utils.cpp | 10 + .../jskitsimpl/common/napi_error_utils.cpp | 6 +- framework/jskitsimpl/common/napi_queue.cpp | 49 +-- framework/jskitsimpl/data/udmf_napi.cpp | 212 ++++++++++++ framework/manager/data_manager.cpp | 129 +++++++- framework/manager/data_manager.h | 10 +- .../manager/lifecycle/lifecycle_policy.cpp | 22 +- .../manager/lifecycle/lifecycle_policy.h | 3 +- .../manager/preprocess/preprocess_utils.cpp | 7 +- framework/manager/store/runtime_store.cpp | 92 +++--- framework/manager/store/runtime_store.h | 7 +- framework/manager/store/store.h | 7 +- framework/manager/store/store_cache.cpp | 3 +- framework/service/udmf_service.h | 13 +- framework/service/udmf_service_client.cpp | 24 +- framework/service/udmf_service_client.h | 9 +- framework/service/udmf_service_proxy.cpp | 132 +++++--- framework/service/udmf_service_proxy.h | 9 +- framework/service/udmf_service_utils.cpp | 98 ++++++ framework/service/udmf_service_utils.h | 35 ++ interfaces/innerkits/BUILD.gn | 1 + interfaces/innerkits/client/udmf_client.h | 9 +- interfaces/innerkits/common/unified_meta.h | 9 +- interfaces/innerkits/common/unified_types.h | 3 +- interfaces/jskits/common/napi_data_utils.h | 1 + interfaces/jskits/common/napi_queue.h | 11 + interfaces/jskits/data/udmf_napi.h | 6 + service/include/udmf_service_impl.h | 9 +- service/include/udmf_service_stub.h | 6 +- service/src/udmf_service_impl.cpp | 36 ++- service/src/udmf_service_stub.cpp | 129 +++++--- 36 files changed, 1272 insertions(+), 222 deletions(-) create mode 100644 framework/service/udmf_service_utils.cpp create mode 100644 framework/service/udmf_service_utils.h diff --git a/framework/common/udmf_types_util.cpp b/framework/common/udmf_types_util.cpp index bd5d6fe..efbcede 100755 --- a/framework/common/udmf_types_util.cpp +++ b/framework/common/udmf_types_util.cpp @@ -309,12 +309,12 @@ template<> bool Unmarshalling(CustomOption &output, MessageParcel &parcel) template<> bool Marshalling(const QueryOption &input, MessageParcel &parcel) { - return ITypesUtil::Marshal(parcel, input.key); + return ITypesUtil::Marshal(parcel, input.key, input.intention); } template<> bool Unmarshalling(QueryOption &output, MessageParcel &parcel) { - return ITypesUtil::Unmarshal(parcel, output.key); + return ITypesUtil::Unmarshal(parcel, output.key, output.intention); } template<> bool Marshalling(const Text &input, MessageParcel &parcel) @@ -552,7 +552,7 @@ template<> bool Unmarshalling(SystemDefinedAppItem &output, MessageParcel &parce std::string abilityName; UDDetails details; if (!ITypesUtil::Unmarshal(parcel, appId, appName, appIconId, appLabelId, bundleName, abilityName, details)) { - LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal UDAppItem failed!"); + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal SystemDefinedAppItem failed!"); return false; } output.SetAppId(appId); @@ -575,7 +575,7 @@ template<> bool Unmarshalling(SystemDefinedPixelMap &output, MessageParcel &parc std::vector rawData; UDDetails details; if (!ITypesUtil::Unmarshal(parcel, rawData, details)) { - LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal UDPixelMap failed!"); + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal SystemDefinedPixelMap failed!"); return false; } output.SetRawData(rawData); @@ -611,7 +611,7 @@ template<> bool Unmarshalling(UDType &output, MessageParcel &parcel) { int32_t type; if (!ITypesUtil::Unmarshal(parcel, type)) { - LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal PlainText failed!"); + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal UDType failed!"); return false; } if (type < TEXT || type >= UD_BUTT) { @@ -632,11 +632,11 @@ template<> bool Unmarshalling(Intention &output, MessageParcel &parcel) { int32_t intention; if (!ITypesUtil::Unmarshal(parcel, intention)) { - LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal PlainText failed!"); + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshal Intention failed!"); return false; } - if (!UnifiedDataUtils::IsValidIntention(intention)) { - LOG_ERROR(UDMF_FRAMEWORK, "invalid UDIntention!"); + if (intention < UD_INTENTION_BASE || intention > UD_INTENTION_BUTT) { + LOG_ERROR(UDMF_FRAMEWORK, "invalid Intention!"); return false; } output = static_cast(intention); diff --git a/framework/innerkitsimpl/client/udmf_client.cpp b/framework/innerkitsimpl/client/udmf_client.cpp index 2f40187..8b3377a 100755 --- a/framework/innerkitsimpl/client/udmf_client.cpp +++ b/framework/innerkitsimpl/client/udmf_client.cpp @@ -29,7 +29,7 @@ UdmfClient &UdmfClient::GetInstance() Status UdmfClient::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { - LOG_INFO(UDMF_CLIENT, "start."); + LOG_DEBUG(UDMF_CLIENT, "start."); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); @@ -40,9 +40,9 @@ Status UdmfClient::SetData(CustomOption &option, UnifiedData &unifiedData, std:: return static_cast(ret); } -Status UdmfClient::GetData(QueryOption &query, UnifiedData &unifiedData) +Status UdmfClient::GetData(const QueryOption &query, UnifiedData &unifiedData) { - LOG_INFO(UDMF_CLIENT, "start."); + LOG_DEBUG(UDMF_CLIENT, "start."); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); @@ -50,12 +50,52 @@ Status UdmfClient::GetData(QueryOption &query, UnifiedData &unifiedData) } int32_t ret = service->GetData(query, unifiedData); + LOG_DEBUG(UDMF_SERVICE, "Getdata : ret = %{public}d!", ret); return static_cast(ret); } -Status UdmfClient::GetSummary(QueryOption &query, Summary &summary) +Status UdmfClient::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) { - LOG_INFO(UDMF_CLIENT, "start."); + LOG_DEBUG(UDMF_CLIENT, "start."); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_ERROR; + } + + int32_t ret = service->GetBatchData(query, unifiedDataSet); + return static_cast(ret); +} + +Status UdmfClient::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + LOG_DEBUG(UDMF_CLIENT, "start."); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_ERROR; + } + + int32_t ret = service->UpdateData(query, unifiedData); + return static_cast(ret); +} + +Status UdmfClient::DeleteData(const QueryOption &query, std::vector &unifiedDataSet) +{ + LOG_DEBUG(UDMF_CLIENT, "start."); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_ERROR; + } + + int32_t ret = service->DeleteData(query, unifiedDataSet); + return static_cast(ret); +} + +Status UdmfClient::GetSummary(const QueryOption &query, Summary &summary) +{ + LOG_DEBUG(UDMF_CLIENT, "start."); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); @@ -66,9 +106,9 @@ Status UdmfClient::GetSummary(QueryOption &query, Summary &summary) return static_cast(ret); } -Status UdmfClient::AddPrivilege(QueryOption &query, Privilege &privilege) +Status UdmfClient::AddPrivilege(const QueryOption &query, Privilege &privilege) { - LOG_INFO(UDMF_CLIENT, "start."); + LOG_DEBUG(UDMF_CLIENT, "start."); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); @@ -81,7 +121,7 @@ Status UdmfClient::AddPrivilege(QueryOption &query, Privilege &privilege) Status UdmfClient::Sync(const QueryOption &query, const std::vector &devices) { - LOG_INFO(UDMF_CLIENT, "start."); + LOG_DEBUG(UDMF_CLIENT, "start."); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); diff --git a/framework/innerkitsimpl/common/unified_key.cpp b/framework/innerkitsimpl/common/unified_key.cpp index ac4e94a..03abf4b 100644 --- a/framework/innerkitsimpl/common/unified_key.cpp +++ b/framework/innerkitsimpl/common/unified_key.cpp @@ -25,7 +25,7 @@ static std::bitset g_ruleGroupId; static const std::string UNIFIED_KEY_SCHEMA = "udmf://"; static const std::string ALPHA_AGGREGATE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const std::string DIGIT_AGGREGATE = "0123456789"; -static const std::string SYMBOL_AGGREGATE = ":;<=>?@[\\]^_`"; +static const std::string SYMBOL_AGGREGATE = ":;<=>?@[\\]_`"; UnifiedKey::UnifiedKey(std::string key) { this->key = std::move(key); diff --git a/framework/innerkitsimpl/common/unified_meta.cpp b/framework/innerkitsimpl/common/unified_meta.cpp index 3db4ced..402fb51 100644 --- a/framework/innerkitsimpl/common/unified_meta.cpp +++ b/framework/innerkitsimpl/common/unified_meta.cpp @@ -15,6 +15,8 @@ #include "unified_meta.h" +#include "unified_key.h" + namespace OHOS { namespace UDMF { bool UnifiedDataUtils::IsValidType(int32_t value) @@ -85,5 +87,22 @@ Intention UnifiedDataUtils::GetIntentionByString(const std::string &intention) } return UD_INTENTION_BUTT; } + +bool UnifiedDataUtils::IsValidOptions(const std::string &key, std::string &intention) +{ + UnifiedKey unifiedKey(key); + auto isValidKey = unifiedKey.IsValid(); + if (key.empty() && IsPersist(intention)) { + return true; + } + if (intention.empty() && isValidKey && IsPersist(unifiedKey.intention)) { + return true; + } + if (isValidKey && unifiedKey.intention == intention && IsPersist(intention)) { + intention = ""; + return true; + } + return false; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp b/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp index bb63127..6067ded 100755 --- a/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp +++ b/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp @@ -843,7 +843,7 @@ HWTEST_F(UdmfClientTest, SetData014, TestSize.Level1) ASSERT_NE(systemDefinedPixelMap2, nullptr); auto rawData2 = systemDefinedPixelMap2->GetRawData(); EXPECT_EQ(rawData1.size(), rawData2.size()); - for (int i = 0; i < rawData1.size(); ++i) { + for (uint32_t i = 0; i < rawData1.size(); ++i) { EXPECT_EQ(rawData1[i], rawData2[i]); } @@ -891,7 +891,7 @@ HWTEST_F(UdmfClientTest, SetData015, TestSize.Level1) applicationDefinedRecord2->GetApplicationDefinedType()); auto rawData2 = applicationDefinedRecord2->GetRawData(); EXPECT_EQ(rawData1.size(), rawData2.size()); - for (int i = 0; i < rawData1.size(); ++i) { + for (uint32_t i = 0; i < rawData1.size(); ++i) { EXPECT_EQ(rawData1[i], rawData2[i]); } @@ -1396,4 +1396,304 @@ HWTEST_F(UdmfClientTest, GetSelfData002, TestSize.Level1) LOG_INFO(UDMF_TEST, "GetSelfData002 end."); } + +/** +* @tc.name: SetData020 +* @tc.desc: Set datas with intention ${UD_INTENTION_SUPER_HUB} and manually check db is cleared before set or not +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, SetData020, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "SetData020 begin."); + QueryOption query = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + std::vector unifiedDataSet; + auto status = UdmfClient::GetInstance().DeleteData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + unifiedDataSet.clear(); + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + ASSERT_TRUE(unifiedDataSet.empty()); + + CustomOption customOption = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + UnifiedData data1; + PlainText plainText1; + plainText1.SetContent("content1"); + std::shared_ptr record1 = std::make_shared(plainText1); + data1.AddRecord(record1); + std::string key; + status = UdmfClient::GetInstance().SetData(customOption, data1, key); + ASSERT_EQ(status, E_OK); + + UnifiedData data2; + PlainText plainText2; + plainText1.SetContent("content2"); + std::shared_ptr<UnifiedRecord> record2 = std::make_shared<PlainText>(plainText1); + data2.AddRecord(record2); + status = UdmfClient::GetInstance().SetData(customOption, data2, key); + ASSERT_EQ(status, E_OK); + + SetHapToken2(); + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + auto size = static_cast<int32_t>(unifiedDataSet.size()); + ASSERT_EQ(size, 2); + LOG_INFO(UDMF_TEST, "SetData020 end."); +} + +/** +* @tc.name: UpdateData001 +* @tc.desc: Update data with invalid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, UpdateData001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "UpdateData001 begin."); + + UnifiedData data; + QueryOption queryOption = { .key = "" }; + auto status = UdmfClient::GetInstance().UpdateData(queryOption, data); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://drag/ohos.test.demo1/abcde" }; + status = UdmfClient::GetInstance().UpdateData(queryOption, data); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + CustomOption customOption = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + UnifiedData data1; + PlainText plainText1; + plainText1.SetContent("content1"); + std::shared_ptr<UnifiedRecord> record1 = std::make_shared<PlainText>(plainText1); + data1.AddRecord(record1); + std::string key; + status = UdmfClient::GetInstance().SetData(customOption, data1, key); + ASSERT_EQ(status, E_OK); + + queryOption = { .key = key }; + SetHapToken2(); + status = UdmfClient::GetInstance().UpdateData(queryOption, data); + ASSERT_EQ(status, E_INVALID_VALUE); + LOG_INFO(UDMF_TEST, "UpdateData001 end."); +} + +/** +* @tc.name: UpdateData002 +* @tc.desc: Update data with valid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, UpdateData002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "UpdateData002 begin."); + + UnifiedData data; + PlainText plainText; + plainText.SetContent("content"); + std::shared_ptr<UnifiedRecord> record = std::make_shared<PlainText>(plainText); + data.AddRecord(record); + + CustomOption customOption = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + UnifiedData data1; + PlainText plainText1; + plainText1.SetContent("content1"); + std::shared_ptr<UnifiedRecord> record1 = std::make_shared<PlainText>(plainText1); + data1.AddRecord(record1); + std::string key; + auto status = UdmfClient::GetInstance().SetData(customOption, data1, key); + + ASSERT_EQ(status, E_OK); + QueryOption queryOption = { .key = key }; + SetHapToken2(); + status = UdmfClient::GetInstance().UpdateData(queryOption, data); + ASSERT_EQ(status, E_OK); + + std::vector<UnifiedData> dataSet; + status = UdmfClient::GetInstance().GetBatchData(queryOption, dataSet); + std::shared_ptr<UnifiedRecord> record2 = dataSet[0].GetRecordAt(0); + ASSERT_NE(record2, nullptr); + auto type = record2->GetType(); + ASSERT_EQ(type, UDType::PLAIN_TEXT); + auto plainText2 = static_cast<PlainText *>(record2.get()); + ASSERT_EQ(plainText2->GetContent(), "content"); + + LOG_INFO(UDMF_TEST, "UpdateData002 end."); +} + +/** +* @tc.name: QueryData001 +* @tc.desc: Query data with invalid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, QueryData001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "QueryData001 begin."); + std::vector<UnifiedData> unifiedDataSet; + QueryOption queryOption = {}; + auto status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://drag/ohos.test.demo1/abcde" }; + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .intention = UD_INTENTION_DRAG }; + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://SuperHub/ohos.test.demo1/abcde", .intention = UD_INTENTION_DRAG }; + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://drag/ohos.test.demo1/abcde", .intention = UD_INTENTION_SUPER_HUB }; + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + LOG_INFO(UDMF_TEST, "QueryData001 end."); +} + +/** +* @tc.name: QueryData002 +* @tc.desc: Query data with valid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, QueryData002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "QueryData002 begin."); + + QueryOption query = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + std::vector<UnifiedData> unifiedDataSet; + auto status = UdmfClient::GetInstance().DeleteData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + unifiedDataSet.clear(); + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + ASSERT_TRUE(unifiedDataSet.empty()); + + CustomOption customOption = { .intention = Intention::UD_INTENTION_SUPER_HUB }; + UnifiedData data; + PlainText plainText; + plainText.SetContent("content1"); + std::shared_ptr<UnifiedRecord> record = std::make_shared<PlainText>(plainText); + data.AddRecord(record); + std::string key; + status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + + query = { .key = key }; + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + auto size = static_cast<int32_t>(unifiedDataSet.size()); + ASSERT_EQ(size, 1); + std::shared_ptr<UnifiedRecord> record2 = unifiedDataSet[0].GetRecordAt(0); + ASSERT_NE(record2, nullptr); + auto type = record2->GetType(); + ASSERT_EQ(type, UDType::PLAIN_TEXT); + auto plainText2 = static_cast<PlainText *>(record2.get()); + ASSERT_EQ(plainText2->GetContent(), "content1"); + + UnifiedData data2; + plainText.SetContent("content2"); + record = std::make_shared<PlainText>(plainText); + data2.AddRecord(record); + status = UdmfClient::GetInstance().SetData(customOption, data2, key); + ASSERT_EQ(status, E_OK); + + unifiedDataSet.clear(); + query = { .key = key, .intention = UD_INTENTION_SUPER_HUB }; + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + size = static_cast<int32_t>(unifiedDataSet.size()); + ASSERT_EQ(size, 1); + record2 = unifiedDataSet[0].GetRecordAt(0); + ASSERT_NE(record2, nullptr); + type = record2->GetType(); + ASSERT_EQ(type, UDType::PLAIN_TEXT); + plainText2 = static_cast<PlainText *>(record2.get()); + ASSERT_EQ(plainText2->GetContent(), "content2"); + + unifiedDataSet.clear(); + query = { .intention = UD_INTENTION_SUPER_HUB }; + status = UdmfClient::GetInstance().GetBatchData(query, unifiedDataSet); + ASSERT_EQ(status, E_OK); + size = static_cast<int32_t>(unifiedDataSet.size()); + ASSERT_EQ(size, 2); + + LOG_INFO(UDMF_TEST, "QueryData002 end."); +} + +/** +* @tc.name: DeleteData001 +* @tc.desc: Delete data with invalid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, DeleteData001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DeleteData001 begin."); + std::vector<UnifiedData> unifiedDataSet; + QueryOption queryOption = {}; + auto status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://drag/ohos.test.demo1/abcde" }; + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .intention = UD_INTENTION_DRAG }; + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://SuperHub/ohos.test.demo1/abcde", .intention = UD_INTENTION_DRAG }; + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + + queryOption = { .key = "udmf://drag/ohos.test.demo1/abcde", .intention = UD_INTENTION_SUPER_HUB }; + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_INVALID_PARAMETERS); + LOG_INFO(UDMF_TEST, "DeleteData001 end."); +} + +/** +* @tc.name: DeleteData002 +* @tc.desc: Delete data with valid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, DeleteData002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DeleteData002 begin."); + + CustomOption customOption = { .intention = UD_INTENTION_SUPER_HUB }; + UnifiedData data; + PlainText plainText; + plainText.SetContent("content1"); + std::shared_ptr<UnifiedRecord> record = std::make_shared<PlainText>(plainText); + data.AddRecord(record); + std::string key; + auto status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + + QueryOption queryOption = { .key = key }; + SetHapToken2(); + + std::vector<UnifiedData> unifiedDataSet; + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_OK); + + unifiedDataSet.clear(); + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_TRUE(unifiedDataSet.empty()); + + queryOption = { .intention = UD_INTENTION_SUPER_HUB }; + unifiedDataSet.clear(); + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_TRUE(!unifiedDataSet.empty()); + + status = UdmfClient::GetInstance().DeleteData(queryOption, unifiedDataSet); + ASSERT_EQ(status, E_OK); + + unifiedDataSet.clear(); + status = UdmfClient::GetInstance().GetBatchData(queryOption, unifiedDataSet); + ASSERT_TRUE(unifiedDataSet.empty()); + LOG_INFO(UDMF_TEST, "DeleteData002 end."); +} } // OHOS::Test \ No newline at end of file diff --git a/framework/jskitsimpl/common/napi_data_utils.cpp b/framework/jskitsimpl/common/napi_data_utils.cpp index 2d895a0..d8eb507 100644 --- a/framework/jskitsimpl/common/napi_data_utils.cpp +++ b/framework/jskitsimpl/common/napi_data_utils.cpp @@ -383,6 +383,16 @@ bool NapiDataUtils::IsTypeForNapiValue(napi_env env, napi_value param, napi_valu return valueType == expectType; } +bool NapiDataUtils::IsNull(napi_env env, napi_value value) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, value, &type); + if (status == napi_ok && (type == napi_undefined || type == napi_null)) { + return true; + } + return false; +} + napi_value NapiDataUtils::DefineClass(napi_env env, const std::string &name, const napi_property_descriptor *properties, size_t count, napi_callback newcb) { diff --git a/framework/jskitsimpl/common/napi_error_utils.cpp b/framework/jskitsimpl/common/napi_error_utils.cpp index 1787e05..6b43b7e 100644 --- a/framework/jskitsimpl/common/napi_error_utils.cpp +++ b/framework/jskitsimpl/common/napi_error_utils.cpp @@ -22,12 +22,8 @@ namespace UDMF { using NapiErrorCode = OHOS::UDMF::NapiErrorCode; static const NapiErrorCode JS_ERROR_CODE_MSGS[] = { + { Status::E_NO_PERMISSION, 201, "Permission denied!" }, { Status::E_INVALID_PARAMETERS, 401, "Parameter error." }, - { Status::E_ERROR, 20400001, "NAPI failed!" }, - { Status::E_FORBIDDEN, 20400002, "Unsupported!" }, - { Status::E_NO_PERMISSION, 20400003, "Have no permission!" }, - { Status::E_INVALID_OPERATION, 20400004, "Invalid operation failed!" }, - { Status::E_UNKNOWN, 20400005, "Unknown failed!" }, }; const std::optional<NapiErrorCode> GetErrorCode(int32_t errorCode) diff --git a/framework/jskitsimpl/common/napi_queue.cpp b/framework/jskitsimpl/common/napi_queue.cpp index baaa332..63b63ce 100644 --- a/framework/jskitsimpl/common/napi_queue.cpp +++ b/framework/jskitsimpl/common/napi_queue.cpp @@ -77,51 +77,50 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr<ContextBase> ctxt, LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork name = %{public}s", name.c_str()); ctxt->execute = std::move(execute); ctxt->complete = std::move(complete); - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork move func finish"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork move func finish"); napi_value promise = nullptr; if (ctxt->callbackRef == nullptr) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork has promise"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork has promise"); napi_create_promise(ctxt->env, &ctxt->deferred, &promise); LOG_DEBUG(UDMF_KITS_NAPI, "create deferred promise"); } else { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork no promise"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork no promise"); napi_get_undefined(ctxt->env, &promise); } - napi_value resource = nullptr; - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork create string start"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork create string start"); napi_create_string_utf8(ctxt->env, name.c_str(), NAPI_AUTO_LENGTH, &resource); - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork create string finish"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork create string finish"); napi_create_async_work(ctxt->env, nullptr, resource, [](napi_env env, void *data) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork start execute"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork start execute"); ASSERT_VOID(data != nullptr, "no data"); - auto ctxt = reinterpret_cast<ContextBase*>(data); + auto ctxt = reinterpret_cast<ContextBase *>(data); LOG_DEBUG(UDMF_KITS_NAPI, "napi_async_execute_callback ctxt->status = %{public}d", ctxt->status); if (ctxt->execute && ctxt->status == napi_ok) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork do user design execute"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork do user design execute"); ctxt->execute(); } - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork finish execute"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork finish execute"); }, [](napi_env env, napi_status status, void *data) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork start output"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork start output"); ASSERT_VOID(data != nullptr, "no data"); - auto ctxt = reinterpret_cast<ContextBase*>(data); + auto ctxt = reinterpret_cast<ContextBase *>(data); LOG_DEBUG(UDMF_KITS_NAPI, "napi_async_complete_callback status = %{public}d, ctxt->status = %{public}d", status, ctxt->status); if ((status != napi_ok) && (ctxt->status == napi_ok)) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork check status"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork check status"); ctxt->status = status; } if ((ctxt->complete) && (status == napi_ok) && (ctxt->status == napi_ok)) { - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork do user design output"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork do user design output"); ctxt->complete(ctxt->output); } GenerateOutput(ctxt); - LOG_INFO(UDMF_KITS_NAPI, "NapiQueue::AsyncWork finish output"); + LOG_DEBUG(UDMF_KITS_NAPI, "NapiQueue::AsyncWork finish output"); }, - reinterpret_cast<void*>(ctxt.get()), &ctxt->work); + reinterpret_cast<void *>(ctxt.get()), &ctxt->work); napi_queue_async_work(ctxt->env, ctxt->work); ctxt->hold = ctxt; // save crossing-thread ctxt. return promise; @@ -129,9 +128,9 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr<ContextBase> ctxt, void NapiQueue::GenerateOutput(ContextBase *ctxt) { - LOG_INFO(UDMF_KITS_NAPI, "GenerateOutput start"); + LOG_DEBUG(UDMF_KITS_NAPI, "GenerateOutput start"); napi_value result[RESULT_ALL] = { nullptr }; - LOG_INFO(UDMF_KITS_NAPI, "GenerateOutput ctxt->status = %{public}d", ctxt->status); + LOG_DEBUG(UDMF_KITS_NAPI, "GenerateOutput ctxt->status = %{public}d", ctxt->status); if (ctxt->status == napi_ok) { napi_get_undefined(ctxt->env, &result[RESULT_ERROR]); if (ctxt->output == nullptr) { @@ -139,13 +138,21 @@ void NapiQueue::GenerateOutput(ContextBase *ctxt) } result[RESULT_DATA] = ctxt->output; } else { + napi_value code = nullptr; napi_value message = nullptr; + if (ctxt->jsCode != 0 && ctxt->jsCode != -1) { + napi_create_string_utf8(ctxt->env, std::to_string(ctxt->jsCode).c_str(), NAPI_AUTO_LENGTH, &code); + } + if (ctxt->jsCode == -1) { + std::string jsCode; + napi_create_string_utf8(ctxt->env, jsCode.c_str(), NAPI_AUTO_LENGTH, &code); + } napi_create_string_utf8(ctxt->env, ctxt->error.c_str(), NAPI_AUTO_LENGTH, &message); - napi_create_error(ctxt->env, nullptr, message, &result[RESULT_ERROR]); + napi_create_error(ctxt->env, code, message, &result[RESULT_ERROR]); napi_get_undefined(ctxt->env, &result[RESULT_DATA]); } if (ctxt->deferred != nullptr) { - LOG_INFO(UDMF_KITS_NAPI, "GenerateOutput deferred branch"); + LOG_DEBUG(UDMF_KITS_NAPI, "GenerateOutput deferred branch"); if (ctxt->status == napi_ok) { LOG_DEBUG(UDMF_KITS_NAPI, "deferred promise resolved"); napi_resolve_deferred(ctxt->env, ctxt->deferred, result[RESULT_DATA]); @@ -162,7 +169,7 @@ void NapiQueue::GenerateOutput(ContextBase *ctxt) napi_call_function(ctxt->env, nullptr, callback, RESULT_ALL, result, &callbackResult); } ctxt->hold.reset(); // release ctxt. - LOG_INFO(UDMF_KITS_NAPI, "GenerateOutput stop"); + LOG_DEBUG(UDMF_KITS_NAPI, "GenerateOutput stop"); } } // namespace UDMF } // namespace OHOS diff --git a/framework/jskitsimpl/data/udmf_napi.cpp b/framework/jskitsimpl/data/udmf_napi.cpp index f956426..9dc0c00 100644 --- a/framework/jskitsimpl/data/udmf_napi.cpp +++ b/framework/jskitsimpl/data/udmf_napi.cpp @@ -17,6 +17,9 @@ #include "napi_data_utils.h" #include "napi_error_utils.h" #include "napi_queue.h" +#include "udmf_client.h" +#include "unified_data_napi.h" +#include "unified_meta.h" namespace OHOS { namespace UDMF { @@ -24,6 +27,11 @@ napi_value UDMFNapi::UDMFInit(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { DECLARE_NAPI_GETTER("UnifiedDataType", CreateUnifiedDataType), + DECLARE_NAPI_GETTER("Intention", CreateIntention), + DECLARE_NAPI_FUNCTION("insertData", InsertData), + DECLARE_NAPI_FUNCTION("updateData", UpdateData), + DECLARE_NAPI_FUNCTION("queryData", QueryData), + DECLARE_NAPI_FUNCTION("deleteData", DeleteData), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); @@ -57,6 +65,16 @@ napi_value UDMFNapi::CreateUnifiedDataType(napi_env env, napi_callback_info info return unifiedDataType; } +napi_value UDMFNapi::CreateIntention(napi_env env, napi_callback_info info) +{ + napi_value intention = nullptr; + napi_create_object(env, &intention); + SetNamedProperty(env, intention, JS_UD_INTENTION_NAME_MAP.at(UD_INTENTION_SUPER_HUB), + UD_INTENTION_MAP.at(UD_INTENTION_SUPER_HUB)); + napi_object_freeze(env, intention); + return intention; +} + napi_status UDMFNapi::SetNamedProperty(napi_env env, napi_value &obj, const std::string &name, const std::string &value) { napi_value property = nullptr; @@ -66,5 +84,199 @@ napi_status UDMFNapi::SetNamedProperty(napi_env env, napi_value &obj, const std: ASSERT(status == napi_ok, "napi_set_named_property failed!", status); return status; } + +napi_value UDMFNapi::InsertData(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "InsertData is called!"); + struct InsertContext : public ContextBase { + std::string key; + Intention intention; + std::shared_ptr<UnifiedData> unifiedData; + }; + std::string intention; + auto unifiedDataNapi = new (std::nothrow) UnifiedDataNapi(); + auto ctxt = std::make_shared<InsertContext>(); + auto input = [env, ctxt, &intention, &unifiedDataNapi](size_t argc, napi_value *argv) { + // require 2 arguments <options, unifiedData> + ASSERT_WITH_ERRCODE(ctxt, argc >= 2, E_INVALID_PARAMETERS, "invalid arguments!"); + ctxt->status = GetNamedProperty(env, argv[0], "intention", intention); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok && UnifiedDataUtils::IsPersist(intention), + E_INVALID_PARAMETERS, "invalid arg[0], i.e. invalid intention!"); + ctxt->status = napi_unwrap(env, argv[1], reinterpret_cast<void **>(&unifiedDataNapi)); + ASSERT_WITH_ERRCODE( + ctxt, ctxt->status == napi_ok, E_INVALID_PARAMETERS, "invalid arg[1], i.e. invalid unifiedData!"); + }; + ctxt->GetCbInfo(env, info, input); + ctxt->unifiedData = unifiedDataNapi->value_; + ctxt->intention = UnifiedDataUtils::GetIntentionByString(intention); + auto execute = [ctxt]() { + CustomOption option = { .intention = ctxt->intention }; + auto status = UdmfClient::GetInstance().SetData(option, *(ctxt->unifiedData), ctxt->key); + ASSERT_WITH_ERRCODE(ctxt, status == E_OK, E_UNKNOWN, "InsertData failed!"); + }; + + auto output = [env, ctxt](napi_value &result) { + ctxt->status = NapiDataUtils::SetValue(env, ctxt->key, result); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_UNKNOWN, "output failed!"); + }; + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output); +} + +napi_value UDMFNapi::UpdateData(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "UpdateData is called!"); + struct UpdateContext : public ContextBase { + std::string key; + std::shared_ptr<UnifiedData> unifiedData; + }; + std::string key; + auto unifiedDataNapi = new (std::nothrow) UnifiedDataNapi(); + auto ctxt = std::make_shared<UpdateContext>(); + auto input = [env, ctxt, &unifiedDataNapi](size_t argc, napi_value *argv) { + // require 2 arguments <options, unifiedData> + ASSERT_WITH_ERRCODE(ctxt, argc >= 2, E_INVALID_PARAMETERS, "invalid arguments!"); + ctxt->status = GetNamedProperty(env, argv[0], "key", ctxt->key); + UnifiedKey key(ctxt->key); + ASSERT_WITH_ERRCODE(ctxt, + ctxt->status == napi_ok && key.IsValid() && UnifiedDataUtils::IsPersist(key.intention), + E_INVALID_PARAMETERS, "invalid arg[0], i.e. invalid key!"); + ctxt->status = napi_unwrap(env, argv[1], reinterpret_cast<void **>(&unifiedDataNapi)); + ASSERT_WITH_ERRCODE( + ctxt, ctxt->status == napi_ok, E_INVALID_PARAMETERS, "invalid arg[1], i.e. invalid unifiedData!"); + }; + ctxt->GetCbInfo(env, info, input); + ctxt->unifiedData = unifiedDataNapi->value_; + auto execute = [ctxt]() { + QueryOption option = { .key = ctxt->key }; + auto status = UdmfClient::GetInstance().UpdateData(option, *(ctxt->unifiedData)); + ASSERT_WITH_ERRCODE(ctxt, status == E_OK, E_UNKNOWN, "UpdateData failed!"); + }; + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute); +} + +napi_value UDMFNapi::QueryData(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "QueryData is called!"); + struct QueryContext : public ContextBase { + std::string key; + Intention intention; + std::vector<UnifiedData> unifiedDataSet; + }; + std::string intention; + auto ctxt = std::make_shared<QueryContext>(); + auto input = [env, ctxt, &intention](size_t argc, napi_value *argv) { + // require 1 arguments <options> + ASSERT_WITH_ERRCODE(ctxt, argc >= 1, E_INVALID_PARAMETERS, "invalid arguments!"); + napi_status keyStatus; + napi_status intentionStatus; + auto options = argv[0]; + keyStatus = GetNamedProperty(env, options, "key", ctxt->key); + intentionStatus = GetNamedProperty(env, options, "intention", intention); + ASSERT_WITH_ERRCODE(ctxt, + (keyStatus == napi_ok || intentionStatus == napi_ok) + && UnifiedDataUtils::IsValidOptions(ctxt->key, intention), + E_INVALID_PARAMETERS, "invalid arg[0], i.e. invalid options!"); + }; + ctxt->GetCbInfo(env, info, input); + ctxt->intention = UnifiedDataUtils::GetIntentionByString(intention); + auto execute = [env, ctxt]() { + QueryOption option = { + .key = ctxt->key, + .intention = ctxt->intention, + }; + auto status = UdmfClient::GetInstance().GetBatchData(option, ctxt->unifiedDataSet); + LOG_DEBUG(UDMF_SERVICE, "GetBatchData : status = %{public}d!", status); + ASSERT_WITH_ERRCODE(ctxt, status == E_OK, E_UNKNOWN, "QueryData failed!"); + }; + auto output = [env, ctxt](napi_value &result) { + ASSERT_WITH_ERRCODE(ctxt, !ctxt->unifiedDataSet.empty(), E_UNKNOWN, "unifiedDataSet is empty!"); + ctxt->status = napi_create_array_with_length(env, ctxt->unifiedDataSet.size(), &ctxt->output); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_UNKNOWN, "napi_create_array_with_length failed!"); + int index = 0; + for (const UnifiedData &data : ctxt->unifiedDataSet) { + std::shared_ptr<UnifiedData> unifiedData = std::make_shared<UnifiedData>(); + unifiedData->SetRecords(data.GetRecords()); + napi_value dataNapi = nullptr; + UnifiedDataNapi::NewInstance(env, unifiedData, dataNapi); + ctxt->status = napi_set_element(env, ctxt->output, index++, dataNapi); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_UNKNOWN, "napi_set_element failed!"); + } + result = ctxt->output; + }; + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output); +} + +napi_value UDMFNapi::DeleteData(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "DeleteData is called!"); + struct DeleteContext : public ContextBase { + std::string key; + Intention intention; + std::vector<UnifiedData> unifiedDataSet; + }; + std::string intention; + auto ctxt = std::make_shared<DeleteContext>(); + auto input = [env, ctxt, &intention](size_t argc, napi_value *argv) { + // require 1 arguments <options> + ASSERT_WITH_ERRCODE(ctxt, argc >= 1, E_INVALID_PARAMETERS, "invalid arguments!"); + napi_status keyStatus; + napi_status intentionStatus; + napi_value options = argv[0]; + keyStatus = GetNamedProperty(env, options, "key", ctxt->key); + intentionStatus = GetNamedProperty(env, options, "intention", intention); + ASSERT_WITH_ERRCODE(ctxt, + (keyStatus == napi_ok || intentionStatus == napi_ok) + && UnifiedDataUtils::IsValidOptions(ctxt->key, intention), + E_INVALID_PARAMETERS, "invalid arg[0], i.e. invalid options!"); + }; + ctxt->GetCbInfo(env, info, input); + ctxt->intention = UnifiedDataUtils::GetIntentionByString(intention); + auto execute = [env, ctxt]() { + QueryOption option = { + .key = ctxt->key, + .intention = ctxt->intention, + }; + auto status = UdmfClient::GetInstance().DeleteData(option, ctxt->unifiedDataSet); + ASSERT_WITH_ERRCODE(ctxt, status == E_OK, E_UNKNOWN, "DeleteData failed!"); + }; + + auto output = [env, ctxt](napi_value &result) { + ASSERT_WITH_ERRCODE(ctxt, !ctxt->unifiedDataSet.empty(), E_UNKNOWN, "unifiedDataSet is empty!"); + ctxt->status = napi_create_array_with_length(env, ctxt->unifiedDataSet.size(), &ctxt->output); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_UNKNOWN, "napi_create_array_with_length failed!"); + int index = 0; + for (const UnifiedData &data : ctxt->unifiedDataSet) { + std::shared_ptr<UnifiedData> unifiedData = std::make_shared<UnifiedData>(); + unifiedData->SetRecords(data.GetRecords()); + napi_value dataNapi = nullptr; + UnifiedDataNapi::NewInstance(env, unifiedData, dataNapi); + ctxt->status = napi_set_element(env, ctxt->output, index++, dataNapi); + ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_UNKNOWN, "napi_set_element failed!"); + } + result = ctxt->output; + }; + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output); +} + +napi_status UDMFNapi::GetNamedProperty(napi_env env, napi_value &obj, const std::string &key, std::string &value) +{ + bool hasKey = false; + napi_status status = napi_has_named_property(env, obj, key.c_str(), &hasKey); + if (status != napi_ok) { + return napi_generic_failure; + } + if (!hasKey) { + return napi_generic_failure; + } + napi_value napiValue = nullptr; + status = napi_get_named_property(env, obj, key.c_str(), &napiValue); + if (status != napi_ok || napiValue == nullptr) { + return napi_generic_failure; + } + if (NapiDataUtils::IsNull(env, napiValue)) { + return napi_ok; + } + return NapiDataUtils::GetValue(env, napiValue, value); +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/framework/manager/data_manager.cpp b/framework/manager/data_manager.cpp index ed7f609..fff84b0 100755 --- a/framework/manager/data_manager.cpp +++ b/framework/manager/data_manager.cpp @@ -15,16 +15,17 @@ #include "data_manager.h" +#include "checker_manager.h" +#include "file.h" #include "lifecycle/lifecycle_manager.h" #include "logger.h" #include "preprocess_utils.h" -#include "checker_manager.h" -#include "file.h" #include "uri_permission_manager.h" namespace OHOS { namespace UDMF { const std::string MSDP_PROCESS_NAME = "msdp_sa"; +const std::string DATA_PREFIX = "udmf://"; DataManager::DataManager() { authorizationMap_[UD_INTENTION_MAP.at(UD_INTENTION_DRAG)] = MSDP_PROCESS_NAME; @@ -70,7 +71,7 @@ int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, st return E_DB_ERROR; } - if (store->Clear() != E_OK) { + if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) { LOG_ERROR(UDMF_FRAMEWORK, "Clear store failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; } @@ -83,7 +84,7 @@ int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, st return E_OK; } -int32_t DataManager::RetrieveData(QueryOption &query, UnifiedData &unifiedData) +int32_t DataManager::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) { UnifiedKey key(query.key); if (!key.IsValid()) { @@ -136,7 +137,93 @@ int32_t DataManager::RetrieveData(QueryOption &query, UnifiedData &unifiedData) return E_OK; } -int32_t DataManager::GetSummary(QueryOption &query, Summary &summary) +int32_t DataManager::RetrieveBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + std::vector<UnifiedData> dataSet; + std::shared_ptr<Store> store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + LOG_DEBUG(UDMF_FRAMEWORK, "has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), + query.intention); + return E_OK; + } + for (const auto &data : dataSet) { + unifiedDataSet.push_back(data); + } + return E_OK; +} + +int32_t DataManager::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + LOG_ERROR(UDMF_FRAMEWORK, "Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData data; + int32_t res = store->Get(query.key, data); + if (res != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Get data from store failed, intention: %{public}s.", key.intention.c_str()); + return res; + } + + if (data.IsEmpty()) { + LOG_ERROR(UDMF_FRAMEWORK, "Invalid parameters, unified data has no record, intention: %{public}s.", + key.intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::shared_ptr<Runtime> runtime = data.GetRuntime(); + + runtime->lastModifiedTime = PreProcessUtils::GetInstance().GetTimeStamp(); + unifiedData.SetRuntime(*runtime); + for (const auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::GetInstance().IdGenerator()); + } + if (store->Update(unifiedData) != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Update unified data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} +int32_t DataManager::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + std::vector<UnifiedData> dataSet; + std::shared_ptr<Store> store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + LOG_DEBUG(UDMF_FRAMEWORK, "has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), + query.intention); + return E_OK; + } + std::shared_ptr<Runtime> runtime; + std::vector<std::string> deleteKeys; + for (const auto &data : dataSet) { + runtime = data.GetRuntime(); + unifiedDataSet.push_back(data); + deleteKeys.push_back(runtime->key.key); + } + if (store->DeleteBatch(deleteKeys) != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Remove data failed."); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t DataManager::GetSummary(const QueryOption &query, Summary &summary) { UnifiedKey key(query.key); if (!key.IsValid()) { @@ -157,7 +244,7 @@ int32_t DataManager::GetSummary(QueryOption &query, Summary &summary) return E_OK; } -int32_t DataManager::AddPrivilege(QueryOption &query, const Privilege &privilege) +int32_t DataManager::AddPrivilege(const QueryOption &query, const Privilege &privilege) { UnifiedKey key(query.key); if (!key.IsValid()) { @@ -224,5 +311,35 @@ int32_t DataManager::Sync(const QueryOption &query, const std::vector<std::strin } return E_OK; } + +int32_t DataManager::QueryDataCommon( + const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store) +{ + auto find = UD_INTENTION_MAP.find(query.intention); + std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; + if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + LOG_ERROR(UDMF_FRAMEWORK, "Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), + intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::string dataPrefix = DATA_PREFIX + intention; + UnifiedKey key(query.key); + key.IsValid(); + if (intention.empty()) { + dataPrefix = key.key; + intention = key.intention; + } + LOG_DEBUG(UDMF_FRAMEWORK, "dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str()); + store = storeCache_.GetStore(intention); + if (store == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); + return E_DB_ERROR; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/framework/manager/data_manager.h b/framework/manager/data_manager.h index c63a1f4..d9a8e26 100755 --- a/framework/manager/data_manager.h +++ b/framework/manager/data_manager.h @@ -35,13 +35,17 @@ public: static DataManager &GetInstance(); int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); - int32_t RetrieveData(QueryOption &query, UnifiedData &unifiedData); - int32_t GetSummary(QueryOption &query, Summary &summary); - int32_t AddPrivilege(QueryOption &query, const Privilege &privilege); + int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); + int32_t RetrieveBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet); + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData); + int32_t DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet); + int32_t GetSummary(const QueryOption &query, Summary &summary); + int32_t AddPrivilege(const QueryOption &query, const Privilege &privilege); int32_t Sync(const QueryOption &query, const std::vector<std::string> &devices); private: DataManager(); + int32_t QueryDataCommon(const QueryOption &query, std::vector<UnifiedData> &datas, std::shared_ptr<Store> &store); StoreCache storeCache_; std::map<std::string, std::string> authorizationMap_; }; diff --git a/framework/manager/lifecycle/lifecycle_policy.cpp b/framework/manager/lifecycle/lifecycle_policy.cpp index caaea62..5a4313a 100644 --- a/framework/manager/lifecycle/lifecycle_policy.cpp +++ b/framework/manager/lifecycle/lifecycle_policy.cpp @@ -58,7 +58,12 @@ Status LifeCyclePolicy::DeleteOnTimeout(const std::string &intention) LOG_ERROR(UDMF_FRAMEWORK, "Get store failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; } - auto timeoutKeys = GetTimeoutKeys(store, INTERVAL); + std::vector<std::string> timeoutKeys; + auto status = GetTimeoutKeys(store, INTERVAL, timeoutKeys); + if (status != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Get timeout keys failed."); + return E_DB_ERROR; + } if (store->DeleteBatch(timeoutKeys) != E_OK) { LOG_ERROR(UDMF_FRAMEWORK, "Remove data failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; @@ -66,13 +71,18 @@ Status LifeCyclePolicy::DeleteOnTimeout(const std::string &intention) return E_OK; } -std::vector<std::string> LifeCyclePolicy::GetTimeoutKeys(const std::shared_ptr<Store> &store, Duration interval) +Status LifeCyclePolicy::GetTimeoutKeys( + const std::shared_ptr<Store> &store, Duration interval, std::vector<std::string> &timeoutKeys) { - std::vector<UnifiedData> datas = store->GetDatas(DATA_PREFIX); - std::vector<std::string> timeoutKeys; + std::vector<UnifiedData> datas; + auto status = store->GetBatchData(DATA_PREFIX, datas); + if (status != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "Get datas failed."); + return E_DB_ERROR; + } if (datas.empty()) { LOG_DEBUG(UDMF_FRAMEWORK, "entries is empty."); - return timeoutKeys; + return E_OK; } auto curTime = PreProcessUtils::GetInstance().GetTimeStamp(); for (const auto &data : datas) { @@ -81,7 +91,7 @@ std::vector<std::string> LifeCyclePolicy::GetTimeoutKeys(const std::shared_ptr<S timeoutKeys.push_back(data.GetRuntime()->key.key); } } - return timeoutKeys; + return E_OK; } } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/framework/manager/lifecycle/lifecycle_policy.h b/framework/manager/lifecycle/lifecycle_policy.h index 8289013..c0168b1 100644 --- a/framework/manager/lifecycle/lifecycle_policy.h +++ b/framework/manager/lifecycle/lifecycle_policy.h @@ -33,7 +33,8 @@ public: virtual Status DeleteOnGet(const UnifiedKey &key); virtual Status DeleteOnStart(const std::string &intention); virtual Status DeleteOnTimeout(const std::string &intention); - virtual std::vector<std::string> GetTimeoutKeys(const std::shared_ptr<Store> &store, Duration interval); + virtual Status GetTimeoutKeys( + const std::shared_ptr<Store> &store, Duration interval, std::vector<std::string> &timeoutKeys); private: static const std::string DATA_PREFIX; diff --git a/framework/manager/preprocess/preprocess_utils.cpp b/framework/manager/preprocess/preprocess_utils.cpp index 3e04784..6962c69 100755 --- a/framework/manager/preprocess/preprocess_utils.cpp +++ b/framework/manager/preprocess/preprocess_utils.cpp @@ -24,6 +24,7 @@ namespace OHOS { namespace UDMF { static constexpr int ID_LEN = 32; +const char SPECIAL = '^'; PreProcessUtils &PreProcessUtils::GetInstance() { static auto instance = new PreProcessUtils(); @@ -57,11 +58,13 @@ std::string PreProcessUtils::IdGenerator() { std::random_device randomDevice; int minimum = 48; - int maximum = 122; + int maximum = 121; std::uniform_int_distribution<int> distribution(minimum, maximum); std::stringstream idStr; for (int32_t i = 0; i < ID_LEN; i++) { - idStr << static_cast<uint8_t>(distribution(randomDevice)); + auto asc = distribution(randomDevice); + asc = asc >= SPECIAL ? asc + 1 : asc; + idStr << static_cast<uint8_t>(asc); } return idStr.str(); } diff --git a/framework/manager/store/runtime_store.cpp b/framework/manager/store/runtime_store.cpp index 48f6331..1d40c1d 100755 --- a/framework/manager/store/runtime_store.cpp +++ b/framework/manager/store/runtime_store.cpp @@ -75,9 +75,12 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) { - std::vector<Entry> entries = GetEntries(key); + std::vector<Entry> entries; + if (GetEntries(key, entries) != E_OK) { + return E_DB_ERROR; + } if (entries.empty()) { - LOG_DEBUG(UDMF_FRAMEWORK, "KvStore getEntries failed, key: %{public}s.", key.c_str()); + LOG_DEBUG(UDMF_FRAMEWORK, "entries is empty."); return E_OK; } for (const auto &entry : entries) { @@ -131,7 +134,6 @@ Status RuntimeStore::Update(const UnifiedData &unifiedData) LOG_ERROR(UDMF_SERVICE, "Delete unified data failed."); return E_DB_ERROR; } - if (Put(unifiedData) != E_OK) { LOG_ERROR(UDMF_SERVICE, "Put unified data failed."); return E_DB_ERROR; @@ -141,9 +143,12 @@ Status RuntimeStore::Update(const UnifiedData &unifiedData) Status RuntimeStore::Delete(const std::string &key) { - std::vector<Entry> entries = GetEntries(key); + std::vector<Entry> entries; + if (GetEntries(key, entries) != E_OK) { + return E_DB_ERROR; + } if (entries.empty()) { - LOG_DEBUG(UDMF_FRAMEWORK, "KvStore getEntries failed, key: %{public}s.", key.c_str()); + LOG_DEBUG(UDMF_FRAMEWORK, "entries is empty."); return E_OK; } std::vector<Key> keys; @@ -154,17 +159,19 @@ Status RuntimeStore::Delete(const std::string &key) return status; } -Status RuntimeStore::DeleteBatch(const std::vector<std::string> &timeoutKeys) +Status RuntimeStore::DeleteBatch(const std::vector<std::string> &unifiedKeys) { - Status status = E_OK; - if (timeoutKeys.empty()) { + LOG_DEBUG(UDMF_SERVICE, "called!"); + if (unifiedKeys.empty()) { LOG_DEBUG(UDMF_SERVICE, "No need to delete!"); - return status; + return E_OK; } - for (const std::string &timeoutKey : timeoutKeys) { - status = status == E_OK ? Delete(timeoutKey) : status; + for (const std::string &unifiedKey : unifiedKeys) { + if (Delete(unifiedKey) != E_OK) { + return E_DB_ERROR; + } } - return status; + return E_OK; } Status RuntimeStore::Sync(const std::vector<std::string> &devices) @@ -183,6 +190,29 @@ Status RuntimeStore::Clear() return Delete(DATA_PREFIX) != E_DB_ERROR ? E_OK : E_DB_ERROR; } +Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector<UnifiedData> &unifiedDataSet) +{ + std::vector<Entry> entries; + auto status = GetEntries(dataPrefix, entries); + if (status != E_OK) { + LOG_ERROR(UDMF_FRAMEWORK, "GetEntries failed."); + return E_DB_ERROR; + } + if (entries.empty()) { + LOG_DEBUG(UDMF_FRAMEWORK, "entries is empty."); + return E_OK; + } + for (const auto &entry : entries) { + UnifiedData data; + std::string keyStr = entry.key.ToString(); + if (std::count(keyStr.begin(), keyStr.end(), '/') == SLASH_COUNT_IN_KEY) { + status = Get(keyStr, data); + unifiedDataSet.push_back(data); + } + } + return status; +} + void RuntimeStore::Close() { dataManager_.CloseKvStore(APP_ID, storeId_); @@ -208,36 +238,17 @@ bool RuntimeStore::Init() return true; } -std::vector<UnifiedData> RuntimeStore::GetDatas(const std::string &dataPrefix) +Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vector<Entry> &entries) { - std::vector<UnifiedData> unifiedDatas; - auto entries = GetEntries(dataPrefix); - if (entries.empty()) { - LOG_DEBUG(UDMF_FRAMEWORK, "entries is empty."); - return unifiedDatas; - } - for (const auto &entry : entries) { - UnifiedData data; - std::string keyStr = entry.key.ToString(); - if (std::count(keyStr.begin(), keyStr.end(), '/') == SLASH_COUNT_IN_KEY) { - Get(keyStr, data); - unifiedDatas.push_back(data); - } - } - return unifiedDatas; -} - -std::vector<Entry> RuntimeStore::GetEntries(const std::string &dataPrefix) -{ - std::vector<Entry> entries; DataQuery query; query.KeyPrefix(dataPrefix); query.OrderByWriteTime(true); auto status = kvStore_->GetEntries(query, entries); if (status != DistributedKv::Status::SUCCESS) { - LOG_DEBUG(UDMF_SERVICE, "KvStore getEntries failed, status: %{public}d.", static_cast<int>(status)); + LOG_ERROR(UDMF_SERVICE, "KvStore getEntries failed, status: %{public}d.", static_cast<int>(status)); + return E_DB_ERROR; } - return entries; + return E_OK; } Status RuntimeStore::PutEntries(const std::vector<Entry> &entries) @@ -245,9 +256,9 @@ Status RuntimeStore::PutEntries(const std::vector<Entry> &entries) size_t size = entries.size(); DistributedKv::Status status; for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector<Entry> batchEntries(entries.begin() + index, - entries.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->PutBatch(batchEntries); + std::vector<Entry> batchEntries( + entries.begin() + index, entries.begin() + std::min(index + MAX_BATCH_SIZE, size)); + status = kvStore_->PutBatch(batchEntries); if (status != DistributedKv::Status::SUCCESS) { LOG_ERROR(UDMF_SERVICE, "KvStore putBatch failed, status: %{public}d.", status); return E_DB_ERROR; @@ -261,9 +272,8 @@ Status RuntimeStore::DeleteEntries(const std::vector<Key> &keys) size_t size = keys.size(); DistributedKv::Status status; for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector<Key> batchKeys(keys.begin() + index, - keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->DeleteBatch(batchKeys); + std::vector<Key> batchKeys(keys.begin() + index, keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); + status = kvStore_->DeleteBatch(batchKeys); if (status != DistributedKv::Status::SUCCESS) { LOG_ERROR(UDMF_SERVICE, "KvStore deleteBatch failed, status: %{public}d.", status); return E_DB_ERROR; diff --git a/framework/manager/store/runtime_store.h b/framework/manager/store/runtime_store.h index ff21586..04aa472 100755 --- a/framework/manager/store/runtime_store.h +++ b/framework/manager/store/runtime_store.h @@ -18,6 +18,7 @@ #include "distributed_kv_data_manager.h" #include "single_kvstore.h" + #include "store.h" namespace OHOS { @@ -31,12 +32,12 @@ public: Status GetSummary(const std::string &key, Summary &summary) override; Status Update(const UnifiedData &unifiedData) override; Status Delete(const std::string &key) override; - Status DeleteBatch(const std::vector<std::string> &timeoutKeys) override; + Status DeleteBatch(const std::vector<std::string> &unifiedKeys) override; Status Sync(const std::vector<std::string> &devices) override; Status Clear() override; + Status GetBatchData(const std::string &dataPrefix, std::vector<UnifiedData> &unifiedDataSet) override; void Close() override; bool Init() override; - std::vector<UnifiedData> GetDatas(const std::string &dataPrefix) override; private: static const DistributedKv::AppId APP_ID; @@ -47,7 +48,7 @@ private: DistributedKv::DistributedKvDataManager dataManager_; std::shared_ptr<DistributedKv::SingleKvStore> kvStore_; DistributedKv::StoreId storeId_; - std::vector<DistributedKv::Entry> GetEntries(const std::string &dataPrefix); + Status GetEntries(const std::string &dataPrefix, std::vector<DistributedKv::Entry> &entries); Status PutEntries(const std::vector<DistributedKv::Entry> &entries); Status DeleteEntries(const std::vector<DistributedKv::Key> &keys); }; diff --git a/framework/manager/store/store.h b/framework/manager/store/store.h index de2b8e3..0a74850 100755 --- a/framework/manager/store/store.h +++ b/framework/manager/store/store.h @@ -17,10 +17,11 @@ #define UDMF_STORE_H #include <string> + #include "error_code.h" -#include "unified_types.h" #include "unified_data.h" #include "unified_key.h" +#include "unified_types.h" namespace OHOS { namespace UDMF { @@ -31,12 +32,12 @@ public: virtual Status GetSummary(const std::string &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<std::string> &timeoutKeys) = 0; + virtual Status DeleteBatch(const std::vector<std::string> &unifiedKeys) = 0; virtual Status Sync(const std::vector<std::string> &devices) = 0; virtual Status Clear() = 0; virtual bool Init() = 0; virtual void Close() = 0; - virtual std::vector<UnifiedData> GetDatas(const std::string &dataPrefix) = 0; + virtual Status GetBatchData(const std::string &dataPrefix, std::vector<UnifiedData> &unifiedDataSet) = 0; }; } // namespace UDMF } // namespace OHOS diff --git a/framework/manager/store/store_cache.cpp b/framework/manager/store/store_cache.cpp index ad60914..e82f979 100755 --- a/framework/manager/store/store_cache.cpp +++ b/framework/manager/store/store_cache.cpp @@ -30,7 +30,8 @@ std::shared_ptr<Store> StoreCache::GetStore(std::string intention) return true; } - if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG) + || intention == UD_INTENTION_MAP.at(UD_INTENTION_SUPER_HUB)) { storePtr = std::make_shared<RuntimeStore>(intention); if (!storePtr->Init()) { LOG_ERROR(UDMF_SERVICE, "Init runtime store failed."); diff --git a/framework/service/udmf_service.h b/framework/service/udmf_service.h index 481b85f..55cf331 100755 --- a/framework/service/udmf_service.h +++ b/framework/service/udmf_service.h @@ -38,20 +38,25 @@ public: virtual ~UdmfService() = default; virtual int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) = 0; - virtual int32_t GetData(QueryOption &query, UnifiedData &unifiedData) = 0; - virtual int32_t GetSummary(QueryOption &query, Summary &summary) = 0; - virtual int32_t AddPrivilege(QueryOption &query, Privilege &privilege) = 0; + virtual int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) = 0; + virtual int32_t GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) = 0; + virtual int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData) = 0; + virtual int32_t DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) = 0; + virtual int32_t GetSummary(const QueryOption &query, Summary &summary) = 0; + virtual int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) = 0; virtual int32_t Sync(const QueryOption &query, const std::vector<std::string> &devices) = 0; static constexpr int32_t MAX_DATA_SIZE = 4 * 1024 * 1024; static constexpr int32_t MAX_RECORD_SIZE = 2 * 1024 * 1024; - static constexpr int32_t MAX_RECORD_NUM = 512; protected: enum FCode { CODE_HEAD, SET_DATA = CODE_HEAD, GET_DATA, + GET_BATCH_DATA, + UPDATE_DATA, + DELETE_DATA, GET_SUMMARY, ADD_PRIVILEGE, SYNC, diff --git a/framework/service/udmf_service_client.cpp b/framework/service/udmf_service_client.cpp index e9ddffd..ecaab7e 100755 --- a/framework/service/udmf_service_client.cpp +++ b/framework/service/udmf_service_client.cpp @@ -80,19 +80,37 @@ int32_t UdmfServiceClient::SetData(CustomOption &option, UnifiedData &unifiedDat return udmfProxy_->SetData(option, unifiedData, key); } -int32_t UdmfServiceClient::GetData(QueryOption &query, UnifiedData &unifiedData) +int32_t UdmfServiceClient::GetData(const QueryOption &query, UnifiedData &unifiedData) { LOG_INFO(UDMF_SERVICE, "start"); return udmfProxy_->GetData(query, unifiedData); } -int32_t UdmfServiceClient::GetSummary(QueryOption &query, Summary &summary) +int32_t UdmfServiceClient::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + LOG_INFO(UDMF_SERVICE, "start"); + return udmfProxy_->GetBatchData(query, unifiedDataSet); +} + +int32_t UdmfServiceClient::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + LOG_INFO(UDMF_SERVICE, "start"); + return udmfProxy_->UpdateData(query, unifiedData); +} + +int32_t UdmfServiceClient::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + LOG_INFO(UDMF_SERVICE, "start"); + return udmfProxy_->DeleteData(query, unifiedDataSet); +} + +int32_t UdmfServiceClient::GetSummary(const QueryOption &query, Summary &summary) { LOG_INFO(UDMF_SERVICE, "start"); return udmfProxy_->GetSummary(query, summary); } -int32_t UdmfServiceClient::AddPrivilege(QueryOption &query, Privilege &privilege) +int32_t UdmfServiceClient::AddPrivilege(const QueryOption &query, Privilege &privilege) { LOG_INFO(UDMF_SERVICE, "start"); return udmfProxy_->AddPrivilege(query, privilege); diff --git a/framework/service/udmf_service_client.h b/framework/service/udmf_service_client.h index f19f537..c61740b 100755 --- a/framework/service/udmf_service_client.h +++ b/framework/service/udmf_service_client.h @@ -34,9 +34,12 @@ public: static std::shared_ptr<UdmfServiceClient> GetInstance(); int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; - int32_t GetData(QueryOption &query, UnifiedData &unifiedData) override; - int32_t GetSummary(QueryOption &query, Summary &summary) override; - int32_t AddPrivilege(QueryOption &query, Privilege &privilege) override; + int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + 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<std::string> &devices) override; private: diff --git a/framework/service/udmf_service_proxy.cpp b/framework/service/udmf_service_proxy.cpp index acd2188..2da4ac9 100755 --- a/framework/service/udmf_service_proxy.cpp +++ b/framework/service/udmf_service_proxy.cpp @@ -16,10 +16,10 @@ #include "udmf_service_proxy.h" #include "ipc_types.h" - #include "preprocess_utils.h" -#include "udmf_types_util.h" #include "tlv_util.h" +#include "udmf_service_utils.h" +#include "udmf_types_util.h" namespace OHOS { namespace UDMF { @@ -48,7 +48,6 @@ namespace UDMF { __status; \ }) - UdmfServiceProxy::UdmfServiceProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IUdmfService>(object) { } @@ -64,10 +63,6 @@ int32_t UdmfServiceProxy::SetData(CustomOption &option, UnifiedData &unifiedData LOG_ERROR(UDMF_SERVICE, "Empty data without any record!"); return E_INVALID_VALUE; } - if (unifiedData.GetRecords().size() > UdmfService::MAX_RECORD_NUM) { - LOG_ERROR(UDMF_SERVICE, "Excessive record: %{public}zu!", unifiedData.GetRecords().size()); - return E_INVALID_VALUE; - } if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { return E_INVALID_VALUE; } @@ -78,24 +73,9 @@ int32_t UdmfServiceProxy::SetData(CustomOption &option, UnifiedData &unifiedData if (!ITypesUtil::Marshal(request, option)) { return E_WRITE_PARCEL_ERROR; } - auto size = unifiedData.GetRecords().size(); - if (!request.WriteInt32(static_cast<int32_t>(size))) { + if (UdmfServiceUtils::MarshalUnifiedData(request, unifiedData) != E_OK) { return E_WRITE_PARCEL_ERROR; } - for (const auto &record : unifiedData.GetRecords()) { - if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { - return E_INVALID_VALUE; - } - std::vector<uint8_t> recordBytes; - auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Writing(record, recordTlv)) { - return E_WRITE_PARCEL_ERROR; - } - if (!request.WriteInt32(static_cast<int32_t>(recordBytes.size())) || - !request.WriteRawData(recordBytes.data(), recordBytes.size())) { - return E_WRITE_PARCEL_ERROR; - } - } MessageParcel reply; MessageOption messageOption; int error = Remote()->SendRequest(SET_DATA, request, reply, messageOption); @@ -107,7 +87,7 @@ int32_t UdmfServiceProxy::SetData(CustomOption &option, UnifiedData &unifiedData return status; } -int32_t UdmfServiceProxy::GetData(QueryOption &query, UnifiedData &unifiedData) +int32_t UdmfServiceProxy::GetData(const QueryOption &query, UnifiedData &unifiedData) { LOG_INFO(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str()); UnifiedKey key(query.key); @@ -121,29 +101,98 @@ int32_t UdmfServiceProxy::GetData(QueryOption &query, UnifiedData &unifiedData) LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x, key:%{public}s", status, query.key.c_str()); return status; } + if (UdmfServiceUtils::UnMarshalUnifiedData(reply, unifiedData) != E_OK) { + return E_READ_PARCEL_ERROR; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} - int32_t count = reply.ReadInt32(); - for (int32_t index = 0; index < count; ++index) { - std::shared_ptr<UnifiedRecord> record; - auto size = reply.ReadInt32(); - if (size == 0) { - continue; - } - const uint8_t *rawData = reinterpret_cast<const uint8_t *>(reply.ReadRawData(size)); - std::vector<uint8_t> recordBytes(rawData, rawData + size); - auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Reading(record, recordTlv)) { - LOG_ERROR(UDMF_SERVICE, "Unmarshall unified record failed."); - return IPC_STUB_INVALID_DATA_ERR; - } - unifiedData.AddRecord(record); +int32_t UdmfServiceProxy::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + LOG_INFO(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str()); + auto find = UD_INTENTION_MAP.find(query.intention); + std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; + if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + LOG_ERROR(UDMF_SERVICE, "invalid option"); + return E_INVALID_PARAMETERS; } + MessageParcel reply; + int32_t status = IPC_SEND(GET_BATCH_DATA, reply, query); + LOG_DEBUG(UDMF_SERVICE, "GetBatchData : status = %{public}d!", status); + if (status != E_OK) { + return status; + } + if (UdmfServiceUtils::UnMarshalBatchUnifiedData(reply, unifiedDataSet) != E_OK) { + return E_READ_PARCEL_ERROR; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} +int32_t UdmfServiceProxy::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + LOG_INFO(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str()); + UnifiedKey key(query.key); + if (!key.IsValid() || !UnifiedDataUtils::IsPersist(key.intention)) { + LOG_ERROR(UDMF_SERVICE, "invalid key"); + return E_INVALID_PARAMETERS; + } + if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { + LOG_ERROR(UDMF_SERVICE, "Exceeded the limit!"); + return E_INVALID_VALUE; + } + if (unifiedData.GetRecords().empty()) { + LOG_ERROR(UDMF_SERVICE, "Invalid data!"); + return E_INVALID_VALUE; + } + + MessageParcel request; + if (!request.WriteInterfaceToken(GetDescriptor())) { + return E_WRITE_PARCEL_ERROR; + } + if (!ITypesUtil::Marshal(request, query)) { + return E_WRITE_PARCEL_ERROR; + } + if (UdmfServiceUtils::MarshalUnifiedData(request, unifiedData) != E_OK) { + return E_WRITE_PARCEL_ERROR; + } + MessageParcel reply; + MessageOption messageOption; + int error = Remote()->SendRequest(UPDATE_DATA, request, reply, messageOption); + if (error != 0) { + return E_WRITE_PARCEL_ERROR; + } + int32_t status; + ITypesUtil::Unmarshal(reply, status); LOG_DEBUG(UDMF_SERVICE, "end."); return status; } -int32_t UdmfServiceProxy::GetSummary(QueryOption &query, Summary &summary) +int32_t UdmfServiceProxy::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + LOG_INFO(UDMF_SERVICE, "start, tag: intention = %{public}d, key = %{public}s", query.intention, query.key.c_str()); + auto find = UD_INTENTION_MAP.find(query.intention); + std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; + if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + LOG_ERROR(UDMF_SERVICE, "invalid option"); + return E_INVALID_PARAMETERS; + } + MessageParcel reply; + int32_t status = IPC_SEND(DELETE_DATA, reply, query); + if (status != E_OK) { + LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x,key: %{public}s, intention:%{public}s", status, query.key.c_str(), + UD_INTENTION_MAP.at(query.intention).c_str()); + return status; + } + if (UdmfServiceUtils::UnMarshalBatchUnifiedData(reply, unifiedDataSet) != E_OK) { + return E_READ_PARCEL_ERROR; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} + +int32_t UdmfServiceProxy::GetSummary(const QueryOption &query, Summary &summary) { LOG_INFO(UDMF_SERVICE, "start, tag: %{public}s", query.key.c_str()); UnifiedKey key(query.key); @@ -162,7 +211,7 @@ int32_t UdmfServiceProxy::GetSummary(QueryOption &query, Summary &summary) return status; } -int32_t UdmfServiceProxy::AddPrivilege(QueryOption &query, Privilege &privilege) +int32_t UdmfServiceProxy::AddPrivilege(const QueryOption &query, Privilege &privilege) { LOG_INFO(UDMF_SERVICE, "start, key: %{public}s", query.key.c_str()); UnifiedKey key(query.key); @@ -196,7 +245,6 @@ int32_t UdmfServiceProxy::Sync(const QueryOption &query, const std::vector<std:: return status; } - int32_t UdmfServiceProxy::SendRequest( IUdmfService::FCode code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { diff --git a/framework/service/udmf_service_proxy.h b/framework/service/udmf_service_proxy.h index 3941d91..f2da219 100755 --- a/framework/service/udmf_service_proxy.h +++ b/framework/service/udmf_service_proxy.h @@ -35,9 +35,12 @@ public: explicit UdmfServiceProxy(const sptr<IRemoteObject> &object); int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; - int32_t GetData(QueryOption &query, UnifiedData &unifiedData) override; - int32_t GetSummary(QueryOption &query, Summary &summary) override; - int32_t AddPrivilege(QueryOption &query, Privilege &privilege) override; + int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + 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<std::string> &devices) override; private: diff --git a/framework/service/udmf_service_utils.cpp b/framework/service/udmf_service_utils.cpp new file mode 100644 index 0000000..2d85e70 --- /dev/null +++ b/framework/service/udmf_service_utils.cpp @@ -0,0 +1,98 @@ +/* + * 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 "udmf_service_utils.h" + + +namespace OHOS { +namespace UDMF { +int32_t UdmfServiceUtils::MarshalUnifiedData(MessageParcel &data, const UnifiedData &unifiedData) +{ + auto size = unifiedData.GetRecords().size(); + if (!data.WriteInt32(static_cast<int32_t>(size))) { + return E_WRITE_PARCEL_ERROR; + } + for (const auto &record : unifiedData.GetRecords()) { + if (record == nullptr) { + continue; + } + if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { + return E_INVALID_VALUE; + } + std::vector<uint8_t> recordBytes; + auto recordTlv = TLVObject(recordBytes); + if (!TLVUtil::Writing(record, recordTlv)) { + return E_WRITE_PARCEL_ERROR; + } + if (!data.WriteInt32(static_cast<int32_t>(recordBytes.size())) + || !data.WriteRawData(recordBytes.data(), recordBytes.size())) { + return E_WRITE_PARCEL_ERROR; + } + } + return E_OK; +} + +int32_t UdmfServiceUtils::UnMarshalUnifiedData(MessageParcel &data, UnifiedData &unifiedData) +{ + int32_t count = data.ReadInt32(); + for (int32_t index = 0; index < count; ++index) { + std::shared_ptr<UnifiedRecord> record; + auto size = data.ReadInt32(); + if (size == 0) { + continue; + } + const uint8_t *rawData = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); + if (rawData == nullptr) { + return IPC_STUB_INVALID_DATA_ERR; + } + std::vector<uint8_t> recordBytes(rawData, rawData + size); + auto recordTlv = TLVObject(recordBytes); + if (!TLVUtil::Reading(record, recordTlv)) { + LOG_ERROR(UDMF_SERVICE, "Unmarshall unified record failed."); + return IPC_STUB_INVALID_DATA_ERR; + } + unifiedData.AddRecord(record); + } + return E_OK; +} + +int32_t UdmfServiceUtils::MarshalBatchUnifiedData(MessageParcel &data, const std::vector<UnifiedData> &unifiedDataSet) +{ + auto unifiedDataSetSize = unifiedDataSet.size(); + if (!data.WriteInt32(static_cast<int32_t>(unifiedDataSetSize))) { + return E_WRITE_PARCEL_ERROR; + } + for (const auto &unifiedData : unifiedDataSet) { + if (MarshalUnifiedData(data, unifiedData) != E_OK) { + return E_WRITE_PARCEL_ERROR; + } + } + return E_OK; +} + +int32_t UdmfServiceUtils::UnMarshalBatchUnifiedData(MessageParcel &data, std::vector<UnifiedData> &unifiedDataSet) +{ + int32_t unifiedDataSetCount = data.ReadInt32(); + for (int32_t dataIndex = 0; dataIndex < unifiedDataSetCount; dataIndex++) { + UnifiedData unifiedData; + if (UnMarshalUnifiedData(data, unifiedData) != E_OK) { + return E_READ_PARCEL_ERROR; + } + unifiedDataSet.push_back(unifiedData); + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/framework/service/udmf_service_utils.h b/framework/service/udmf_service_utils.h new file mode 100644 index 0000000..0675035 --- /dev/null +++ b/framework/service/udmf_service_utils.h @@ -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. + */ + +#ifndef UDMF_UDMF_SERVICE_UTILS_H +#define UDMF_UDMF_SERVICE_UTILS_H + +#include "tlv_util.h" +#include "unified_data.h" +#include "udmf_service.h" + +namespace OHOS { +namespace UDMF { +class UdmfServiceUtils { +public: + static int32_t MarshalUnifiedData(MessageParcel &data, const UnifiedData &unifiedData); + static int32_t UnMarshalUnifiedData(MessageParcel &data, UnifiedData &unifiedData); + + static int32_t MarshalBatchUnifiedData(MessageParcel &data, const std::vector<UnifiedData> &unifiedDataSet); + static int32_t UnMarshalBatchUnifiedData(MessageParcel &data, std::vector<UnifiedData> &unifiedDataSet); +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_UDMF_SERVICE_UTILS_H diff --git a/interfaces/innerkits/BUILD.gn b/interfaces/innerkits/BUILD.gn index 7b79b73..08a612c 100755 --- a/interfaces/innerkits/BUILD.gn +++ b/interfaces/innerkits/BUILD.gn @@ -71,6 +71,7 @@ ohos_shared_library("udmf_client") { "${udmf_framework_path}/manager/store/store_cache.cpp", "${udmf_framework_path}/service/udmf_service_client.cpp", "${udmf_framework_path}/service/udmf_service_proxy.cpp", + "${udmf_framework_path}/service/udmf_service_utils.cpp", ] public_configs = [ ":udmf_client_config" ] diff --git a/interfaces/innerkits/client/udmf_client.h b/interfaces/innerkits/client/udmf_client.h index 240e4fc..a6eb010 100755 --- a/interfaces/innerkits/client/udmf_client.h +++ b/interfaces/innerkits/client/udmf_client.h @@ -31,9 +31,12 @@ public: static UdmfClient &GetInstance(); Status SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key); - Status GetData(QueryOption &query, UnifiedData &unifiedData); - Status GetSummary(QueryOption &query, Summary& summary); - Status AddPrivilege(QueryOption &query, Privilege &privilege); + Status GetData(const QueryOption &query, UnifiedData &unifiedData); + Status GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet); + Status UpdateData(const QueryOption &query, UnifiedData &unifiedData); + Status DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet); + Status GetSummary(const QueryOption &query, Summary& summary); + Status AddPrivilege(const QueryOption &query, Privilege &privilege); Status Sync(const QueryOption &query, const std::vector<std::string> &devices); }; } // namespace UDMF diff --git a/interfaces/innerkits/common/unified_meta.h b/interfaces/innerkits/common/unified_meta.h index 8e87571..f0d5b56 100644 --- a/interfaces/innerkits/common/unified_meta.h +++ b/interfaces/innerkits/common/unified_meta.h @@ -108,13 +108,17 @@ enum Intention : int32_t { UD_INTENTION_DRAG, UD_INTENTION_SHARE, UD_INTENTION_SYS, - UD_INTENTION_SUPERHUB, + UD_INTENTION_SUPER_HUB, UD_INTENTION_BUTT, }; static const std::unordered_map<int32_t, std::string> UD_INTENTION_MAP { { UD_INTENTION_DRAG, "drag" }, - { UD_INTENTION_SUPERHUB, "SuperHub" }, + { UD_INTENTION_SUPER_HUB, "SuperHub" }, +}; + +static const std::unordered_map<int32_t, std::string> JS_UD_INTENTION_NAME_MAP { + { UD_INTENTION_SUPER_HUB, "SUPER_HUB" }, }; class UnifiedDataUtils { @@ -126,6 +130,7 @@ public: static bool IsPersist(const Intention &intention); static bool IsPersist(const std::string &intention); static Intention GetIntentionByString(const std::string &intention); + static bool IsValidOptions(const std::string &key, std::string &intention); }; } // namespace UDMF } // namespace OHOS diff --git a/interfaces/innerkits/common/unified_types.h b/interfaces/innerkits/common/unified_types.h index 600ff04..f15960a 100755 --- a/interfaces/innerkits/common/unified_types.h +++ b/interfaces/innerkits/common/unified_types.h @@ -76,7 +76,8 @@ struct CustomOption { */ struct QueryOption { std::string key; - uint32_t tokenId {}; + Intention intention {}; + int32_t tokenId {}; int32_t pid {}; }; } // namespace UDMF diff --git a/interfaces/jskits/common/napi_data_utils.h b/interfaces/jskits/common/napi_data_utils.h index 07bd094..bc19dd5 100644 --- a/interfaces/jskits/common/napi_data_utils.h +++ b/interfaces/jskits/common/napi_data_utils.h @@ -86,6 +86,7 @@ public: static bool IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType); + static bool IsNull(napi_env env, napi_value value); /* napi_define_class wrapper */ static napi_value DefineClass(napi_env env, const std::string &name, const napi_property_descriptor *properties, size_t count, napi_callback newcb); diff --git a/interfaces/jskits/common/napi_queue.h b/interfaces/jskits/common/napi_queue.h index d3163c2..093ef7b 100644 --- a/interfaces/jskits/common/napi_queue.h +++ b/interfaces/jskits/common/napi_queue.h @@ -23,6 +23,7 @@ #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" +#include "napi_error_utils.h" namespace OHOS { namespace UDMF { @@ -137,6 +138,16 @@ private: } \ } while (0) +#define ASSERT_WITH_ERRCODE(ctxt, condition, errcode, message) \ + do { \ + if (!(condition)) { \ + (ctxt)->status = napi_generic_failure; \ + GenerateNapiError(errcode, (ctxt)->jsCode, (ctxt)->error); \ + LOG_ERROR(UDMF_KITS_NAPI, "test (" #condition ") failed: " message); \ + return; \ + } \ + } while (0) + class NapiQueue { public: static napi_value AsyncWork(napi_env env, std::shared_ptr<ContextBase> ctxt, const std::string &name, diff --git a/interfaces/jskits/data/udmf_napi.h b/interfaces/jskits/data/udmf_napi.h index 18532d9..8c576eb 100644 --- a/interfaces/jskits/data/udmf_napi.h +++ b/interfaces/jskits/data/udmf_napi.h @@ -29,8 +29,14 @@ public: private: static napi_value CreateUnifiedDataType(napi_env env, napi_callback_info info); + static napi_value CreateIntention(napi_env env, napi_callback_info info); static napi_status SetNamedProperty( napi_env env, napi_value &obj, const std::string &name, const std::string &value); + static napi_value InsertData(napi_env env, napi_callback_info info); + static napi_value UpdateData(napi_env env, napi_callback_info info); + static napi_value QueryData(napi_env env, napi_callback_info info); + static napi_value DeleteData(napi_env env, napi_callback_info info); + static napi_status GetNamedProperty(napi_env env, napi_value &obj, const std::string &key, std::string &value); }; } // namespace UDMF } // namespace OHOS diff --git a/service/include/udmf_service_impl.h b/service/include/udmf_service_impl.h index fbe7585..30b9daf 100755 --- a/service/include/udmf_service_impl.h +++ b/service/include/udmf_service_impl.h @@ -31,9 +31,12 @@ public: ~UdmfServiceImpl() = default; int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; - int32_t GetData(QueryOption &query, UnifiedData &unifiedData) override; - int32_t GetSummary(QueryOption &query, Summary &summary) override; - int32_t AddPrivilege(QueryOption &query, Privilege &privilege) override; + int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) override; + 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<std::string> &devices) override; int32_t OnInitialize() override; diff --git a/service/include/udmf_service_stub.h b/service/include/udmf_service_stub.h index f6c4498..9684d2e 100755 --- a/service/include/udmf_service_stub.h +++ b/service/include/udmf_service_stub.h @@ -19,9 +19,10 @@ #include <map> #include <string> -#include "error_code.h" #include "feature/feature_system.h" #include "message_parcel.h" + +#include "error_code.h" #include "udmf_service.h" namespace OHOS { @@ -38,6 +39,9 @@ public: private: int32_t OnSetData(MessageParcel &data, MessageParcel &reply); int32_t OnGetData(MessageParcel &data, MessageParcel &reply); + int32_t OnGetBatchData(MessageParcel &data, MessageParcel &reply); + int32_t OnUpdateData(MessageParcel &data, MessageParcel &reply); + int32_t OnDeleteData(MessageParcel &data, MessageParcel &reply); int32_t OnGetSummary(MessageParcel &data, MessageParcel &reply); int32_t OnAddPrivilege(MessageParcel &data, MessageParcel &reply); int32_t OnSync(MessageParcel &data, MessageParcel &reply); diff --git a/service/src/udmf_service_impl.cpp b/service/src/udmf_service_impl.cpp index c1f37c1..d88b977 100755 --- a/service/src/udmf_service_impl.cpp +++ b/service/src/udmf_service_impl.cpp @@ -15,8 +15,9 @@ #include "udmf_service_impl.h" -#include "data_manager.h" #include "iservice_registry.h" + +#include "data_manager.h" #include "lifecycle/lifecycle_manager.h" #include "logger.h" #include "preprocess_utils.h" @@ -43,23 +44,41 @@ UdmfServiceImpl::Factory::~Factory() int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { - LOG_INFO(UDMF_SERVICE, "start"); + LOG_DEBUG(UDMF_SERVICE, "start"); return DataManager::GetInstance().SaveData(option, unifiedData, key); } -int32_t UdmfServiceImpl::GetData(QueryOption &query, UnifiedData &unifiedData) +int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData) { - LOG_INFO(UDMF_SERVICE, "start"); + LOG_DEBUG(UDMF_SERVICE, "start"); return DataManager::GetInstance().RetrieveData(query, unifiedData); } -int32_t UdmfServiceImpl::GetSummary(QueryOption &query, Summary &summary) +int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) { - LOG_INFO(UDMF_SERVICE, "start"); + LOG_DEBUG(UDMF_SERVICE, "start"); + return DataManager::GetInstance().RetrieveBatchData(query, unifiedDataSet); +} + +int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + LOG_DEBUG(UDMF_SERVICE, "start"); + return DataManager::GetInstance().UpdateData(query, unifiedData); +} + +int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet) +{ + LOG_DEBUG(UDMF_SERVICE, "start"); + return DataManager::GetInstance().DeleteData(query, unifiedDataSet); +} + +int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) +{ + LOG_DEBUG(UDMF_SERVICE, "start"); return DataManager::GetInstance().GetSummary(query, summary); } -int32_t UdmfServiceImpl::AddPrivilege(QueryOption &query, Privilege &privilege) +int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege) { return DataManager::GetInstance().AddPrivilege(query, privilege); } @@ -71,7 +90,7 @@ int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector<std::s int32_t UdmfServiceImpl::OnInitialize() { - LOG_INFO(UDMF_SERVICE, "start"); + LOG_DEBUG(UDMF_SERVICE, "start"); Status status = LifeCycleManager::GetInstance().DeleteOnStart(); if (status != E_OK) { LOG_ERROR(UDMF_SERVICE, "DeleteOnStart execute failed, status: %{public}d", status); @@ -84,3 +103,4 @@ int32_t UdmfServiceImpl::OnInitialize() } } // namespace UDMF } // namespace OHOS + diff --git a/service/src/udmf_service_stub.cpp b/service/src/udmf_service_stub.cpp index d555559..ede7c39 100755 --- a/service/src/udmf_service_stub.cpp +++ b/service/src/udmf_service_stub.cpp @@ -19,19 +19,21 @@ #include "accesstoken_kit.h" #include "ipc_skeleton.h" - #include "logger.h" +#include "tlv_util.h" +#include "udmf_service_utils.h" #include "udmf_types_util.h" #include "unified_data.h" #include "unified_meta.h" -#include "tlv_util.h" - namespace OHOS { namespace UDMF { UdmfServiceStub::UdmfServiceStub() { memberFuncMap_[static_cast<uint32_t>(SET_DATA)] = &UdmfServiceStub::OnSetData; memberFuncMap_[static_cast<uint32_t>(GET_DATA)] = &UdmfServiceStub::OnGetData; + memberFuncMap_[static_cast<uint32_t>(GET_BATCH_DATA)] = &UdmfServiceStub::OnGetBatchData; + memberFuncMap_[static_cast<uint32_t>(UPDATE_DATA)] = &UdmfServiceStub::OnUpdateData; + memberFuncMap_[static_cast<uint32_t>(DELETE_DATA)] = &UdmfServiceStub::OnDeleteData; memberFuncMap_[static_cast<uint32_t>(GET_SUMMARY)] = &UdmfServiceStub::OnGetSummary; memberFuncMap_[static_cast<uint32_t>(ADD_PRIVILEGE)] = &UdmfServiceStub::OnAddPrivilege; memberFuncMap_[static_cast<uint32_t>(SYNC)] = &UdmfServiceStub::OnSync; @@ -73,27 +75,8 @@ int32_t UdmfServiceStub::OnSetData(MessageParcel &data, MessageParcel &reply) return IPC_STUB_INVALID_DATA_ERR; } UnifiedData unifiedData; - int32_t count = data.ReadInt32(); - if (count > MAX_RECORD_NUM) { - LOG_ERROR(UDMF_SERVICE, "Excessive record: %{public}d!", count); - return E_INVALID_VALUE; - } - for (int32_t index = 0; index < count; ++index) { - std::shared_ptr<UnifiedRecord> record; - int32_t size = data.ReadInt32(); - if (size == 0) { - continue; - } - const uint8_t *rawData = reinterpret_cast<const uint8_t *>(data.ReadRawData(size)); - if (rawData == nullptr) { - return IPC_STUB_INVALID_DATA_ERR; - } - std::vector<uint8_t> recordBytes(rawData, rawData + size); - auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Reading(record, recordTlv)) { - return IPC_STUB_INVALID_DATA_ERR; - } - unifiedData.AddRecord(record); + if (UdmfServiceUtils::UnMarshalUnifiedData(data, unifiedData) != E_OK) { + return IPC_STUB_INVALID_DATA_ERR; } if (unifiedData.GetRecords().empty()) { LOG_ERROR(UDMF_SERVICE, "Empty data without any record!"); @@ -137,25 +120,95 @@ int32_t UdmfServiceStub::OnGetData(MessageParcel &data, MessageParcel &reply) LOG_ERROR(UDMF_SERVICE, "Marshal ud data, key: %{public}s", query.key.c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } - auto size = unifiedData.GetRecords().size(); - if (!reply.WriteInt32(static_cast<int32_t>(size))) { + if (UdmfServiceUtils::MarshalUnifiedData(reply, unifiedData) != E_OK) { return E_WRITE_PARCEL_ERROR; } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetBatchData(MessageParcel &data, MessageParcel &reply) +{ + LOG_INFO(UDMF_SERVICE, "start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + LOG_ERROR(UDMF_SERVICE, "Unmarshal query"); + return IPC_STUB_INVALID_DATA_ERR; + } + uint32_t token = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t pid = static_cast<int>(IPCSkeleton::GetCallingPid()); + query.pid = pid; + std::vector<UnifiedData> unifiedDataSet; + int32_t status = GetBatchData(query, unifiedDataSet); + LOG_DEBUG(UDMF_SERVICE, "Getdata : status = %{public}d!", status); + if (!ITypesUtil::Marshal(reply, status)) { + LOG_ERROR(UDMF_SERVICE, "Marshal ud data, key: %{public}s", query.key.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + if (UdmfServiceUtils::MarshalBatchUnifiedData(reply, unifiedDataSet) != E_OK) { + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnUpdateData(MessageParcel &data, MessageParcel &reply) +{ + LOG_INFO(UDMF_SERVICE, "start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + LOG_ERROR(UDMF_SERVICE, "Unmarshal query"); + return IPC_STUB_INVALID_DATA_ERR; + } + UnifiedData unifiedData; + if (UdmfServiceUtils::UnMarshalUnifiedData(data, unifiedData) != E_OK) { + return IPC_STUB_INVALID_DATA_ERR; + } + if (unifiedData.GetRecords().empty()) { + LOG_ERROR(UDMF_SERVICE, "Empty data without any record!"); + return E_INVALID_VALUE; + } + if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { + LOG_ERROR(UDMF_SERVICE, "Exceeded data limit!"); + return E_INVALID_VALUE; + } for (const auto &record : unifiedData.GetRecords()) { - if (record == nullptr) { - continue; - } - std::vector<uint8_t> recordBytes; - auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Writing(record, recordTlv)) { - LOG_ERROR(UDMF_SERVICE, "TLVUtil writing unified record failed."); - return E_WRITE_PARCEL_ERROR; - } - if (!reply.WriteInt32(static_cast<int32_t>(recordBytes.size())) || - !reply.WriteRawData(recordBytes.data(), recordBytes.size())) { - return E_WRITE_PARCEL_ERROR; + if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { + return E_INVALID_VALUE; } } + uint32_t token = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t pid = static_cast<int>(IPCSkeleton::GetCallingPid()); + query.pid = pid; + int32_t status = UpdateData(query, unifiedData); + if (!ITypesUtil::Marshal(reply, status)) { + LOG_ERROR(UDMF_SERVICE, "Marshal update status failed, key: %{public}s", query.key.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnDeleteData(MessageParcel &data, MessageParcel &reply) +{ + LOG_INFO(UDMF_SERVICE, "start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + LOG_ERROR(UDMF_SERVICE, "Unmarshal query"); + return IPC_STUB_INVALID_DATA_ERR; + } + uint32_t token = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t pid = static_cast<int>(IPCSkeleton::GetCallingPid()); + query.pid = pid; + std::vector<UnifiedData> unifiedDataSet; + int32_t status = DeleteData(query, unifiedDataSet); + if (!ITypesUtil::Marshal(reply, status)) { + LOG_ERROR(UDMF_SERVICE, "Marshal ud data, key: %{public}s", query.key.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + if (UdmfServiceUtils::MarshalBatchUnifiedData(reply, unifiedDataSet) != E_OK) { + return E_WRITE_PARCEL_ERROR; + } return E_OK; } -- Gitee