diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp index 510778234fa75fd96a7309adcf0479e0da17e9c2..5c51ac09b02c2eb700408ab0ceb182e2db013b13 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp @@ -223,7 +223,11 @@ DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &b } // Use instMemory to make sure this singleton not free before other object. // This operation needn't to malloc memory, we needn't to check nullptr. - instPtr = new DistributedObjectStoreImpl(flatObjectStore); + instPtr = new (std::nothrow) DistributedObjectStoreImpl(flatObjectStore); + if (instPtr == nullptr) { + LOG_ERROR("no memory for DistributedObjectStoreImpl malloc!"); + return nullptr; + } } } return instPtr; diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp index dba081c2c6a09b021939e563213ed44ade619006..96b87453bf1b22ff87310dc99d56cedb6a7c51f1 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -276,9 +276,13 @@ int32_t CacheManager::SaveObject(const std::string &bundleName, const std::strin sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); + return ERR_PROCESSING; + } + sptr objectSaveCallback = new (std::nothrow) ObjectSaveCallback(callback); + if (objectSaveCallback == nullptr) { + LOG_ERROR("CacheManager::SaveObject no memory for ObjectSaveCallback malloc!"); return ERR_NULL_PTR; } - sptr objectSaveCallback = new ObjectSaveCallback(callback); int32_t status = proxy->ObjectStoreSave( bundleName, sessionId, deviceId, objectData, objectSaveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { @@ -294,9 +298,14 @@ int32_t CacheManager::RevokeSaveObject( sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); + return ERR_PROCESSING; + } + sptr objectRevokeSaveCallback = new (std::nothrow) + ObjectRevokeSaveCallback(callback); + if (objectRevokeSaveCallback == nullptr) { + LOG_ERROR("CacheManager::RevokeSaveObject no memory for ObjectRevokeSaveCallback malloc!"); return ERR_NULL_PTR; } - sptr objectRevokeSaveCallback = new ObjectRevokeSaveCallback(callback); int32_t status = proxy->ObjectStoreRevokeSave( bundleName, sessionId, objectRevokeSaveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { @@ -314,7 +323,11 @@ int32_t CacheManager::ResumeObject(const std::string &bundleName, const std::str LOG_ERROR("proxy is nullptr."); return ERR_NULL_PTR; } - sptr objectRetrieveCallback = new ObjectRetrieveCallback(callback); + sptr objectRetrieveCallback = new (std::nothrow) ObjectRetrieveCallback(callback); + if (objectRetrieveCallback == nullptr) { + LOG_ERROR("CacheManager::ResumeObject no memory for ObjectRetrieveCallback malloc!"); + return ERR_NULL_PTR; + } int32_t status = proxy->ObjectStoreRetrieve( bundleName, sessionId, objectRetrieveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { @@ -332,7 +345,11 @@ int32_t CacheManager::SubscribeDataChange(const std::string &bundleName, const s LOG_ERROR("proxy is nullptr."); return ERR_NULL_PTR; } - sptr objectRemoteResumeCallback = new ObjectChangeCallback(callback); + sptr objectRemoteResumeCallback = new (std::nothrow) ObjectChangeCallback(callback); + if (objectRemoteResumeCallback == nullptr) { + LOG_ERROR("CacheManager::SubscribeDataChange no memory for ObjectChangeCallback malloc!"); + return ERR_NULL_PTR; + } ClientAdaptor::RegisterClientDeathListener(bundleName, objectRemoteResumeCallback->AsObject()); int32_t status = proxy->RegisterDataObserver( bundleName, sessionId, objectRemoteResumeCallback->AsObject().GetRefPtr()); diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp index 4effc12b380c26120e441d801bfd00d5015a42c9..362698f771f668821ec6e2cdd63fd6f8216c2df4 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp @@ -64,39 +64,6 @@ void StatusNotifierImpl::OnChanged(const std::string &sessionId, const std::string &onlineStatus) { } -static void TestSetSessionId(std::string bundleName, std::string sessionId) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(sessionId); - EXPECT_NE(nullptr, object); - - uint32_t ret = objectStore->DeleteObject(sessionId); - EXPECT_EQ(SUCCESS, ret); -} - -static void TestSaveAndRevokeSave(std::string bundleName, std::string sessionId) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(sessionId); - EXPECT_NE(nullptr, object); - - uint32_t ret = object->PutString("name", "zhangsan"); - EXPECT_EQ(SUCCESS, ret); - ret = object->PutDouble("salary", SALARY); - EXPECT_EQ(SUCCESS, ret); - ret = object->PutBoolean("isTrue", true); - EXPECT_EQ(SUCCESS, ret); - - ret = object->Save("local"); - EXPECT_EQ(SUCCESS, ret); - ret = object->RevokeSave(); - EXPECT_EQ(SUCCESS, ret); - - ret = objectStore->DeleteObject(sessionId); - EXPECT_EQ(SUCCESS, ret); -} void GrantPermissionNative() { @@ -400,6 +367,15 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_GetSessionId_001, TestSize.Lev */ HWTEST_F(NativeObjectStoreTest, DistributedObject_TestSetSessionId_001, TestSize.Level1) { + auto TestSetSessionId = [] (std::string bundleName, std::string sessionId) { + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + uint32_t ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + }; std::thread t1(TestSetSessionId, "default1", "session1"); std::thread t2(TestSetSessionId, "default2", "session2"); std::thread t3(TestSetSessionId, "default3", "session3"); @@ -454,7 +430,25 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_001, TestSize. { std::string bundleName = "default"; std::string sessionId = "123456"; - TestSaveAndRevokeSave(bundleName, sessionId); + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + uint32_t ret = object->PutString("name", "zhangsan"); + EXPECT_EQ(SUCCESS, ret); + ret = object->PutDouble("salary", SALARY); + EXPECT_EQ(SUCCESS, ret); + ret = object->PutBoolean("isTrue", true); + EXPECT_EQ(SUCCESS, ret); + + ret = object->Save("local"); + EXPECT_EQ(SUCCESS, ret); + ret = object->RevokeSave(); + EXPECT_EQ(SUCCESS, ret); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); } /** @@ -464,6 +458,27 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_001, TestSize. */ HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_002, TestSize.Level1) { + auto TestSaveAndRevokeSave = [](std::string bundleName, std::string sessionId) { + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + uint32_t ret = object->PutString("name", "zhangsan"); + EXPECT_EQ(SUCCESS, ret); + ret = object->PutDouble("salary", SALARY); + EXPECT_EQ(SUCCESS, ret); + ret = object->PutBoolean("isTrue", true); + EXPECT_EQ(SUCCESS, ret); + + ret = object->Save("local"); + EXPECT_EQ(SUCCESS, ret); + ret = object->RevokeSave(); + EXPECT_EQ(SUCCESS, ret); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + }; std::thread t1(TestSaveAndRevokeSave, "default1", "session1"); std::thread t2(TestSaveAndRevokeSave, "default2", "session2"); std::thread t3(TestSaveAndRevokeSave, "default3", "session3"); diff --git a/data_object/frameworks/jskitsimpl/include/adaptor/js_common.h b/data_object/frameworks/jskitsimpl/include/adaptor/js_common.h index 33b8cf7c9bf2ca6f76282114193867a8084bd5c6..74016c64dace7dbfea31f362e9e06bcc36d0866a 100644 --- a/data_object/frameworks/jskitsimpl/include/adaptor/js_common.h +++ b/data_object/frameworks/jskitsimpl/include/adaptor/js_common.h @@ -24,6 +24,7 @@ namespace OHOS::ObjectStore { return nullptr; \ } \ } + #define CHECK_EQUAL_WITH_RETURN_VOID(status, value) \ { \ if (status != value) { \ @@ -31,6 +32,7 @@ namespace OHOS::ObjectStore { return; \ } \ } + #define CHECK_EQUAL_WITH_RETURN_FALSE(status, value) \ { \ if (status != value) { \ @@ -38,6 +40,7 @@ namespace OHOS::ObjectStore { return false; \ } \ } + #define ASSERT_MATCH_ELSE_RETURN_VOID(condition) \ { \ if (!(condition)) { \ @@ -45,6 +48,7 @@ namespace OHOS::ObjectStore { return; \ } \ } + #define ASSERT_MATCH_ELSE_RETURN_NULL(condition) \ { \ if (!(condition)) { \ @@ -52,6 +56,7 @@ namespace OHOS::ObjectStore { return nullptr; \ } \ } + #define ASSERT_MATCH_ELSE_GOTO_ERROR(condition) \ { \ if (!(condition)) { \ @@ -59,6 +64,27 @@ namespace OHOS::ObjectStore { goto ERROR; \ } \ } + +#define CHECK_API_VALID(assertion) \ + do { \ + if (!(assertion)) { \ + std::shared_ptr apiError = std::make_shared(); \ + ctxt->SetError(apiError); \ + ctxt->status = napi_generic_failure; \ + return; \ + } \ + } while (0) + +#define CHECK_VALID(assertion, msg) \ + do { \ + if (!(assertion)) { \ + std::shared_ptr innerError = std::make_shared(); \ + ctxt->SetError(innerError); \ + ctxt->status = napi_generic_failure; \ + ctxt->message = msg; \ + return; \ + } \ + } while (0) } // namespace OHOS::ObjectStore static const char *CHANGE = "change"; static const char *STATUS = "status"; diff --git a/data_object/frameworks/jskitsimpl/include/common/object_error.h b/data_object/frameworks/jskitsimpl/include/common/object_error.h index a982e9bcb45469bc1c9b4ecc693586dfdde514bd..8ebe82e4deeb8843baf5208dd503a12248dd40a2 100644 --- a/data_object/frameworks/jskitsimpl/include/common/object_error.h +++ b/data_object/frameworks/jskitsimpl/include/common/object_error.h @@ -20,6 +20,7 @@ namespace OHOS { namespace ObjectStore { +static const int EXCEPTION_DEVICE_NOT_SUPPORT = 801; static const int EXCEPTION_PARAMETER_CHECK = 401; static const int EXCEPTION_NO_PERMISSION = 201; static const int EXCEPTION_DB_EXIST = 15400001; @@ -73,6 +74,13 @@ public: std::string GetMessage() override; int GetCode() override; }; + +class DeviceNotSupportedError : public Error { +public: + DeviceNotSupportedError() = default; + std::string GetMessage() override; + int GetCode() override; +}; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp index 5800f164c459dad02c648acc24726436408563fa..334369e600c58704e15ad2f5177e67799d7b1e39 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp @@ -248,6 +248,16 @@ napi_value JSDistributedObject::JSSave(napi_env env, napi_callback_info info) }; ctxt->GetCbInfo(env, info, getCbOpe); CHECH_STATUS_ERRCODE(env, ctxt->status != napi_invalid_arg, ctxt->error); + auto execute = [ctxt]() { + LOG_INFO("start"); + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper->GetObject() != nullptr, ctxt, "object is null"); + uint32_t status = ctxt->wrapper->GetObject()->Save(ctxt->deviceId); + CHECK_API_VALID(status != ERR_PROCESSING); + CHECK_VALID(status == SUCCESS, "operation failed"); + ctxt->status = napi_ok; + LOG_INFO("end"); + }; auto output = [env, ctxt](napi_value &result) { if (ctxt->status == napi_ok) { CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); @@ -258,22 +268,6 @@ napi_value JSDistributedObject::JSSave(napi_env env, napi_callback_info info) CHECK_STATUS_RETURN_VOID(ctxt, "output failed!"); } }; - auto execute = [ctxt]() { - LOG_INFO("start"); - CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); - CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper->GetObject() != nullptr, ctxt, "object is null"); - uint32_t status = ctxt->wrapper->GetObject()->Save(ctxt->deviceId); - if (status != SUCCESS) { - LOG_ERROR("Save failed, status = %{public}d", status); - auto innerError = std::make_shared(); - ctxt->SetError(innerError); - ctxt->status = napi_generic_failure; - ctxt->message = std::string("operation failed"); - return; - } - ctxt->status = napi_ok; - LOG_INFO("end"); - }; return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output); } @@ -300,7 +294,15 @@ napi_value JSDistributedObject::JSRevokeSave(napi_env env, napi_callback_info in napi_throw_error((env), std::to_string(ctxt->error->GetCode()).c_str(), ctxt->error->GetMessage().c_str()); return nullptr; } - + auto execute = [ctxt]() { + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper->GetObject() != nullptr, ctxt, "object is null"); + uint32_t status = ctxt->wrapper->GetObject()->RevokeSave(); + CHECK_API_VALID(status != ERR_PROCESSING); + CHECK_VALID(status == SUCCESS, "operation failed"); + ctxt->status = napi_ok; + LOG_INFO("end"); + }; auto output = [env, ctxt](napi_value &result) { if (ctxt->status == napi_ok) { CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); @@ -311,25 +313,7 @@ napi_value JSDistributedObject::JSRevokeSave(napi_env env, napi_callback_info in CHECK_STATUS_RETURN_VOID(ctxt, "output failed!"); } }; - return NapiQueue::AsyncWork( - env, ctxt, std::string(__FUNCTION__), - [ctxt]() { - LOG_INFO("start"); - CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); - CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper->GetObject() != nullptr, ctxt, "object is null"); - uint32_t status = ctxt->wrapper->GetObject()->RevokeSave(); - if (status != SUCCESS) { - LOG_ERROR("Save failed, status = %{public}d", status); - auto innerError = std::make_shared(); - ctxt->SetError(innerError); - ctxt->status = napi_generic_failure; - ctxt->message = std::string("operation failed"); - return; - } - ctxt->status = napi_ok; - LOG_INFO("end"); - }, - output); + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute, output); } napi_value JSDistributedObject::GetSaveResultCons( diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp index e8c92e825e7ee2c2c7b40c07bf3443976b633dd4..2ff2021027ff0cda4fb54ff73db26878e6793c5f 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp @@ -108,7 +108,11 @@ napi_value JSDistributedObjectStore::NewDistributedObject( napi_value result; napi_status status = napi_new_instance(env, JSDistributedObject::GetCons(env), 0, nullptr, &result); CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok); - JSObjectWrapper *objectWrapper = new JSObjectWrapper(objectStore, object); + JSObjectWrapper *objectWrapper = new (std::nothrow) JSObjectWrapper(objectStore, object); + if (objectWrapper == nullptr) { + LOG_ERROR("JSDistributedObjectStore::NewDistributedObject no memory for objectWrapper malloc!"); + return nullptr; + } objectWrapper->SetObjectId(objectId); status = napi_wrap( env, result, objectWrapper, diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp index 40f964723426f183b1f57251af89a174438b1380..9e1895d00db962a804d1d3d830678c3ebc9c3af7 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp @@ -105,7 +105,11 @@ void JSWatcher::Emit(const char *type, const std::string &sessionId, const std:: } for (EventHandler *handler = listener->handlers_; handler != nullptr; handler = handler->next) { - ChangeArgs *changeArgs = new ChangeArgs(handler->callbackRef, sessionId, changeData); + ChangeArgs *changeArgs = new (std::nothrow) ChangeArgs(handler->callbackRef, sessionId, changeData); + if (changeArgs == nullptr) { + LOG_ERROR("JSWatcher::Emit no memory for changeArgs malloc!"); + return; + } CallFunction(ProcessChange, changeArgs); } } @@ -171,7 +175,11 @@ void JSWatcher::Emit( } for (EventHandler *handler = listener->handlers_; handler != nullptr; handler = handler->next) { - StatusArgs *changeArgs = new StatusArgs(handler->callbackRef, sessionId, networkId, status); + StatusArgs *changeArgs = new (std::nothrow) StatusArgs(handler->callbackRef, sessionId, networkId, status); + if (changeArgs == nullptr) { + LOG_ERROR("JSWatcher::Emit no memory for StatusArgs malloc!"); + return; + } CallFunction(ProcessStatus, changeArgs); } return; @@ -248,10 +256,18 @@ bool EventListener::Add(napi_env env, napi_value handler) } if (handlers_ == nullptr) { - handlers_ = new EventHandler(); + handlers_ = new (std::nothrow) EventHandler(); + if (handlers_ == nullptr) { + LOG_ERROR("EventListener::Add no memory for EventHandler malloc!"); + return false; + } handlers_->next = nullptr; } else { - auto temp = new EventHandler(); + auto temp = new (std::nothrow) EventHandler(); + if (temp == nullptr) { + LOG_ERROR("EventListener::Add no memory for EventHandler malloc!"); + return false; + } temp->next = handlers_; handlers_ = temp; } diff --git a/data_object/frameworks/jskitsimpl/src/common/object_error.cpp b/data_object/frameworks/jskitsimpl/src/common/object_error.cpp index 0f03e14b35911adb857621b8cf0247269b2c7c18..12347fd0d2022895f9fcc68068e56742e2591120 100644 --- a/data_object/frameworks/jskitsimpl/src/common/object_error.cpp +++ b/data_object/frameworks/jskitsimpl/src/common/object_error.cpp @@ -67,5 +67,15 @@ int InnerError::GetCode() { return EXCEPTION_INNER; } + +std::string DeviceNotSupportedError::GetMessage() +{ + return "Capability not supported."; +} + +int DeviceNotSupportedError::GetCode() +{ + return EXCEPTION_DEVICE_NOT_SUPPORT; +} } // namespace ObjectStore } // namespace OHOS \ No newline at end of file diff --git a/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunit.test.js b/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunit.test.js index 380d88084ad1fa9cee32a522bd7b99c6e369d6ef..aed6d72f88a9f24a904d03c8e31ee7bdc7306f89 100644 --- a/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunit.test.js +++ b/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunit.test.js @@ -63,6 +63,7 @@ function statusCallback4(sessionId, networkId, status) { const TIMEOUT = 1500; const PERMISSION_USER_SET = 1; const PERMISSION_USER_NAME = "ohos.permission.DISTRIBUTED_DATASYNC"; +const CATCH_ERR = -1; var tokenID = undefined; async function grantPerm() { console.info("====grant Permission start===="); @@ -677,33 +678,74 @@ describe('objectStoreTest',function () { * @tc.name: testSave001 * @tc.desc: test save local * @tc.type: FUNC - * @tc.require: I4WDAK + * @tc.require: */ - it('testSave001', 0, async function () { + it('testSave001', 0, async function (done) { console.log(TAG + "************* testSave001 start *************"); var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("tmpsession1"); - expect("tmpsession1" == g_object.__sessionId).assertEqual(true); - - let result = await g_object.save("local"); - expect(result.sessionId == "tmpsession1").assertEqual(true); - expect(result.version == g_object.__version).assertEqual(true); - expect(result.deviceId == "local").assertEqual(true); + g_object.setSessionId("testSession001"); + expect("testSession001" == g_object.__sessionId).assertEqual(true); + + g_object.save("local").then((ret) => { + expect(ret.sessionId == "testSession001").assertEqual(true); + expect(ret.version == g_object.__version).assertEqual(true); + expect(ret.deviceId == "local").assertEqual(true); + done(); + + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("testSession001"); + + expect(g_object.name == "Amy").assertEqual(true); + expect(g_object.age == 18).assertEqual(true); + expect(g_object.isVis == false).assertEqual(true); + }).catch((err) => { + expect("801").assertEqual(err.code.toString()); + done(); + }); + console.log(TAG + "************* testSave001 end *************"); + }) - g_object.setSessionId(""); - g_object.name = undefined; - g_object.age = undefined; - g_object.isVis = undefined; - g_object.setSessionId("tmpsession1"); + /** + * @tc.name: testSave002 + * @tc.desc: test save local + * @tc.type: FUNC + * @tc.require: + */ + it('testSave002', 0, async function (done) { + console.log(TAG + "************* testSave002 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + expect(g_object == undefined).assertEqual(false); - expect(g_object.name == "Amy").assertEqual(true); - expect(g_object.age == 18).assertEqual(true); - expect(g_object.isVis == false).assertEqual(true); - console.log(TAG + "************* testSave001 end *************"); - g_object.setSessionId(""); + g_object.setSessionId("testSession002"); + expect("testSession002" == g_object.__sessionId).assertEqual(true); + g_object.save("local", (err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect(result.sessionId == "testSession002").assertEqual(true); + expect(result.version == g_object.__version).assertEqual(true); + expect(result.deviceId == "local").assertEqual(true); + done(); + + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("testSession002"); + + expect(g_object.name == "Amy").assertEqual(true); + expect(g_object.age == 18).assertEqual(true); + expect(g_object.isVis == false).assertEqual(true); + }) + console.log(TAG + "************* testSave002 end *************"); }) /** @@ -712,36 +754,92 @@ describe('objectStoreTest',function () { * @tc.type: FUNC * @tc.require: I4WDAK */ - it('testRevokeSave001', 0, async function () { + it('testRevokeSave001', 0, async function (done) { console.log(TAG + "************* testRevokeSave001 start *************"); var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("123456"); - expect("123456" == g_object.__sessionId).assertEqual(true); + g_object.setSessionId("testSession003"); + expect("testSession003" == g_object.__sessionId).assertEqual(true); - let result = await g_object.save("local"); - expect(result.sessionId == "123456").assertEqual(true); - expect(result.version == g_object.__version).assertEqual(true); - expect(result.deviceId == "local").assertEqual(true); + g_object.save("local", (err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect(result.sessionId == "testSession003").assertEqual(true); + expect(result.version == g_object.__version).assertEqual(true); + expect(result.deviceId == "local").assertEqual(true); + g_object.revokeSave((err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect("testSession003" == result.sessionId).assertEqual(true); + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("testSession003"); + + expect(g_object.name == undefined).assertEqual(true); + expect(g_object.age == undefined).assertEqual(true); + expect(g_object.isVis == undefined).assertEqual(true); + done(); + }) + }); - result = await g_object.revokeSave(); + console.log(TAG + "************* testRevokeSave001 end *************"); + }) + /** + * @tc.name: testRevokeSave002 + * @tc.desc: test save local + * @tc.type: FUNC + * @tc.require: + */ + it('testRevokeSave002', 0, async function () { + console.log(TAG + "************* testRevokeSave002 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + expect(g_object == undefined).assertEqual(false); + + g_object.setSessionId("testSession004"); + expect("testSession004" == g_object.__sessionId).assertEqual(true); + + let result = await g_object.save("local").catch((err)=> { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; + }); + if (result === CATCH_ERR) { + return; + } + + expect(result.sessionId.toString() == "testSession004").assertEqual(true); + expect(result.version.toString() == g_object.__version.toString()).assertEqual(true); + expect(result.deviceId.toString() == "local").assertEqual(true); + + result = await g_object.revokeSave().catch((err)=> { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; + }); + + if (result === CATCH_ERR) { + return; + } g_object.setSessionId(""); g_object.name = undefined; g_object.age = undefined; g_object.isVis = undefined; - g_object.setSessionId("123456"); + g_object.setSessionId("testSession004"); expect(g_object.name == undefined).assertEqual(true); expect(g_object.age == undefined).assertEqual(true); expect(g_object.isVis == undefined).assertEqual(true); - expect(result.sessionId == "123456").assertEqual(true); - - console.log(TAG + "************* testRevokeSave001 end *************"); - g_object.setSessionId(""); + console.log(TAG + "************* testRevokeSave002 end *************"); }) /** @@ -752,25 +850,21 @@ describe('objectStoreTest',function () { */ it('OnstatusRestored001', 0, async function () { console.log(TAG + "************* OnstatusRestored001 start *************"); - var g_object = distributedObject.createDistributedObject({ name: undefined, age: undefined, isVis: undefined }); - g_object.setSessionId("123456"); - g_object.name = "jack"; - g_object.age = 19; - g_object.isVis = true; - - let result = await g_object.save("local"); - expect(result.sessionId == "123456").assertEqual(true); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.on("status", statusCallback4); + g_object.setSessionId("testSession005"); + let result = await g_object.save("local").catch((err)=> { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; + }); + if (result === CATCH_ERR) { + return; + } + expect(result.sessionId == "testSession005").assertEqual(true); expect(result.version == g_object.__version).assertEqual(true); expect(result.deviceId == "local").assertEqual(true); - g_object.setSessionId(""); - - g_object.on("status", statusCallback4); - - g_object.setSessionId("123456"); - g_object.setSessionId(""); console.log(TAG + "************* OnstatusRestored001 end *************"); - }) console.log(TAG + "*************Unit Test End*************"); diff --git a/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunitV9.test.js b/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunitV9.test.js index c1e3d4b89ce71086a59001d387ca8bff5ca7c95c..02b69e9b0db433d7d74a75a118ed3487ed5485aa 100644 --- a/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunitV9.test.js +++ b/data_object/frameworks/jskitsimpl/test/unittest/src/ObjectStoreJsunitV9.test.js @@ -42,6 +42,7 @@ function statusCallback2(sessionId, networkId, status) { const PERMISSION_USER_SET = 1; const PERMISSION_USER_NAME = "ohos.permission.DISTRIBUTED_DATASYNC"; +const CATCH_ERR = -1; var tokenID = undefined; async function grantPerm() { console.info("====grant Permission start===="); @@ -373,7 +374,7 @@ describe('objectStoreTest', function () { }) /** - * @tc.name:V9testOff002 + * @tc.name: V9testOff002 * @tc.desc object join session and off,object can not receive callback * @tc.type: FUNC */ @@ -458,44 +459,38 @@ describe('objectStoreTest', function () { * @tc.desc: test save local * @tc.type: FUNC */ - it('V9testSave001', 0, async function () { + it('V9testSave001', 0, async function (done) { console.log(TAG + "************* V9testSave001 start *************"); var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("tmpsession1").then(() => { + g_object.setSessionId("mySession1").then(() => { console.info("join session"); }).catch((error) => { console.info(TAG + error.code + error.message); }); - expect("tmpsession1" == g_object.__sessionId).assertEqual(true); + expect("mySession1" == g_object.__sessionId).assertEqual(true); - let result = await g_object.save("local"); - expect(result.sessionId == "tmpsession1").assertEqual(true); - expect(result.version == g_object.__version).assertEqual(true); - expect(result.deviceId == "local").assertEqual(true); + g_object.save("local").then((ret) => { + expect(ret.sessionId == "mySession1").assertEqual(true); + expect(ret.version == g_object.__version).assertEqual(true); + expect(ret.deviceId == "local").assertEqual(true); + done(); - g_object.setSessionId((error, data) => { - console.info(TAG + error + "," + data); - }); - g_object.name = undefined; - g_object.age = undefined; - g_object.isVis = undefined; - g_object.setSessionId("tmpsession1").then(() => { - console.info("join session"); - }).catch((error) => { - console.info(TAG + error.code + error.message); - }); + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("mySession1"); - expect(g_object.name == "Amy").assertEqual(true); - expect(g_object.age == 18).assertEqual(true); - expect(g_object.isVis == false).assertEqual(true); - console.log(TAG + "************* V9testSave001 end *************"); - g_object.setSessionId().then(() => { - console.info("leave session"); - }).catch((error) => { - console.info(TAG + error.code + error.message); + expect(g_object.name == "Amy").assertEqual(true); + expect(g_object.age == 18).assertEqual(true); + expect(g_object.isVis == false).assertEqual(true); + }).catch((err) => { + expect("801").assertEqual(err.code.toString()); + done(); }); + console.log(TAG + "************* V9testSave001 end *************"); }) /** @@ -503,20 +498,57 @@ describe('objectStoreTest', function () { * @tc.desc: test save local * @tc.type: FUNC */ - it('V9testSave002', 0, async function () { + it('V9testSave002', 0, async function (done) { console.log(TAG + "************* V9testSave002 start *************"); var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("tmpsession1").then(() => { + g_object.setSessionId("mySession2"); + expect("mySession2" == g_object.__sessionId).assertEqual(true); + + g_object.save("local", (err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect(result.sessionId == "mySession2").assertEqual(true); + expect(result.version == g_object.__version).assertEqual(true); + expect(result.deviceId == "local").assertEqual(true); + + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("mySession2"); + + expect(g_object.name == "Amy").assertEqual(true); + expect(g_object.age == 18).assertEqual(true); + expect(g_object.isVis == false).assertEqual(true); + done(); + }); + console.log(TAG + "************* V9testSave002 end *************"); + }) + + /** + * @tc.name: V9testSave003 + * @tc.desc: test save local + * @tc.type: FUNC + */ + it('V9testSave003', 0, async function () { + console.log(TAG + "************* V9testSave003 start *************"); + var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); + expect(g_object == undefined).assertEqual(false); + + g_object.setSessionId("mySession3").then(() => { console.info("join session"); }).catch((error) => { console.info(TAG + error.code + error.message); }); - expect("tmpsession1" == g_object.__sessionId).assertEqual(true); + expect("mySession3" == g_object.__sessionId).assertEqual(true); try { g_object.save(1234).then((result) => { - expect(result.sessionId == "tmpsession1").assertEqual(true); + expect(result.sessionId == "mySession3").assertEqual(true); expect(result.version == g_object.__version).assertEqual(true); expect(result.deviceId == "local").assertEqual(true); }) @@ -524,20 +556,20 @@ describe('objectStoreTest', function () { expect(error.message == "Parameter error. The type of 'deviceId' must be 'string'.").assertEqual(true); } g_object.save("errorDeviceId").then((result) => { - expect(result.sessionId == "tmpsession1").assertEqual(true); + expect(result.sessionId == "mySession3").assertEqual(true); expect(result.version == g_object.__version).assertEqual(true); expect(result.deviceId == "local").assertEqual(true); }).catch((error) => { expect(error != undefined).assertEqual(true); }); - + try { g_object.save("local", 123); } catch (error) { expect(error.code == 401).assertEqual(true); expect(error.message == "Parameter error. The type of 'callback' must be 'function'.").assertEqual(true); } - console.log(TAG + "************* V9testSave002 end *************"); + console.log(TAG + "************* V9testSave003 end *************"); g_object.setSessionId().then(() => { console.info("leave session"); }).catch((error) => { @@ -550,81 +582,129 @@ describe('objectStoreTest', function () { * @tc.desc: test RevokeSave * @tc.type: FUNC */ - it('V9testRevokeSave001', 0, async function () { + it('V9testRevokeSave001', 0, async function (done) { console.log(TAG + "************* V9testRevokeSave001 start *************"); var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("123456").then(() => { - console.info("join session"); - }).catch((error) => { - console.info(TAG + error.code + error.message); + g_object.setSessionId("mySession4"); + expect("mySession4" == g_object.__sessionId).assertEqual(true); + + g_object.save("local", (err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect(result.sessionId == "mySession4").assertEqual(true); + expect(result.version == g_object.__version).assertEqual(true); + expect(result.deviceId == "local").assertEqual(true); + g_object.revokeSave((err, result) => { + if (err) { + expect("801").assertEqual(err.code.toString()); + done(); + return; + } + expect("mySession4" == result.sessionId).assertEqual(true); + g_object.setSessionId(""); + g_object.name = undefined; + g_object.age = undefined; + g_object.isVis = undefined; + g_object.setSessionId("mySession4"); + + expect(g_object.name == undefined).assertEqual(true); + expect(g_object.age == undefined).assertEqual(true); + expect(g_object.isVis == undefined).assertEqual(true); + done(); + }) }); - expect("123456" == g_object.__sessionId).assertEqual(true); + console.log(TAG + "************* V9testRevokeSave001 end *************"); + }) - let result = await g_object.save("local"); - expect(result.sessionId == "123456").assertEqual(true); - expect(result.version == g_object.__version).assertEqual(true); - expect(result.deviceId == "local").assertEqual(true); - result = await g_object.revokeSave(); + /** + * @tc.name: V9testRevokeSave002 + * @tc.desc: test save local + * @tc.type: FUNC + * @tc.require: + */ + it('V9testRevokeSave002', 0, async function () { + console.log(TAG + "************* V9testRevokeSave002 start *************"); + var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); + expect(g_object != undefined).assertEqual(true); - g_object.setSessionId((error, data) => { - console.info(TAG + error + "," + data); + g_object.setSessionId("mySession5"); + expect("mySession5" == g_object.__sessionId.toString()).assertEqual(true); + + let result = await g_object.save("local").catch((err)=> { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; }); + if (result === CATCH_ERR) { + return; + } + + expect(result.sessionId.toString() == "mySession5").assertEqual(true); + expect(result.version.toString() == g_object.__version.toString()).assertEqual(true); + expect(result.deviceId.toString() == "local").assertEqual(true); + + result = await g_object.revokeSave().catch((err)=> { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; + }); + + if (result === CATCH_ERR) { + return; + } + g_object.setSessionId(""); g_object.name = undefined; g_object.age = undefined; g_object.isVis = undefined; - g_object.setSessionId("123456").then(() => { - console.info("join session"); - }).catch((error) => { - console.info(TAG + error.code + error.message); - }); + g_object.setSessionId("mySession5"); expect(g_object.name == undefined).assertEqual(true); expect(g_object.age == undefined).assertEqual(true); expect(g_object.isVis == undefined).assertEqual(true); - expect(result.sessionId == "123456").assertEqual(true); - console.log(TAG + "************* V9testRevokeSave001 end *************"); - g_object.setSessionId("", (error, data) => { - console.info(TAG + error + "," + data); - }); + + console.log(TAG + "************* V9testRevokeSave002 end *************"); }) /** - * @tc.name: V9testRevokeSave002 + * @tc.name: V9testRevokeSave003 * @tc.desc: test RevokeSave * @tc.type: FUNC */ - it('V9testRevokeSave002', 0, async function () { - console.log(TAG + "************* V9testRevokeSave002 start *************"); + it('V9testRevokeSave003', 0, async function () { + console.log(TAG + "************* V9testRevokeSave003 start *************"); var g_object = distributedObject.create(context, {name: "Amy", age: 18, isVis: false}); expect(g_object == undefined).assertEqual(false); - g_object.setSessionId("123456").then(() => { + g_object.setSessionId("mySession6").then(() => { console.info("join session"); }).catch((error) => { console.info(TAG + error.code + error.message); }); - expect("123456" == g_object.__sessionId).assertEqual(true); - let result = await g_object.save("local"); - expect(result.sessionId == "123456").assertEqual(true); + expect("mySession6" == g_object.__sessionId).assertEqual(true); + let result = await g_object.save("local").catch((err) => { + expect("801").assertEqual(err.code.toString()); + return CATCH_ERR; + }); + if (result === CATCH_ERR) { + return; + } + expect(result.sessionId == "mySession6").assertEqual(true); expect(result.version == g_object.__version).assertEqual(true); expect(result.deviceId == "local").assertEqual(true); try { g_object.revokeSave(123).then((result) => { - expect(result.sessionId == "tmpsession1").assertEqual(true) + expect(result.sessionId == "mySession6").assertEqual(true); }).catch((err) => { console.log(err.code + err.message); }); } catch (error) { console.info(error.code + error.message); - expect(error.code == 401).assertEqual(true); - expect(error.message == "Parameter error. The type of 'callback' must be 'function'.").assertEqual(true); + expect("401").assertEqual(error.code.toString()); } - console.log(TAG + "************* V9testRevokeSave002 end *************"); - g_object.setSessionId("", (error, data) => { - console.info(TAG + error + "," + data); - }); + console.log(TAG + "************* V9testRevokeSave003 end *************"); }) - + console.log(TAG + "*************Unit Test End*************"); }) \ No newline at end of file diff --git a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp index a0c928203afdf539f365a6701f9e8107b9627dce..13e225526484793734c9eadffeb0d90c245c2735 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp @@ -85,7 +85,11 @@ napi_value DataSharePredicatesProxy::New(napi_env env, napi_callback_info info) NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); if (is_constructor) { - auto *proxy = new DataSharePredicatesProxy(); + auto *proxy = new (std::nothrow) DataSharePredicatesProxy(); + if (proxy == nullptr) { + LOG_ERROR("DataSharePredicatesProxy::New new DataSharePredicatesProxy error."); + return nullptr; + } proxy->predicates_ = std::make_shared(); napi_status ret = napi_wrap(env, thiz, proxy, DataSharePredicatesProxy::Destructor, nullptr, nullptr); if (ret != napi_ok) { diff --git a/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp b/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp index 07702427c5ce729b036cb0b143ef82ba32dc538b..cab484adb07531defe7ec68dcc9e6c7e33412a66 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_result_set_proxy.cpp @@ -106,7 +106,11 @@ napi_value DataShareResultSetProxy::Initialize(napi_env env, napi_callback_info { napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr)); - auto *proxy = new DataShareResultSetProxy(); + auto *proxy = new (std::nothrow) DataShareResultSetProxy(); + if (proxy == nullptr) { + LOG_ERROR("DataShareResultSetProxy::Initialize new DataShareResultSetProxy error."); + return nullptr; + } auto finalize = [](napi_env env, void *data, void *hint) { DataShareResultSetProxy *proxy = reinterpret_cast(data); if (proxy != nullptr) { diff --git a/data_share/frameworks/js/napi/dataShare/BUILD.gn b/data_share/frameworks/js/napi/dataShare/BUILD.gn index 04925420105c57ee695e549e38aca713af42be2c..0cdf6a90cb33090ef7968796a2d2ea0460687558 100644 --- a/data_share/frameworks/js/napi/dataShare/BUILD.gn +++ b/data_share/frameworks/js/napi/dataShare/BUILD.gn @@ -24,6 +24,7 @@ ohos_shared_library("datashare") { sources = [ "${datashare_napi_path}/dataShare/src/async_call.cpp", "${datashare_napi_path}/dataShare/src/napi_datashare_helper.cpp", + "${datashare_napi_path}/dataShare/src/napi_datashare_inner_observer.cpp", "${datashare_napi_path}/dataShare/src/napi_datashare_observer.cpp", "${datashare_napi_path}/dataShare/src/native_datashare_module.cpp", ] diff --git a/mock/innerkits/ipc/ipc_single/include/message_option.h b/data_share/frameworks/js/napi/dataShare/include/napi_datashare_inner_observer.h similarity index 41% rename from mock/innerkits/ipc/ipc_single/include/message_option.h rename to data_share/frameworks/js/napi/dataShare/include/napi_datashare_inner_observer.h index 7aa96519d9752db6516229b21758a47d3e62cc89..eba5d1b8cfb128267dc327503b87aa692bbcae3e 100644 --- a/mock/innerkits/ipc/ipc_single/include/message_option.h +++ b/data_share/frameworks/js/napi/dataShare/include/napi_datashare_inner_observer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,31 +13,34 @@ * limitations under the License. */ -#ifndef OHOS_IPC_MESSAGE_OPTION_H -#define OHOS_IPC_MESSAGE_OPTION_H +#ifndef NAPI_DATASHARE_INNER_OBSERVER_H +#define NAPI_DATASHARE_INNER_OBSERVER_H + +#include + +#include "napi/native_common.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" -#include namespace OHOS { -class MessageOption { +namespace DataShare { +class NAPIInnerObserver : public std::enable_shared_from_this { public: - enum { - TF_SYNC = 0x00, - TF_ASYNC = 0x01, - TF_STATUS_CODE = 0x08, - TF_ACCEPT_FDS = 0x10, - TF_WAIT_TIME = 0x4, + NAPIInnerObserver(napi_env env, napi_value callback); + void OnChange(); + void DeleteReference(); + napi_ref GetCallback(); +private: + struct ObserverWorker { + std::weak_ptr observer_; + ObserverWorker(std::shared_ptr observerIn) + : observer_(observerIn) {} }; - MessageOption(int flags = TF_SYNC, int waitTime = TF_WAIT_TIME); - ~MessageOption() = default; - void SetFlags(int flags); - int GetFlags() const; - void SetWaitTime(int waitTime); - int GetWaitTime() const; -private: - uint32_t flags_; - int waitTime_; + napi_env env_ = nullptr; + napi_ref ref_ = nullptr; + uv_loop_s *loop_ = nullptr; }; -using MessageOptionPtr = std::shared_ptr; -} // namespace OHOS -#endif // OHOS_IPC_MESSAGE_OPTION_H \ No newline at end of file +} // namespace DataShare +} // namespace OHOS +#endif //NAPI_DATASHARE_INNER_OBSERVER_H diff --git a/data_share/frameworks/js/napi/dataShare/include/napi_datashare_observer.h b/data_share/frameworks/js/napi/dataShare/include/napi_datashare_observer.h index ae88f0362c36b5f698879dfa47533143f7f70f31..fb0ac07211128a3cb45bcba6f2aae5d54051ea87 100644 --- a/data_share/frameworks/js/napi/dataShare/include/napi_datashare_observer.h +++ b/data_share/frameworks/js/napi/dataShare/include/napi_datashare_observer.h @@ -16,30 +16,17 @@ #ifndef NAPI_DATASHARE_OBSERVER_H #define NAPI_DATASHARE_OBSERVER_H -#include #include "data_ability_observer_stub.h" -#include "napi/native_common.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" +#include "napi_datashare_inner_observer.h" namespace OHOS { namespace DataShare { class NAPIDataShareObserver : public AAFwk::DataAbilityObserverStub { public: - NAPIDataShareObserver(napi_env env, napi_value callback); + explicit NAPIDataShareObserver(const std::shared_ptr observer) : observer_(observer){}; virtual ~NAPIDataShareObserver(); void OnChange() override; - void DeleteReference(); - napi_ref GetCallback(); -private: - struct ObserverWorker { - const NAPIDataShareObserver *observer_ = nullptr; - ObserverWorker(const NAPIDataShareObserver *observerIn) : observer_(observerIn) {} - }; - - napi_env env_ = nullptr; - napi_ref ref_ = nullptr; - uv_loop_s *loop_ = nullptr; + std::shared_ptr observer_ = nullptr; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp index f55ab910e786c3d5eb984282b994cfc72879a9e1..7ce19f082616e14c0db3026c29f064f32d3e9784 100644 --- a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp @@ -152,7 +152,7 @@ void AsyncCall::DeleteContext(napi_env env, AsyncContext *context) napi_delete_reference(env, context->self); napi_delete_async_work(env, context->work); } - if (context != nullptr) { + if (context != nullptr && context->ctx != nullptr) { context->ctx->exec_ = nullptr; context->ctx->input_ = nullptr; context->ctx->output_ = nullptr; diff --git a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp index 1a4586ee8a6803af945b3179543dd74c1e14db73..1539805875ccd0862bcf8a8913be7cc9ab2a605f 100644 --- a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp @@ -192,7 +192,10 @@ napi_value NapiDataShareHelper::Initialize(napi_env env, napi_callback_info info LOG_ERROR("Parameters error, need at least 2 parameters!"); return nullptr; } - auto *proxy = new NapiDataShareHelper(); + auto *proxy = new (std::nothrow) NapiDataShareHelper(); + if (proxy == nullptr) { + return nullptr; + } auto finalize = [](napi_env env, void * data, void * hint) { NapiDataShareHelper *proxy = reinterpret_cast(data); delete proxy; @@ -700,7 +703,7 @@ bool NapiDataShareHelper::HasRegisteredObserver(napi_env env, std::listGetCallback())) { + if (DataShareJSUtils::Equals(env, callback, it->observer_->GetCallback())) { LOG_DEBUG("The observer has already subscribed."); return true; } @@ -718,7 +721,8 @@ void NapiDataShareHelper::RegisteredObserver(napi_env env, const std::string &ur LOG_DEBUG("has registered observer"); return; } - sptr observer(new (std::nothrow) NAPIDataShareObserver(env, callback)); + auto innerObserver = std::make_shared(env, callback); + sptr observer(new (std::nothrow) NAPIDataShareObserver(innerObserver)); if (observer == nullptr) { LOG_ERROR("observer is nullptr"); return; @@ -738,12 +742,12 @@ void NapiDataShareHelper::UnRegisteredObserver(napi_env env, const std::string & auto &list = obs->second; auto it = list.begin(); while (it != list.end()) { - if (!DataShareJSUtils::Equals(env, callback, (*it)->GetCallback())) { + if (!DataShareJSUtils::Equals(env, callback, (*it)->observer_->GetCallback())) { ++it; continue; } datashareHelper_->UnregisterObserver(Uri(uri), *it); - (*it)->DeleteReference(); + (*it)->observer_->DeleteReference(); it = list.erase(it); break; } @@ -764,7 +768,7 @@ void NapiDataShareHelper::UnRegisteredObserver(napi_env env, const std::string & auto it = list.begin(); while (it != list.end()) { datashareHelper_->UnregisterObserver(Uri(uri), *it); - (*it)->DeleteReference(); + (*it)->observer_->DeleteReference(); it = list.erase(it); } observerMap_.erase(uri); diff --git a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e0f21d735c2709dc701ef973415e850f2b1af1b9 --- /dev/null +++ b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_inner_observer.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 "napi_datashare_observer.h" + +#include +#include "datashare_log.h" + +namespace OHOS { +namespace DataShare { +NAPIInnerObserver::NAPIInnerObserver(napi_env env, napi_value callback) + : env_(env) +{ + napi_create_reference(env, callback, 1, &ref_); + napi_get_uv_event_loop(env, &loop_); +} + +void NAPIInnerObserver::OnChange() +{ + LOG_DEBUG("NAPIInnerObserver Start"); + if (ref_ == nullptr) { + LOG_ERROR("ref_ is nullptr"); + return; + } + ObserverWorker *observerWorker = new (std::nothrow)ObserverWorker(shared_from_this()); + if (observerWorker == nullptr) { + LOG_ERROR("Failed to create observerWorker"); + return; + } + uv_work_t *work = new (std::nothrow)uv_work_t(); + if (work == nullptr) { + delete observerWorker; + LOG_ERROR("Failed to create uv work"); + return; + } + work->data = observerWorker; + int ret = uv_queue_work(loop_, work, + [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + LOG_DEBUG("uv_queue_work start"); + std::shared_ptr innerWorker(reinterpret_cast(work->data)); + auto observer = innerWorker->observer_.lock(); + if (observer == nullptr || observer->ref_ == nullptr) { + delete work; + LOG_ERROR("innerWorker->observer_->ref_ is nullptr"); + return; + } + napi_handle_scope scope = nullptr; + napi_open_handle_scope(observer->env_, &scope); + if (scope == nullptr) { + delete work; + return; + } + napi_value callback = nullptr; + napi_value args[2] = {0}; + napi_value global = nullptr; + napi_value result; + napi_get_reference_value(observer->env_, observer->ref_, &callback); + napi_get_global(observer->env_, &global); + napi_status callStatus = napi_call_function(observer->env_, global, callback, 2, args, &result); + napi_close_handle_scope(observer->env_, scope); + if (callStatus != napi_ok) { + LOG_ERROR("napi_call_function failed status : %{public}d", callStatus); + } + delete work; + }); + if (ret != 0) { + LOG_ERROR("uv_queue_work failed"); + delete observerWorker; + delete work; + } +} + +void NAPIInnerObserver::DeleteReference() +{ + if (ref_ != nullptr) { + napi_delete_reference(env_, ref_); + ref_ = nullptr; + } +} + +napi_ref NAPIInnerObserver::GetCallback() +{ + return ref_; +} +} // namespace DataShare +} // namespace OHOS diff --git a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_observer.cpp b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_observer.cpp index 0b6df0d0082b10fe3bbc48c7a87002d5d8679cb7..997cf479a2fd70662ea235010b66c5a627ed4a5f 100644 --- a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_observer.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_observer.cpp @@ -19,82 +19,12 @@ namespace OHOS { namespace DataShare { -NAPIDataShareObserver::NAPIDataShareObserver(napi_env env, napi_value callback) - : env_(env) -{ - napi_create_reference(env, callback, 1, &ref_); - napi_get_uv_event_loop(env, &loop_); -} - NAPIDataShareObserver::~NAPIDataShareObserver() {} void NAPIDataShareObserver::OnChange() { - LOG_DEBUG("Start"); - if (ref_ == nullptr) { - LOG_ERROR("ref_ is nullptr"); - return; - } - ObserverWorker *observerWorker = new (std::nothrow)ObserverWorker(this); - if (observerWorker == nullptr) { - LOG_ERROR("Failed to create observerWorker"); - return; - } - uv_work_t *work = new (std::nothrow)uv_work_t(); - if (work == nullptr) { - delete observerWorker; - LOG_ERROR("Failed to create uv work"); - return; - } - work->data = observerWorker; - int ret = uv_queue_work(loop_, work, - [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - LOG_DEBUG("uv_queue_work start"); - std::shared_ptr innerWorker(reinterpret_cast(work->data)); - if (innerWorker->observer_->ref_ == nullptr) { - delete work; - LOG_ERROR("innerWorker->observer_->ref_ is nullptr"); - return; - } - napi_handle_scope scope = nullptr; - napi_open_handle_scope(innerWorker->observer_->env_, &scope); - if (scope == nullptr) { - return; - } - napi_value callback = nullptr; - napi_value args[2] = {0}; - napi_value global = nullptr; - napi_value result; - napi_get_reference_value(innerWorker->observer_->env_, - innerWorker->observer_->ref_, &callback); - napi_get_global(innerWorker->observer_->env_, &global); - napi_status callStatus = - napi_call_function(innerWorker->observer_->env_, global, callback, 2, args, &result); - napi_close_handle_scope(innerWorker->observer_->env_, scope); - if (callStatus != napi_ok) { - LOG_ERROR("napi_call_function failed status : %{public}d", callStatus); - } - delete work; - }); - if (ret != 0) { - LOG_ERROR("uv_queue_work failed"); - delete observerWorker; - delete work; - } -} - -void NAPIDataShareObserver::DeleteReference() -{ - if (ref_ != nullptr) { - napi_delete_reference(env_, ref_); - ref_ = nullptr; - } -} - -napi_ref NAPIDataShareObserver::GetCallback() -{ - return ref_; + LOG_DEBUG("NAPIDataShareObserver Start"); + observer_->OnChange(); } } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/common/include/adaptor.h b/data_share/frameworks/native/common/include/adaptor.h index 074ac634a8f71507e29c9680c58c6be69e1206ab..8f9b2290b53ef1c37ec95a78eae0de23f7c3ac03 100644 --- a/data_share/frameworks/native/common/include/adaptor.h +++ b/data_share/frameworks/native/common/include/adaptor.h @@ -25,7 +25,7 @@ #else #include "hitrace.h" -#define DISTRIBUTED_DATA_HITRACE(trace) HiTrace hitrace(trace) +#define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING #endif diff --git a/data_share/frameworks/native/common/src/ishared_result_set_proxy.cpp b/data_share/frameworks/native/common/src/ishared_result_set_proxy.cpp index 91e58cc5bf182092ace04712fb011c6f01e480da..2df45f5e7be43f01bdf35d39db0b3a43499ed418 100644 --- a/data_share/frameworks/native/common/src/ishared_result_set_proxy.cpp +++ b/data_share/frameworks/native/common/src/ishared_result_set_proxy.cpp @@ -15,7 +15,6 @@ #include "ishared_result_set_proxy.h" -#include "adaptor.h" #include "datashare_errno.h" #include "datashare_log.h" #include "iremote_proxy.h" @@ -74,7 +73,6 @@ int ISharedResultSetProxy::GetAllColumnNames(std::vector &columnNam int ISharedResultSetProxy::GetRowCount(int &count) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (rowCount_ >= 0) { count = rowCount_; return E_OK; diff --git a/data_share/frameworks/native/provider/include/datashare_ext_ability.h b/data_share/frameworks/native/provider/include/datashare_ext_ability.h index e4a57eff9c7f5e3405bf8f75de88a7d39f20760a..dcafee55072271e1d02e082b01ea05812a7b8f3f 100644 --- a/data_share/frameworks/native/provider/include/datashare_ext_ability.h +++ b/data_share/frameworks/native/provider/include/datashare_ext_ability.h @@ -18,6 +18,7 @@ #include #include "extension_base.h" +#include "datashare_business_error.h" #include "datashare_values_bucket.h" #include "datashare_predicates.h" #include "datashare_result_set.h" @@ -138,11 +139,12 @@ public: * @param uri Indicates the path of data to query. * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null. * @param columns Indicates the columns to query. If this parameter is null, all columns are queried. + * @param businessError Indicates the error by query. * * @return Returns the query result. */ - virtual std::shared_ptr Query( - const Uri &uri, const DataSharePredicates &predicates, std::vector &columns); + virtual std::shared_ptr Query(const Uri &uri, const DataSharePredicates &predicates, + std::vector &columns, DatashareBusinessError &businessError); /** * @brief Obtains the MIME type matching the data specified by the URI of the Data ability. This method should be diff --git a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h index 51de22dade934a608468a42cbbbbb829044aafaa..41a61e333d60743ddc2e2210c9030dcd4b2a2c5d 100644 --- a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h +++ b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h @@ -158,7 +158,7 @@ public: * @return Returns the query result. */ std::shared_ptr Query(const Uri &uri, const DataSharePredicates &predicates, - std::vector &columns) override; + std::vector &columns, DatashareBusinessError &businessError) override; /** * @brief Obtains the MIME type matching the data specified by the URI of the Data ability. This method should be diff --git a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp index d4a51eb534672a82b82aa7b28f57972c0d241acd..66e6fafff0d9be6037f2c492a0b1913f54219295 100644 --- a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp @@ -95,7 +95,7 @@ int DataShareExtAbility::Delete(const Uri &uri, const DataSharePredicates &predi } std::shared_ptr DataShareExtAbility::Query(const Uri &uri, - const DataSharePredicates &predicates, std::vector &columns) + const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { return nullptr; } diff --git a/data_share/frameworks/native/provider/src/datashare_stub.cpp b/data_share/frameworks/native/provider/src/datashare_stub.cpp index 7b5682e082fc752a8f0cb83ae65f8e8fc21ef3f1..531db554222fd9c3e1e3cafecd7362a5206957a7 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub.cpp @@ -20,6 +20,7 @@ #include "ipc_types.h" #include "ishared_result_set.h" #include "itypes_utils.h" +#include "unistd.h" namespace OHOS { namespace DataShare { @@ -114,8 +115,10 @@ ErrCode DataShareStub::CmdOpenFile(MessageParcel &data, MessageParcel &reply) } if (!reply.WriteFileDescriptor(fd)) { LOG_ERROR("fail to WriteFileDescriptor fd"); + close(fd); return ERR_INVALID_VALUE; } + close(fd); return DATA_SHARE_NO_ERROR; } diff --git a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp index 106faf0c28d137371579091b9352a64263b7c2c6..8a12e916d3a5c4aa3043434b6a7e70b30bd67b75 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp @@ -218,8 +218,8 @@ std::shared_ptr DataShareStubImpl::Query(const Uri &uri, return resultSet; } - std::function syncTaskFunc = [=, &columns, &resultSet, &extension]() { - resultSet = extension->Query(uri, predicates, columns); + std::function syncTaskFunc = [=, &columns, &resultSet, &businessError, &extension]() { + resultSet = extension->Query(uri, predicates, columns, businessError); }; std::function getRetFunc = [=, &resultSet, &businessError, client = sptr(this)]() -> bool { diff --git a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp index 71374a5e3cfa3bbf0790b0c17137ef09eefc96de..579620c65831f78bda1a95b1e93150da1fd96a8c 100644 --- a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp +++ b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp @@ -91,7 +91,7 @@ void DataShareUvQueue::Purge(uv_work_t* work) LOG_ERROR("invalid work"); return; } - if(work->data == nullptr) { + if (work->data == nullptr) { LOG_ERROR("invalid work->data"); delete work; return; diff --git a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp index c7bd388dffe8c79764a0f076ebcb6e429261887f..f4ab77ce1f9d7e12ece479960763ab7e983df36c 100644 --- a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp @@ -236,7 +236,11 @@ NativeValue* JsDataShareExtAbility::CallObjectMethod(const char* name, NativeVal } size_t count = argc + 1; - NativeValue **args = new NativeValue *[count]; + NativeValue **args = new (std::nothrow) NativeValue *[count]; + if (args == nullptr) { + LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new NativeValue error."); + return nullptr; + } for (size_t i = 0; i < argc; i++) { args[i] = argv[i]; } @@ -485,10 +489,10 @@ int JsDataShareExtAbility::Delete(const Uri &uri, const DataSharePredicates &pre } std::shared_ptr JsDataShareExtAbility::Query(const Uri &uri, - const DataSharePredicates &predicates, std::vector &columns) + const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { std::shared_ptr ret; - ret = DataShareExtAbility::Query(uri, predicates, columns); + ret = DataShareExtAbility::Query(uri, predicates, columns, businessError); HandleScope handleScope(jsRuntime_); napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); diff --git a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp index e27ec5496de730f47f905c760ccad934dbbbc87c..c91920c684e4e10ed1a8fa4a6e0836b0e62fd650 100644 --- a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp @@ -53,6 +53,10 @@ void DataShareManagerImpl::LinkToDeath(const sptr remote) { sptr deathRecipient = new (std::nothrow) DataShareManagerImpl::ServiceDeathRecipient(this); + if (deathRecipient == nullptr) { + LOG_ERROR("DataShareManagerImpl::LinkToDeath new ServiceDeathRecipient error."); + return; + } if (!remote->AddDeathRecipient(deathRecipient)) { LOG_ERROR("add death recipient failed"); } diff --git a/data_share/interfaces/inner_api/BUILD.gn b/data_share/interfaces/inner_api/BUILD.gn index b0074329cc43771c6f28d67c99f88d4bdbb82743..cadbb1268bf09db10bcf8e94e009a9788a980e10 100644 --- a/data_share/interfaces/inner_api/BUILD.gn +++ b/data_share/interfaces/inner_api/BUILD.gn @@ -77,7 +77,7 @@ ohos_shared_library("datashare_consumer") { "ability_runtime:dataobs_manager", "c_utils:utils", "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", + "ipc:ipc_single", "ipc_js:rpc", "napi:ace_napi", "samgr:samgr_proxy", @@ -118,7 +118,7 @@ ohos_shared_library("datashare_provider") { "access_token:libaccesstoken_sdk", "c_utils:utils", "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", + "ipc:ipc_single", "ipc_js:rpc", "napi:ace_napi", ] diff --git a/data_share/interfaces/inner_api/common/include/datashare_predicates.h b/data_share/interfaces/inner_api/common/include/datashare_predicates.h index 7b24e1a9295e2251fe696437c5d08f5c3fdced76..df8b5edac58c0c9a9ef24139949eb52fc99eb5cc 100644 --- a/data_share/interfaces/inner_api/common/include/datashare_predicates.h +++ b/data_share/interfaces/inner_api/common/include/datashare_predicates.h @@ -126,7 +126,7 @@ public: } /** - * @brief The LessThanOrEqualTo of the predicate. + * @brief The In of the predicate. * * @param field Indicates the target field. * @param value Indicates the queried value. diff --git a/data_share/test/native/BUILD.gn b/data_share/test/native/BUILD.gn index 41b9a93703e19e6fff30398017a7401436c4d4d1..8c5ee15a76ff78cfe30a6e0909fc5f1b10127024 100644 --- a/data_share/test/native/BUILD.gn +++ b/data_share/test/native/BUILD.gn @@ -146,7 +146,7 @@ ohos_unittest("ErrorCodeTest") { "data_share:datashare_common", "data_share:datashare_consumer", "hilog_native:libhilog", - "ipc:ipc_core", + "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp index ad447fde8e5e8f9b75be068a8043e276988b3dfa..223438515e08f266939ffc9d197ea800fca35e90 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp @@ -300,7 +300,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_006, TestSize.Le vector columns; Uri uri(MEDIALIBRARY_DATA_URI); auto resultSet = helper->Query(uri, predicates, columns); - int result = 0; + int result = -1; if (resultSet != nullptr) { resultSet->GetRowCount(result); } diff --git a/datamgr_service/conf/config.json b/datamgr_service/conf/config.json index 91ca003bbdfef4b4bd57c1f761faafd67e6c6e49..2bf2041c482b6ff09353488f26ac35bbfb0fbe7d 100644 --- a/datamgr_service/conf/config.json +++ b/datamgr_service/conf/config.json @@ -16,6 +16,9 @@ }, { "lib": "libconfigdemo2.z.so" + }, + { + "lib": "libudmf_server.z.so" } ], "bundleChecker": { diff --git a/datamgr_service/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp index 2ab4cb2246dcb50413469aeaebe92c6a4a41c9e5..36f24cafb6eef21e923a9e8083f4a6c8d82759bb 100644 --- a/datamgr_service/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp @@ -18,6 +18,7 @@ #include "uninstaller_impl.h" #include #include +#include "bundle_common_event.h" #include "common_event_manager.h" #include "common_event_support.h" #include "device_manager_adapter.h" @@ -46,7 +47,7 @@ void UninstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) Want want = event.GetWant(); std::string action = want.GetAction(); if (action != CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED && - action != CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { + action != OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { return; } @@ -82,7 +83,7 @@ Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService) } MatchingSkills matchingSkills; matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); + matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); CommonEventSubscribeInfo info(matchingSkills); auto callback = [kvStoreDataService](const std::string &bundleName, int32_t userId, int32_t appIndex) { kvStoreDataService->OnUninstall(bundleName, userId, appIndex, IPCSkeleton::GetCallingTokenID()); diff --git a/datamgr_service/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp b/datamgr_service/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp index 2fe059135ada0491a9815c2d12d9638cfca95434..22dc48a69084548bc1289e7f2e7f1ea47d3cecb6 100644 --- a/datamgr_service/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp @@ -37,11 +37,9 @@ void BackupRuleManager::LoadBackupRules(const std::vector &backupRu void BackupRuleManager::RegisterPlugin(const std::string &backupRule, std::function getter) { - auto it = getters_.Find(backupRule); - if (it.first) { - return; - } - getters_[backupRule] = getter; + getters_.ComputeIfAbsent(backupRule, [&getter](const auto &) { + return move(getter); + }); } bool BackupRuleManager::CanBackup() diff --git a/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp b/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp index b7213f3c229c99b10612b7946d77dd47aa8ee94f..825d9404b6a6b707d7a03cf23b392d9d27d1d753 100644 --- a/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/checker/checker_manager.cpp @@ -42,11 +42,9 @@ void CheckerManager::LoadCheckers(std::vector &checkers) void CheckerManager::RegisterPlugin(const std::string &checker, std::function getter) { - auto it = getters_.Find(checker); - if (it.first) { - return; - } - getters_[checker] = getter; + getters_.ComputeIfAbsent(checker, [&getter](const auto &) { + return move(getter); + }); } std::string CheckerManager::GetAppId(const StoreInfo &info) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.cpp index 329b9499858320981a904531decca0e44b47a89e..2b28637838e823183370c9a5cad4a811b73e93c9 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #define LOG_TAG "DataShareProfileInfo" #include "data_share_profile_info.h" @@ -57,9 +57,7 @@ bool ProfileInfo::Marshal(json &node) const bool ProfileInfo::Unmarshal(const json &node) { - bool ret = true; - ret = GetValue(node, GET_NAME(tableConfig), tableConfig) && ret; - return ret; + return GetValue(node, GET_NAME(tableConfig), tableConfig); } bool DataShareProfileInfo::GetProfileInfoFromExtension(const AppExecFwk::BundleInfo &bundleInfo, @@ -71,15 +69,14 @@ bool DataShareProfileInfo::GetProfileInfoFromExtension(const AppExecFwk::BundleI return true; } - for (auto &item : bundleInfo.extensionInfos) { + for (auto const &item : bundleInfo.extensionInfos) { if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - std::vector infos; bool isCompressed = !item.hapPath.empty(); std::string resourcePath = isCompressed ? item.hapPath : item.resourcePath; - if (!GetResProfileByMetadata(item.metadata, resourcePath, isCompressed, infos) || infos.empty()) { - ZLOGE("failed, bundleName is %{public}s, resourcePath is %{public}s, metadata.size is %{public}zu," - "infos.size is %{public}zu", bundleInfo.name.c_str(), resourcePath.c_str(), item.metadata.size(), - infos.size()); + std::vector infos = GetResProfileByMetadata(item.metadata, resourcePath, isCompressed); + if (infos.empty()) { + ZLOGE("failed, bundleName is %{public}s, resourcePath is %{public}s, metadata.size is %{public}zu,", + bundleInfo.name.c_str(), resourcePath.c_str(), item.metadata.size()); return false; } return profileInfo.Unmarshall(infos[0]); @@ -89,23 +86,24 @@ bool DataShareProfileInfo::GetProfileInfoFromExtension(const AppExecFwk::BundleI return false; } -bool DataShareProfileInfo::GetResProfileByMetadata(const std::vector &metadata, - const std::string &resourcePath, bool isCompressed, std::vector &profileInfos) const +std::vector DataShareProfileInfo::GetResProfileByMetadata( + const std::vector &metadata, const std::string &resourcePath, bool isCompressed) const { + std::vector profileInfos; if (metadata.empty() || resourcePath.empty()) { - return false; + return profileInfos; } std::shared_ptr resMgr = InitResMgr(resourcePath); if (resMgr == nullptr) { - return false; + return profileInfos; } - for (auto &meta : metadata) { + for (auto const &meta : metadata) { if (meta.name.compare(DATA_SHARE_PROFILE_META) == 0) { - return GetResFromResMgr(meta.resource, *resMgr, isCompressed, profileInfos); + return GetResFromResMgr(meta.resource, *resMgr, isCompressed); } } - return false; + return profileInfos; } std::shared_ptr DataShareProfileInfo::InitResMgr(const std::string &resourcePath) const @@ -128,17 +126,18 @@ std::shared_ptr DataShareProfileInfo::InitResMgr(const std::str return resMgr; } -bool DataShareProfileInfo::GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, - bool isCompressed, std::vector &profileInfos) const +std::vector DataShareProfileInfo::GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, + bool isCompressed) const { + std::vector profileInfos; if (resName.empty()) { - return false; + return profileInfos; } size_t pos = resName.rfind(PROFILE_FILE_PREFIX); if ((pos == std::string::npos) || (pos == resName.length() - PROFILE_PREFIX_LEN)) { ZLOGE("res name invalid, resName is %{public}s", resName.c_str()); - return false; + return profileInfos; } std::string profileName = resName.substr(pos + PROFILE_PREFIX_LEN); // hap is compressed status, get file content. @@ -150,34 +149,34 @@ bool DataShareProfileInfo::GetResFromResMgr(const std::string &resName, Resource if (ret != SUCCESS || fileContent == nullptr) { ZLOGE("failed, ret is %{public}d, profileName is %{public}s", ret, profileName.c_str()); - return false; + return profileInfos; } if (len == 0) { ZLOGE("fileContent is empty, profileName is %{public}s", profileName.c_str()); - return false; + return profileInfos; } std::string rawData(fileContent.get(), fileContent.get() + len); if (!Config::IsJson(rawData)) { ZLOGE("rawData is not json, profileName is %{public}s", profileName.c_str()); - return false; + return profileInfos; } profileInfos.push_back(std::move(rawData)); - return true; + return profileInfos; } // hap is decompressed status, get file path then read file. std::string resPath; RState ret = resMgr.GetProfileByName(profileName.c_str(), resPath); if (ret != SUCCESS) { ZLOGE("profileName not found, ret is %{public}d, profileName is %{public}s", ret, profileName.c_str()); - return false; + return profileInfos; } std::string profile = ReadProfile(resPath); if (profile.empty()) { ZLOGE("Read profile failed, resPath is %{public}s", resPath.c_str()); - return false; + return profileInfos; } profileInfos.push_back(std::move(profile)); - return true; + return profileInfos; } bool DataShareProfileInfo::IsFileExisted(const std::string &filePath) const diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.h index 9dac5236f18ff97902976f82cb3639da46e05aa4..b943aaf15f67ca7343116f43dd9510c5cf98c3a4 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_info.h @@ -45,11 +45,11 @@ public: ProfileInfo &profileInfo, bool &isSingleApp); private: - bool GetResProfileByMetadata(const std::vector &metadata, const std::string &resourcePath, - bool isCompressed, std::vector &profileInfos) const; + std::vector GetResProfileByMetadata(const std::vector &metadata, + const std::string &resourcePath, bool isCompressed) const; std::shared_ptr InitResMgr(const std::string &basicString) const; - bool GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, bool isCompressed, - std::vector &profileInfos) const; + std::vector GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, + bool isCompressed) const; std::string ReadProfile(const std::string &resPath) const; bool IsFileExisted(const std::string &filePath) const; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 63c9fd3ff2c1247aa41dda32c75bba015706f590..4fc2ca94e9edab4330926dc2383d68f65ca29caf 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -212,13 +212,12 @@ std::string DataShareServiceImpl::GetRealityTableName(uint32_t tokenId, const Ap PermissionProxy::PermissionState DataShareServiceImpl::VerifyPermission(uint32_t tokenID, DataShareServiceImpl::PermissionType permissionType, const AppExecFwk::BundleInfo &bundleInfo) { - std::string permission; switch (permissionType) { case PermissionType::READ_PERMISSION: { - return PermissionProxy::QueryReadPermission(tokenID, permission, bundleInfo); + return PermissionProxy::QueryReadPermission(tokenID, bundleInfo); } case PermissionType::WRITE_PERMISSION: { - return PermissionProxy::QueryWritePermission(tokenID, permission, bundleInfo); + return PermissionProxy::QueryWritePermission(tokenID, bundleInfo); } } return PermissionProxy::PermissionState::NOT_FIND; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.cpp index 0403006b7c07d5f79ca8f3c8a0c628dc91aeb8ce..ab68c1df1d60a5b04210341690b72dd7a10f6f02 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.cpp @@ -38,17 +38,16 @@ bool PermissionProxy::GetBundleInfo(const std::string &bundleName, uint32_t toke } PermissionProxy::PermissionState PermissionProxy::QueryWritePermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo) + const AppExecFwk::BundleInfo &bundleInfo) { - for (auto &item : bundleInfo.extensionInfos) { + for (auto const &item : bundleInfo.extensionInfos) { if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - permission = item.writePermission; - if (permission.empty()) { + if (item.writePermission.empty()) { ZLOGW("WritePermission is empty! BundleName is %{public}s, tokenId is %{public}x", bundleInfo.name.c_str(), tokenId); return PermissionState::NOT_FIND; } - int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); + int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, item.writePermission); if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { ZLOGE("Verify write permission denied!"); return PermissionState::DENIED; @@ -60,16 +59,16 @@ PermissionProxy::PermissionState PermissionProxy::QueryWritePermission(uint32_t } PermissionProxy::PermissionState PermissionProxy::QueryReadPermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo) + const AppExecFwk::BundleInfo &bundleInfo) { - for (auto &item : bundleInfo.extensionInfos) { + for (auto const &item : bundleInfo.extensionInfos) { if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { if (item.readPermission.empty()) { ZLOGW("ReadPermission is empty! BundleName is %{public}s, tokenId is %{public}x", bundleInfo.name.c_str(), tokenId); return PermissionState::NOT_FIND; } - int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); + int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, item.readPermission); if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { ZLOGE("Verify Read permission denied!"); return PermissionState::DENIED; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.h b/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.h index afc4be366277dde2c853057e72e0127593fd7644..69b6ae0a5b4c1eb9694a078dec2137259a2f0466 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/permission_proxy.h @@ -39,10 +39,8 @@ public: }; static bool GetBundleInfo(const std::string &bundleName, uint32_t tokenId, AppExecFwk::BundleInfo &bundleInfo); - static PermissionState QueryWritePermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo); - static PermissionState QueryReadPermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo); + static PermissionState QueryWritePermission(uint32_t tokenId, const AppExecFwk::BundleInfo &bundleInfo); + static PermissionState QueryReadPermission(uint32_t tokenId, const AppExecFwk::BundleInfo &bundleInfo); static bool QueryMetaData(const std::string &bundleName, const std::string &storeName, DistributedData::StoreMetaData &metaData, int32_t userId); static std::string GetTableNameByCrossUserMode(const ProfileInfo &profileInfo, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.cpp b/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.cpp index 96b41176c30420bcc6a9cbf10c7b35fc9025958b..b88ae0ace3047381bd5908cd3d6c29c390e18ccb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.cpp @@ -31,32 +31,32 @@ bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo, bool tab return false; } - uriInfo.bundleName = splitUri[URI_INDEX_BUNLDENAME]; - uriInfo.moduleName = splitUri[URI_INDEX_MODULENAME]; - uriInfo.storeName = splitUri[URI_INDEX_STORENAME]; - if (splitUri.size() > URI_INDEX_MIN) { - uriInfo.tableName = splitUri[URI_INDEX_TABLENAME]; + uriInfo.bundleName = splitUri[BUNDLE_NAME]; + uriInfo.moduleName = splitUri[MODULE_NAME]; + uriInfo.storeName = splitUri[STORE_NAME]; + if (splitUri.size() > OPTIONAL_BEGIN) { + uriInfo.tableName = splitUri[TABLE_NAME]; } return true; } bool URIUtils::IsValidPath(const std::vector &splitUri, bool tableNameEmpty) { - if (splitUri.size() < URI_INDEX_MIN) { + if (splitUri.size() < OPTIONAL_BEGIN) { return false; } - if (splitUri[URI_INDEX_BUNLDENAME].empty() || splitUri[URI_INDEX_MODULENAME].empty() || - splitUri[URI_INDEX_STORENAME].empty()) { + if (splitUri[BUNDLE_NAME].empty() || splitUri[MODULE_NAME].empty() || + splitUri[STORE_NAME].empty()) { ZLOGE("Uri has empty field!"); return false; } if (!tableNameEmpty) { - if (splitUri.size() < URI_INDEX_MAX) { + if (splitUri.size() < PARAM_BUTT) { ZLOGE("Uri need contains tableName"); return false; } - if (splitUri[URI_INDEX_TABLENAME].empty()) { + if (splitUri[TABLE_NAME].empty()) { ZLOGE("Uri tableName can't be empty!"); return false; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.h b/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.h index 625c45a9056457cb0fbfb21258d4c915dfc275bc..659773b2e71b2b97496e2c15f029836980badb4f 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/uri_utils.h @@ -38,12 +38,14 @@ public: private: static bool IsValidPath(const std::vector &splitUri, bool tableNameEmpty); - static constexpr size_t URI_INDEX_BUNLDENAME = 0; - static constexpr size_t URI_INDEX_MODULENAME = 1; - static constexpr size_t URI_INDEX_STORENAME = 2; - static constexpr size_t URI_INDEX_TABLENAME = 3; - static constexpr size_t URI_INDEX_MIN = 3; - static constexpr size_t URI_INDEX_MAX = 4; + enum PATH_PARAM : int32_t { + BUNDLE_NAME = 0, + MODULE_NAME, + STORE_NAME, + OPTIONAL_BEGIN, + TABLE_NAME = OPTIONAL_BEGIN, + PARAM_BUTT + }; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_URI_UTILS_H diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp index 5fbd181433602db4a06f619b54ae46b2abe5151b..6a3fc5d148e7e616be49f31cd65f471353853aa4 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -53,15 +53,19 @@ std::set UserDelegate::GetLocalUsers() ZLOGE("failed to get local device id"); return {}; } - if (!deviceUserMap_.Contains(deviceId)) { - LoadFromMeta(deviceId); - } std::set users; - deviceUserMap_.ComputeIfPresent(deviceId, [&users](auto&, std::map &value) { - for (auto [user, active] : value) { + deviceUserMap_.Compute(deviceId, [&users](const auto &key, auto &userMap) { + if (userMap.empty()) { + UserMetaData userMetaData; + MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); + for (const auto &user : userMetaData.users) { + userMap.insert_or_assign(user.id, user.isActive); + } + } + for (const auto [user, active] : userMap) { users.emplace(std::to_string(user)); } - return !value.empty(); + return !userMap.empty(); }); return users; } @@ -78,12 +82,19 @@ std::vector UserDelegate::GetRemoteUserStatus(const std::vector UserDelegate::GetUsers(const std::string &deviceId) { std::vector userStatus; - if (!deviceUserMap_.Contains(deviceId)) { - LoadFromMeta(deviceId); - } - for (const auto &entry : deviceUserMap_[deviceId]) { - userStatus.emplace_back(entry.first, entry.second); - } + deviceUserMap_.Compute(deviceId, [&userStatus](const auto &key, auto &userMap) { + if (userMap.empty()) { + UserMetaData userMetaData; + MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); + for (const auto &user : userMetaData.users) { + userMap.insert_or_assign(user.id, user.isActive); + } + } + for (const auto [key, value] : userMap) { + userStatus.emplace_back(key, value); + } + return !userMap.empty(); + }); ZLOGI("device:%{public}s, users:%{public}s", Anonymous::Change(deviceId).c_str(), Serializable::Marshall(userStatus).c_str()); return userStatus; @@ -96,17 +107,15 @@ void UserDelegate::DeleteUsers(const std::string &deviceId) void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector &userStatus) { - ZLOGI("begin, device:%{public}.10s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size()); + ZLOGI("begin, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size()); deviceUserMap_.Compute(deviceId, [&userStatus](const auto &key, std::map &userMap) { userMap = {}; - for (auto &user : userStatus) { - userMap[user.id] = user.isActive; + for (const auto &user : userStatus) { + userMap.insert_or_assign(user.id, user.isActive); } + ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(key).c_str(), userMap.size()); return true; }); - - ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), - deviceUserMap_[deviceId].size()); } bool UserDelegate::InitLocalUserMeta() @@ -124,25 +133,16 @@ bool UserDelegate::InitLocalUserMeta() UserMetaData userMetaData; userMetaData.deviceId = GetLocalDeviceId(); UpdateUsers(userMetaData.deviceId, userStatus); - for (auto &pair : deviceUserMap_[userMetaData.deviceId]) { - userMetaData.users.emplace_back(pair.first, pair.second); - } - + deviceUserMap_.ComputeIfPresent(userMetaData.deviceId, [&userMetaData](const auto &, std::map &userMap) { + for (const auto &[key, value] : userMap) { + userMetaData.users.emplace_back(key, value); + } + return true; + }); ZLOGI("put user meta data save meta data"); return MetaDataManager::GetInstance().SaveMeta(UserMetaRow::GetKeyFor(userMetaData.deviceId), userMetaData); } -void UserDelegate::LoadFromMeta(const std::string &deviceId) -{ - UserMetaData userMetaData; - MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(deviceId), userMetaData); - std::map userMap; - for (const auto &user : userMetaData.users) { - userMap[user.id] = user.isActive; - } - deviceUserMap_[deviceId] = userMap; -} - UserDelegate &UserDelegate::GetInstance() { static UserDelegate instance; diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.h b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.h index fb3797d63837635d51dff7132e45e5672d0130c9..440c25f7f623ca97eb8d9d4931088374eee81e1f 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.h @@ -56,7 +56,6 @@ private: UserDelegate &userDelegate_; }; std::vector GetUsers(const std::string &deviceId); - void LoadFromMeta(const std::string &deviceId); void UpdateUsers(const std::string &deviceId, const std::vector &userStatus); void DeleteUsers(const std::string &deviceId); bool NotifyUserEvent(const UserEvent &userEvent); diff --git a/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp b/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp index 6430fac49a239e8694df403b529cb632149f4093..b1ee7541b3651285cd9fb73bfe34b98e87d596ce 100644 --- a/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/config_factory_test.cpp @@ -61,7 +61,7 @@ HWTEST_F(ConfigFactoryTest, ComponentConfig, TestSize.Level0) { auto *components = ConfigFactory::GetInstance().GetComponentConfig(); ASSERT_NE(components, nullptr); - ASSERT_EQ(components->size(), 2); + ASSERT_EQ(components->size(), 3); const ComponentConfig &config = (*components)[0]; ASSERT_EQ(config.description, "3rd party adapter"); ASSERT_EQ(config.lib, "libconfigdemo.z.so"); diff --git a/kv_store/frameworks/common/task_scheduler.h b/kv_store/frameworks/common/task_scheduler.h index 478fff8e6b0803669dbe992f8603f6fec486a784..68245bd2a6bbd4116d4cc2077abed0697f760202 100644 --- a/kv_store/frameworks/common/task_scheduler.h +++ b/kv_store/frameworks/common/task_scheduler.h @@ -28,7 +28,7 @@ #include "visibility.h" namespace OHOS { -class API_LOCAL TaskScheduler { +class TaskScheduler { public: using TaskId = uint64_t; using Time = std::chrono::steady_clock::time_point; @@ -52,7 +52,6 @@ public: } TaskScheduler(const std::string &name) : TaskScheduler(std::numeric_limits::max(), name) {} TaskScheduler(size_t capacity = std::numeric_limits::max()) : TaskScheduler(capacity, "") {} - ~TaskScheduler() { isRunning_ = false; @@ -60,7 +59,6 @@ public: Execute([]() {}); thread_->join(); } - // execute task at specific time TaskId At(const Time &begin, Task task, Duration interval = INVALID_INTERVAL, uint64_t times = UNLIMITED_TIMES) { @@ -80,7 +78,6 @@ public: indexes_[innerTask.taskId] = it; return innerTask.taskId; } - TaskId Reset(TaskId taskId, const Duration &interval) { std::unique_lock lock(mutex_); @@ -88,17 +85,14 @@ public: running_.interval = interval; return running_.taskId; } - auto index = indexes_.find(taskId); if (index == indexes_.end()) { return INVALID_TASK_ID; } - auto &innerTask = index->second->second; if (innerTask.interval != INVALID_INTERVAL) { innerTask.interval = interval; } - auto it = tasks_.insert({ std::chrono::steady_clock::now() + interval, std::move(innerTask) }); if (it == tasks_.begin() || index->second == tasks_.begin()) { condition_.notify_one(); @@ -107,20 +101,17 @@ public: indexes_[taskId] = it; return taskId; } - void Clean() { std::unique_lock lock(mutex_); indexes_.clear(); tasks_.clear(); } - // execute task periodically with duration TaskId Every(Duration interval, Task task) { return At(std::chrono::steady_clock::now() + interval, task, interval); } - // remove task in SchedulerTask void Remove(TaskId taskId, bool wait = false) { @@ -129,31 +120,27 @@ public: return (!wait || running_.taskId != taskId); }); auto index = indexes_.find(taskId); - if (index != indexes_.end()) { + if (index == indexes_.end()) { return; } tasks_.erase(index->second); indexes_.erase(index); condition_.notify_one(); } - // execute task periodically with duration after delay TaskId Every(Duration delay, Duration interval, Task task) { return At(std::chrono::steady_clock::now() + delay, task, interval); } - // execute task for some times periodically with duration after delay TaskId Every(int32_t times, Duration delay, Duration interval, Task task) { return At(std::chrono::steady_clock::now() + delay, task, interval, times); } - TaskId Execute(Task task) { return At(std::chrono::steady_clock::now(), std::move(task)); } - private: struct InnerTask { TaskId taskId = INVALID_TASK_ID; @@ -182,11 +169,9 @@ private: tasks_.erase(it); running_.times--; } - if (exec) { exec(); } - { std::unique_lock lock(mutex_); if (running_.interval != INVALID_INTERVAL && running_.times > 0) { diff --git a/kv_store/frameworks/common/test/task_scheduler_test.cpp b/kv_store/frameworks/common/test/task_scheduler_test.cpp index 67e27fc266ad991264d9e13c43b6132bc46f9274..5b3b3fdf45579fb03a517ea5f77c596afb719da2 100644 --- a/kv_store/frameworks/common/test/task_scheduler_test.cpp +++ b/kv_store/frameworks/common/test/task_scheduler_test.cpp @@ -24,8 +24,8 @@ using namespace OHOS; using duration = std::chrono::steady_clock::duration; class TaskSchedulerTest : public testing::Test { public: - static constexpr uint32_t SHORT_INTERVAL = 100; - static constexpr uint32_t LONG_INTERVAL = 300; + static constexpr uint32_t SHORT_INTERVAL = 100; // ms + static constexpr uint32_t LONG_INTERVAL = 1; // s static void SetUpTestCase(void){}; static void TearDownTestCase(void){}; void SetUp(){}; @@ -62,21 +62,23 @@ HWTEST_F(TaskSchedulerTest, At, TestSize.Level0) /** * @tc.name: Every -* @tc.desc: +* @tc.desc:execute task periodically with duration * @tc.type: FUNC * @tc.require: * @tc.author: ht */ -HWTEST_F(TaskSchedulerTest, Every, TestSize.Level0) +HWTEST_F(TaskSchedulerTest, ExecuteDuration, TestSize.Level0) { TaskScheduler taskScheduler("everyTest"); auto blockData = std::make_shared>(LONG_INTERVAL, 0); - taskScheduler.Every(std::chrono::milliseconds(SHORT_INTERVAL), [blockData]() { - int testData = 1; + int testData = 0; + taskScheduler.Every(std::chrono::milliseconds(SHORT_INTERVAL), [blockData, &testData]() { + testData++; blockData->SetValue(testData); }); - for (int i = 1; i < 5; ++i) { - ASSERT_EQ(blockData->GetValue(), 1); + for (int i = 1; i < 10; ++i) { + ASSERT_EQ(blockData->GetValue(), i); + blockData->Clear(0); } } @@ -151,3 +153,108 @@ HWTEST_F(TaskSchedulerTest, Reset3, TestSize.Level0) auto resetTaskId = taskScheduler.Reset(atTaskId, std::chrono::milliseconds(0)); ASSERT_EQ(resetTaskId, TaskScheduler::INVALID_TASK_ID); } + +/** +* @tc.name: Every +* @tc.desc: execute task for some times periodically with duration. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(TaskSchedulerTest, EveryExecuteTimes, TestSize.Level0) +{ + TaskScheduler taskScheduler("everyTimes"); + auto blockData = std::make_shared>(LONG_INTERVAL, 0); + int testData = 0; + int times = 5; + auto taskId = taskScheduler.Every(times, std::chrono::milliseconds(0), + std::chrono::milliseconds(SHORT_INTERVAL), [blockData, times, &testData]() { + testData++; + if (testData < times) { + blockData->Clear(testData); + return; + } + blockData->SetValue(testData); + }); + ASSERT_EQ(blockData->GetValue(), times); + auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); + ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID); + ASSERT_EQ(blockData->GetValue(), times); +} + +/** +* @tc.name: Remove +* @tc.desc: remove task before execute. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(TaskSchedulerTest, RemoveBeforeExecute, TestSize.Level0) +{ + TaskScheduler taskScheduler("RemoveBeforeExecute"); + auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL); + auto blockData = std::make_shared>(LONG_INTERVAL, 0); + int testData = 0; + auto taskId = taskScheduler.At(expiredTime, [blockData, testData]() { + int tmpData = testData + 1; + blockData->SetValue(tmpData); + }, std::chrono::milliseconds(SHORT_INTERVAL)); + taskScheduler.Remove(taskId); + auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); + ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID); + ASSERT_EQ(blockData->GetValue(), testData); +} + +/** +* @tc.name: Remove +* @tc.desc: remove task during execute, and waiting. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(TaskSchedulerTest, RemoveWaitExecute, TestSize.Level0) +{ + TaskScheduler taskScheduler("RemoveWaitExecute"); + auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(0); + auto blockDataTest = std::make_shared>(LONG_INTERVAL, 0); + auto blockDataWait = std::make_shared>(LONG_INTERVAL, 0); + int testData = 1; + auto taskId = taskScheduler.At(expiredTime, [blockDataTest, blockDataWait, &testData]() { + blockDataTest->SetValue(testData); + blockDataWait->GetValue(); + int tmpData = testData + 1; + blockDataTest->SetValue(tmpData); + }, std::chrono::milliseconds(SHORT_INTERVAL)); + ASSERT_EQ(blockDataTest->GetValue(), testData); + auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); + ASSERT_EQ(taskId, resetId); + taskScheduler.Remove(taskId, true); + ASSERT_EQ(blockDataTest->GetValue(), testData + 1); +} + +/** +* @tc.name: Remove +* @tc.desc: remove task during execute, but no wait. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(TaskSchedulerTest, RemoveNoWaitExecute, TestSize.Level0) +{ + TaskScheduler taskScheduler("RemoveNoWaitExecute"); + auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(0); + auto blockDataTest = std::make_shared>(LONG_INTERVAL, 0); + auto blockDataWait = std::make_shared>(LONG_INTERVAL, 0); + int testData = 1; + auto taskId = taskScheduler.At(expiredTime, [blockDataTest, blockDataWait, &testData]() { + blockDataTest->SetValue(testData); + blockDataWait->GetValue(); + int tmpData = testData + 1; + blockDataTest->SetValue(tmpData); + }); + ASSERT_EQ(blockDataTest->GetValue(), testData); + blockDataTest->Clear(0); + taskScheduler.Remove(taskId); + blockDataWait->SetValue(testData); + ASSERT_EQ(blockDataTest->GetValue(), testData + 1); +} \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h index 1d53bdc821f1c00af62129989a41ebb48ef9cbcf..85991d85f3134100d077ee2499dedcd2c7df1ba5 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h @@ -33,6 +33,7 @@ public: Status RegisterRemoteObserver(); Status UnregisterRemoteObserver(); void OnChange(const DBChangedData &data) override; + void OnServiceDeath(); private: class ObserverClient : public KvStoreObserverClient { diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index 00bfeb3a409b10e431f36d3fba62968080d911e0..87f0ab5eabc158e411c2463db02aaf5c040d7941 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -22,12 +22,15 @@ #include "dev_manager.h" #include "kv_store_nb_delegate.h" #include "kvdb_service.h" +#include "kvstore_death_recipient.h" #include "observer_bridge.h" #include "single_kvstore.h" #include "sync_observer.h" namespace OHOS::DistributedKv { -class SingleStoreImpl : public SingleKvStore, public DevManager::Observer { +class SingleStoreImpl : public SingleKvStore, + public DevManager::Observer, + public KvStoreDeathRecipient { public: using Observer = KvStoreObserver; using SyncCallback = KvStoreSyncCallback; @@ -67,6 +70,7 @@ public: std::map &status) override; void Online(const std::string &device) override; void Offline(const std::string &device) override; + void OnRemoteDied() override; // normal function int32_t Close(bool isForce = false); @@ -99,6 +103,7 @@ private: std::function BridgeReleaser(); Status DoSync(const SyncInfo &syncInfo, std::shared_ptr observer); void DoAutoSync(); + void Register(); bool autoSync_ = false; int32_t ref_ = 1; @@ -111,6 +116,8 @@ private: std::shared_ptr dbStore_ = nullptr; std::shared_ptr syncObserver_ = nullptr; ConcurrentMap>> observers_; + static constexpr int32_t INTERVAL = 500; // ms + uint64_t taskId_ = 0; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h index 4348b561a47956e85a4fcfab2e2afe67d54e758e..5a10d5df9a96b17e480fc2185f5b3b6ea923772d 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h @@ -20,7 +20,8 @@ namespace OHOS::DistributedKv { class TaskExecutor { public: static TaskExecutor &GetInstance(); - bool Execute(TaskScheduler::Task &&task, int32_t interval = 0); + TaskScheduler::TaskId Execute(TaskScheduler::Task &&task, int32_t interval = 0); + void RemoveTask(TaskScheduler::TaskId taskId); private: TaskExecutor(); diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp index 85019f8623ebef3619c4dd56ab56bf8d3c890369..373c8bf57f585ebc72673d90fb81046d70c8453e 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp @@ -106,4 +106,12 @@ std::vector ObserverBridge::ConvertDB(const T &dbEntries, std::string &de } return entries; } + +void ObserverBridge::OnServiceDeath() +{ + if (remote_ == nullptr) { + return; + } + remote_ = nullptr; +} } // namespace OHOS::DistributedKv diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp index 30825703710cd4e7ae41d35ab61753ded7e737a5..ce279b409c1722f6413870ea31d5f30c65c6339c 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp @@ -70,21 +70,23 @@ SecurityManager::DBPassword SecurityManager::GetDBPassword(const std::string &na { DBPassword dbPassword; auto secKey = LoadKeyFromFile(name, path, dbPassword.isKeyOutdated); + std::vector key{}; + if (secKey.empty() && needCreate) { - secKey = Random(KEY_SIZE); - if (!SaveKeyToFile(name, path, secKey)) { + key = Random(KEY_SIZE); + if (!SaveKeyToFile(name, path, key)) { secKey.assign(secKey.size(), 0); + key.assign(key.size(), 0); return dbPassword; } } - std::vector secretKey{}; - if (Decrypt(secKey, secretKey)) { - dbPassword.SetValue(secKey.data(), secKey.size()); + if ((!secKey.empty() && Decrypt(secKey, key)) || !key.empty()) { + dbPassword.SetValue(key.data(), key.size()); } secKey.assign(secKey.size(), 0); - secretKey.assign(secKey.size(), 0); + key.assign(key.size(), 0); return dbPassword; } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index e79f8a3835750293ec5232350842715858a69ee2..09fd328233c9078e1ad133429656317a9a679aef 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -23,6 +23,7 @@ #include "log_print.h" #include "store_result_set.h" #include "store_util.h" +#include "task_executor.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedDataDfx; using namespace std::chrono; @@ -56,6 +57,9 @@ SingleStoreImpl::~SingleStoreImpl() if (interval_ > 0) { DevManager::GetInstance().Unregister(this); } + if (taskId_ > 0) { + TaskExecutor::GetInstance().RemoveTask(taskId_); + } } StoreId SingleStoreImpl::GetStoreId() const @@ -814,4 +818,43 @@ void SingleStoreImpl::Online(const std::string &device) void SingleStoreImpl::Offline(const std::string &device) { } + +void SingleStoreImpl::OnRemoteDied() +{ + std::shared_lock lock(rwMutex_); + if (taskId_ > 0) { + return; + } + observers_.ForEach([](const auto &, std::pair> &pair) { + if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { + pair.second->OnServiceDeath(); + } + return false; + }); + taskId_ = TaskExecutor::GetInstance().Execute([this]() { + Register(); + }, INTERVAL); +} + +void SingleStoreImpl::Register() +{ + std::shared_lock lock(rwMutex_); + Status status = SUCCESS; + observers_.ForEach([&status](const auto &, std::pair> &pair) { + if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { + status = pair.second->RegisterRemoteObserver(); + if (status != SUCCESS) { + return true; + } + } + return false; + }); + if (status != SUCCESS) { + taskId_ = TaskExecutor::GetInstance().Execute([this]() { + Register(); + }, INTERVAL); + } else { + taskId_ = 0; + } +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index 2e64222cc0b4d5af1d66a951d6e61ac028be6a1e..2cc33ef617e01c538f0bad3977a3d8a39aa954cf 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -17,6 +17,7 @@ #include "backup_manager.h" #include "device_convertor.h" +#include "kvstore_service_death_notifier.h" #include "log_print.h" #include "security_manager.h" #include "single_store_impl.h" @@ -105,6 +106,7 @@ std::shared_ptr StoreFactory::GetOrOpenStore(const AppId &appId, } isCreate = true; stores[storeId] = kvStore; + KvStoreServiceDeathNotifier::AddServiceDeathWatcher(kvStore); return !stores.empty(); }); return kvStore; @@ -132,6 +134,7 @@ Status StoreFactory::Close(const AppId &appId, const StoreId &storeId, bool isFo status = SUCCESS; auto ref = it->second->Close(isForce); if (ref <= 0) { + KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(it->second); it = values.erase(it); } else { ++it; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp index daec059e57cf20c0947edfb3322d7eae370d9487..fecdeac714a90c744a15dc05e1937c256f1f2d2b 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp @@ -21,14 +21,21 @@ TaskExecutor &TaskExecutor::GetInstance() return instance; } -bool TaskExecutor::Execute(TaskScheduler::Task &&task, int32_t interval) +TaskScheduler::TaskId TaskExecutor::Execute(TaskScheduler::Task &&task, int32_t interval) { if (pool_ == nullptr) { - return false; + return TaskScheduler::INVALID_TASK_ID; } auto time = TaskScheduler::Clock::now() + std::chrono::milliseconds(interval); - pool_->At(time, std::move(task)); - return true; + return pool_->At(time, std::move(task)); +} + +void TaskExecutor::RemoveTask(TaskScheduler::TaskId taskId) +{ + if (pool_ == nullptr) { + return; + } + pool_->Remove(taskId, true); } TaskExecutor::TaskExecutor() diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index d71333e178953b481d2db53a402ebf9dbabaf799..b2a40d8fe68cc5d091f446ffaea64402515b4097 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -29,13 +29,7 @@ namespace OHOS::Test { std::vector Random(int32_t len) { -// std::random_device randomDevice; -// std::uniform_int_distribution distribution(0, std::numeric_limits::max()); - std::vector key(len, 'a'); -// for (int32_t i = 0; i < len; i++) { -// key[i] = static_cast(distribution(randomDevice)); -// } - return key; + return std::vector(len, 'a'); } class SingleStoreImplTest : public testing::Test { @@ -76,7 +70,6 @@ public: void SingleStoreImplTest::SetUpTestCase(void) { std::string baseDir = "/data/service/el1/public/database/SingleStoreImplTest"; - StoreManager::GetInstance().Delete({ "SingleStoreImplTest" }, { "SingleKVStore" }, baseDir); mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); } @@ -921,7 +914,7 @@ HWTEST_F(SingleStoreImplTest, MaxLogSizeTest002, TestSize.Level0) auto status = kvStore_->GetResultSet({ "" }, output); ASSERT_EQ(status, SUCCESS); ASSERT_NE(output, nullptr); - ASSERT_GT(output->GetCount(), 0); + ASSERT_EQ(output->GetCount(), 3); EXPECT_EQ(output->MoveToFirst(), true); /** * @tc.steps:step3. Put more data into the database. diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/store_factory_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/store_factory_test.cpp index 8c96694ec5785c30f8d7c258dc0e0d4be52d65a1..7a14167bd700a81a0a790857ff15e5ef2f10a29a 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/store_factory_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/store_factory_test.cpp @@ -66,9 +66,13 @@ public: static void DeleteKVStore(); }; -void StoreFactoryTest::SetUpTestCase(void){} +void StoreFactoryTest::SetUpTestCase(void) +{ +} -void StoreFactoryTest::TearDownTestCase(void){} +void StoreFactoryTest::TearDownTestCase(void) +{ +} void StoreFactoryTest::SetUp(void) { diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp index d41f0cc400112cd9f679ac4247aa9795dcbfc9dd..a69f8c7a4cf6e54796ad1af4b866a64e55a8b943 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp @@ -286,6 +286,8 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); ctxt->resultSet->SetNative(kvResultSet); + bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); + ctxt->resultSet->SetSchema(isSchema); }; auto output = [env, ctxt](napi_value& result) { ctxt->status = napi_get_reference_value(env, ctxt->ref, &result); diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp index 504b3eb7ad9b58be0ba83b777859cad79688b23c..bf01fe487c7fbe5d5bc405a8e505ee7861e4b8fb 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp @@ -236,6 +236,8 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); ctxt->resultSet->SetNative(kvResultSet); + bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); + ctxt->resultSet->SetSchema(isSchema); }; auto output = [env, ctxt](napi_value& result) { ctxt->status = napi_get_reference_value(env, ctxt->ref, &result); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp index 829be592596ad1ac0b18c3e6711140ce3e3a0387..c3ea9f58220922e7cf9be0737b08fc8e41d4e1e0 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp @@ -54,6 +54,8 @@ napi_value JsDeviceKVStore::Constructor(napi_env env) DECLARE_NAPI_FUNCTION("rollback", JsSingleKVStore::Rollback), DECLARE_NAPI_FUNCTION("enableSync", JsSingleKVStore::EnableSync), DECLARE_NAPI_FUNCTION("setSyncRange", JsSingleKVStore::SetSyncRange), + DECLARE_NAPI_FUNCTION("backup", JsSingleKVStore::Backup), + DECLARE_NAPI_FUNCTION("restore", JsSingleKVStore::Restore), /* JsDeviceKVStore externs JsSingleKVStore */ DECLARE_NAPI_FUNCTION("get", JsDeviceKVStore::Get), DECLARE_NAPI_FUNCTION("getEntries", JsDeviceKVStore::GetEntries), @@ -252,6 +254,8 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); + ctxt->resultSet->SetSchema(isSchema); }; auto output = [env, ctxt](napi_value& result) { ctxt->status = napi_get_reference_value(env, ctxt->ref, &result); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp index 7904735dc4f8cd0a5f3d38f4811d8925096c2377..2e3f5031b854fbd645e17d2a833b9f0459e5ab3a 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp @@ -30,8 +30,9 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { Status::STORE_META_CHANGED, 15100002, "Open existed database with changed options." }, { Status::PERMISSION_DENIED, 202, "Permission denied" }, { Status::CRYPT_ERROR, 15100003, "Database corrupted." }, - { Status::OVER_MAX_LIMITS, 15100001, "Over max subscribe limits." }, + { Status::OVER_MAX_LIMITS, 15100001, "Over max limits." }, { Status::ALREADY_CLOSED, 15100005, "Database or result set already closed." }, + { Status::WAL_OVER_LIMITS, 14800047, "the WAL file size exceeds the default limit."} }; const std::optional GetJsErrorCode(int32_t errorCode) diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp index 138bab26b842ab694ebb8eb0a55b672e41de5d3c..8320919f5e1c02d38892882e4e8550b81e65dadf 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp @@ -1008,6 +1008,8 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); + ctxt->resultSet->SetSchema(isSchema); }; auto output = [env, ctxt](napi_value& result) { ctxt->status = napi_get_reference_value(env, ctxt->ref, &result); diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h index e553ddcb55c000d060e6846c50e02bacbbe1995c..6b836a6fccc7b92afc9385a7033405a53740fe0e 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h @@ -157,8 +157,8 @@ enum DistributedTableMode : int { struct CaseInsensitiveComparator { bool operator() (const std::string& first, const std::string& second) const { - std::string str1(first.length(),' '); - std::string str2(second.length(),' '); + std::string str1(first.length(), ' '); + std::string str2(second.length(), ' '); std::transform(first.begin(), first.end(), str1.begin(), tolower); std::transform(second.begin(), second.end(), str2.begin(), tolower); return str1 < str2; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/data_value.cpp b/kv_store/frameworks/libs/distributeddb/common/src/data_value.cpp index 99fc897dcbb66b061a7e7a2a8aa2fbf05c10fc65..6ac0ad91f034b09053fa79cf391633908caf4cd1 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/data_value.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/data_value.cpp @@ -175,7 +175,7 @@ DataValue &DataValue::operator=(const Blob &blob) int DataValue::Set(Blob *&blob) { ResetValue(); - if (blob == nullptr || blob->GetSize() <= 0) { + if (blob == nullptr || blob->GetSize() < 0) { LOGE("Transfer Blob to DataValue failed."); return -E_INVALID_ARGS; } @@ -257,7 +257,7 @@ int DataValue::GetBlob(Blob *&outVal) const int DataValue::SetBlob(const Blob &val) { ResetValue(); - if (val.GetSize() <= 0) { + if (val.GetSize() < 0) { return E_OK; } value_.blobPtr = new(std::nothrow) Blob(); diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp index 3cb9f9aab447e1014d37bdebba8e481af0ac4e28..4f8427e1aecfd8f3558c77c43ebec03c2fa12261 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -405,6 +405,17 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, break; } } + if (errCode == -E_WAIT_RETRY) { + const int RETRY_INTERVAL = 1000; + TimerId timerId = 0u; + const std::string target = inTask.dstTarget; + RefObject::IncObjRef(this); + errCode = RuntimeContext::GetInstance()->SetTimer(RETRY_INTERVAL, [this, target](TimerId id) { + OnSendable(target); + RefObject::DecObjRef(this); + return -E_END_TIMER; + }, nullptr, timerId); + } if (taskNeedFinalize) { TaskFinalizer(inTask, errCode); } diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp index 921a3732fab62fb3521053ccc1a4c16545239038..849bae8450ab65b1378b30ed26417c41ecd3c63f 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp @@ -214,6 +214,10 @@ int NetworkAdapter::SendBytes(const std::string &dstTarget, const uint8_t *bytes DeviceInfos dstDevInfo; dstDevInfo.identifier = dstTarget; DBStatus errCode = processCommunicator_->SendData(dstDevInfo, bytes, length); + if (errCode == DBStatus::RATE_LIMIT) { + LOGD("[NAdapt][SendBytes] rate limit!"); + return -E_WAIT_RETRY; + } if (errCode != DBStatus::OK) { LOGE("[NAdapt][SendBytes] SendData Fail, errCode=%d.", static_cast(errCode)); // These code is compensation for the probable defect of IProcessCommunicator implementation. diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.cpp index 5268d29109c9b47f1a1e378230089daa48c45c3c..80033be2825a5e4d62444b2ff896c1d6393c5fda 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.cpp @@ -24,6 +24,7 @@ #include "macro_utils.h" #include "securec.h" #include "version.h" +#include namespace DistributedDB { namespace { @@ -60,6 +61,7 @@ FrameType GetFrameType(uint8_t inPacketType) } std::map ProtocolProto::msgIdMapFunc_; +std::shared_mutex ProtocolProto::msgIdMutex_; uint32_t ProtocolProto::GetAppLayerFrameHeaderLength() { @@ -366,6 +368,7 @@ int ProtocolProto::CombinePacketIntoFrame(SerialBuffer *inFrame, const uint8_t * int ProtocolProto::RegTransformFunction(uint32_t msgId, const TransformFunc &inFunc) { + std::unique_lock autoLock(msgIdMutex_); if (msgIdMapFunc_.count(msgId) != 0) { return -E_ALREADY_REGISTER; } @@ -378,6 +381,7 @@ int ProtocolProto::RegTransformFunction(uint32_t msgId, const TransformFunc &inF void ProtocolProto::UnRegTransformFunction(uint32_t msgId) { + std::unique_lock autoLock(msgIdMutex_); if (msgIdMapFunc_.count(msgId) != 0) { msgIdMapFunc_.erase(msgId); } @@ -582,12 +586,12 @@ int ProtocolProto::CalculateXorSum(const uint8_t *bytes, uint32_t length, uint64 int ProtocolProto::CalculateDataSerializeLength(const Message *inMsg, uint32_t &outLength) { uint32_t messageId = inMsg->GetMessageId(); - if (msgIdMapFunc_.count(messageId) == 0) { + TransformFunc function; + if (GetTransformFunc(messageId, function) != E_OK) { LOGE("[Proto][CalcuDataSerialLen] Not registered for messageId=%" PRIu32 ".", messageId); return -E_NOT_REGISTER; } - TransformFunc function = msgIdMapFunc_[messageId]; uint32_t serializeLen = function.computeFunc(inMsg); uint32_t alignedLen = BYTE_8_ALIGN(serializeLen); // Currently not allowed the upper module to send a message without data. Regard serializeLen zero as abnormal. @@ -625,8 +629,11 @@ int ProtocolProto::SerializeMessage(SerialBuffer *inBuff, const Message *inMsg) return E_OK; } // If dataLen not zero, the TransformFunc of this messageId must exist, the caller's logic guarantee it - uint32_t messageId = inMsg->GetMessageId(); - TransformFunc function = msgIdMapFunc_[messageId]; + TransformFunc function; + if (GetTransformFunc(inMsg->GetMessageId(), function) != E_OK) { + LOGE("[Proto][Serialize] Not register, messageId=%" PRIu32 ".", inMsg->GetMessageId()); + return -E_NOT_REGISTER; + } int result = function.serializeFunc(payloadByteLen.first + sizeof(MessageHeader), dataLen, inMsg); if (result != E_OK) { LOGE("[Proto][Serialize] SerializeFunc Fail, result=%d.", result); @@ -674,12 +681,11 @@ int ProtocolProto::DeSerializeMessage(const SerialBuffer *inBuff, Message *inMsg if (onlyMsgHeader || dataLen == 0) { // Do not need to deserialize data return E_OK; } - uint32_t messageId = inMsg->GetMessageId(); - if (msgIdMapFunc_.count(messageId) == 0) { - LOGE("[Proto][DeSerialize] Not register, messageId=%" PRIu32 ".", messageId); + TransformFunc function; + if (GetTransformFunc(inMsg->GetMessageId(), function) != E_OK) { + LOGE("[Proto][DeSerialize] Not register, messageId=%" PRIu32 ".", inMsg->GetMessageId()); return -E_NOT_REGISTER; } - TransformFunc function = msgIdMapFunc_[messageId]; int result = function.deserializeFunc(payloadByteLen.first + sizeof(MessageHeader), dataLen, inMsg); if (result != E_OK) { LOGE("[Proto][DeSerialize] DeserializeFunc Fail, result=%d.", result); @@ -1092,4 +1098,15 @@ int ProtocolProto::FillExtendHeadDataIfNeed(std::shared_ptr } return E_OK; } + +int ProtocolProto::GetTransformFunc(uint32_t messageId, DistributedDB::TransformFunc &function) +{ + std::shared_lock autoLock(msgIdMutex_); + const auto &entry = msgIdMapFunc_.find(messageId); + if (entry == msgIdMapFunc_.end()) { + return -E_NOT_REGISTER; + } + function = entry->second; + return E_OK; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.h b/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.h index c5f7e0918c1703daf5207438a40dfce3934e231f..f151f0a609d7c265eccc20571dfcad7cc9891bb9 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/protocol_proto.h @@ -18,6 +18,7 @@ #include #include +#include #include "communicator_type_define.h" #include "frame_header.h" #include "iprocess_communicator.h" @@ -130,6 +131,9 @@ private: static int FillExtendHeadDataIfNeed(std::shared_ptr &extendHandle, SerialBuffer *buffer, uint32_t headSize); + static int GetTransformFunc(uint32_t messageId, TransformFunc &function); + + static std::shared_mutex msgIdMutex_; static std::map msgIdMapFunc_; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h index 1fc0b12eddcd3f3c8245e74b18285b65a34751b0..6a73e36c06a5d2e45c741dabe3810c7b21810792 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -65,6 +65,7 @@ enum DBStatus { NONEXISTENT, // for row record, pass invalid column name or invalid column index. TYPE_MISMATCH, // for row record, get value with mismatch func. REMOTE_OVER_SIZE, // for remote query, the data is too many, only get part or data. + RATE_LIMIT, }; struct KvStoreConfig { diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/kvdb_manager.h b/kv_store/frameworks/libs/distributeddb/storage/include/kvdb_manager.h index 7ea47927c4ccc71cfc7310adb8e98cd5ddc08728..88f028cda8699b0fc63edc3be2fcc73d3741ed0c 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/kvdb_manager.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/kvdb_manager.h @@ -128,9 +128,13 @@ private: static int TryLockDB(const KvDBProperties &kvDBProp, int retryTimes); static int UnlockDB(const KvDBProperties &kvDBProp); + static bool CheckOpenDBOptionWithCached(const KvDBProperties &properties, IKvDB *kvdb); + static std::atomic instance_; static std::mutex kvDBLock_; static std::mutex instanceLock_; + + static std::mutex fileHandleMutex_; static std::map locks_; std::map localKvDBs_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp index 162457d3804b573072792b9c81dbe09c7412a876..d354c5baa6b04e0038212308bb53aec3ea3bdb1d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp @@ -29,6 +29,7 @@ std::atomic KvDBManager::instance_{nullptr}; std::mutex KvDBManager::kvDBLock_; std::mutex KvDBManager::instanceLock_; std::map KvDBManager::locks_; +std::mutex KvDBManager::fileHandleMutex_; namespace { DefaultFactory g_defaultFactory; @@ -120,7 +121,7 @@ int KvDBManager::ExecuteRemoveDatabase(const KvDBProperties &properties) } errCode = -E_NOT_FOUND; - for (const KvDBType kvDbType : g_dbTypeArr) { + for (KvDBType kvDbType : g_dbTypeArr) { int innerErrCode = E_OK; IKvDB *kvdb = factory->CreateKvDb(kvDbType, innerErrCode); if (innerErrCode != E_OK) { @@ -206,9 +207,12 @@ int KvDBManager::TryLockDB(const KvDBProperties &kvDBProp, int retryTimes) return E_OK; } - if (locks_.count(id) != 0) { - LOGI("db has been locked!"); - return E_OK; + { + std::lock_guard autoLock(fileHandleMutex_); + if (locks_.count(id) != 0) { + LOGI("db has been locked!"); + return E_OK; + } } std::string hexHashId = DBCommon::TransferStringToHex((id)); @@ -223,6 +227,7 @@ int KvDBManager::TryLockDB(const KvDBProperties &kvDBProp, int retryTimes) errCode = OS::FileLock(handle, false); // not block process if (errCode == E_OK) { LOGI("[%s]locked!", STR_MASK(DBCommon::TransferStringToHex(KvDBManager::GenerateKvDBIdentifier(kvDBProp)))); + std::lock_guard autoLock(fileHandleMutex_); locks_[id] = handle; return errCode; } else if (errCode == -E_BUSY) { @@ -246,23 +251,57 @@ int KvDBManager::UnlockDB(const KvDBProperties &kvDBProp) return E_OK; } std::string identifierDir = KvDBManager::GenerateKvDBIdentifier(kvDBProp); - if (locks_.count(identifierDir) == 0) { - return E_OK; + OS::FileHandle *handle = nullptr; + { + std::lock_guard autoLock(fileHandleMutex_); + if (locks_.count(identifierDir) == 0) { + return E_OK; + } + handle = locks_[identifierDir]; } - int errCode = OS::FileUnlock(locks_[identifierDir]); + int errCode = OS::FileUnlock(handle); if (errCode != E_OK) { LOGE("DB unlocked! errCode = [%d]", errCode); return errCode; } - errCode = OS::CloseFile(locks_[identifierDir]); + errCode = OS::CloseFile(handle); if (errCode != E_OK) { LOGE("DB closed! errCode = [%d]", errCode); return errCode; } + std::lock_guard autoLock(fileHandleMutex_); locks_.erase(identifierDir); return E_OK; } +bool KvDBManager::CheckOpenDBOptionWithCached(const KvDBProperties &properties, IKvDB *kvDB) +{ + bool isMemoryDb = properties.GetBoolProp(KvDBProperties::MEMORY_MODE, false); + std::string canonicalDir = properties.GetStringProp(KvDBProperties::DATA_DIR, ""); + if (!isMemoryDb && (canonicalDir.empty() || canonicalDir != kvDB->GetStorePath())) { + LOGE("Failed to check store path, the input path does not match with cached store."); + return false; + } + + bool compressOnSyncUser = properties.GetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, false); + bool compressOnSyncGet = kvDB->GetMyProperties().GetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, false); + if (compressOnSyncUser != compressOnSyncGet) { + LOGE("Failed to check compress option, the input %d not match with cached %d.", compressOnSyncUser, + compressOnSyncGet); + return false; + } + if (compressOnSyncUser) { + int compressRateUser = properties.GetIntProp(KvDBProperties::COMPRESSION_RATE, 0); + int compressRateGet = kvDB->GetMyProperties().GetIntProp(KvDBProperties::COMPRESSION_RATE, 0); + if (compressRateUser != compressRateGet) { + LOGE("Failed to check compress rate, the input %d not match with cached %d.", compressRateUser, + compressRateGet); + return false; + } + } + return true; +} + // Used to open a kvdb with the given property IKvDBConnection *KvDBManager::GetDatabaseConnection(const KvDBProperties &properties, int &errCode, bool isNeedIfOpened) @@ -283,10 +322,8 @@ IKvDBConnection *KvDBManager::GetDatabaseConnection(const KvDBProperties &proper LOGE("Failed to open the db:%d", errCode); } } else { - bool isMemoryDb = properties.GetBoolProp(KvDBProperties::MEMORY_MODE, false); - std::string canonicalDir = properties.GetStringProp(KvDBProperties::DATA_DIR, ""); - if (!isMemoryDb && (canonicalDir.empty() || canonicalDir != kvDB->GetStorePath())) { - LOGE("Failed to check store path, the input path does not match with cached store."); + if (!CheckOpenDBOptionWithCached(properties, kvDB)) { + LOGE("Failed to check open db option"); errCode = -E_INVALID_ARGS; } else { connection = kvDB->GetDBConnection(errCode); @@ -447,7 +484,7 @@ int KvDBManager::CalculateKvStoreSize(const KvDBProperties &properties, uint64_t } uint64_t totalSize = 0; - for (const KvDBType kvDbType : g_dbTypeArr) { + for (KvDBType kvDbType : g_dbTypeArr) { int innerErrCode = E_OK; IKvDB *kvDB = factory->CreateKvDb(kvDbType, innerErrCode); if (innerErrCode != E_OK) { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 7b6be36816a16d80695449dce5b9e72571abe361..0e8877f24539730d44182b2f0ae10245baa8f8b7 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -827,7 +827,7 @@ int RelationalSyncAbleStorage::GetRemoteDeviceSchema(const std::string &deviceId LOGE("Get remote device schema from meta failed. err=%d", errCode); return errCode; } - std::string remoteSchema(remoteSchemaBuff.begin(), remoteSchemaBuff.end()); + remoteSchema = std::string(remoteSchemaBuff.begin(), remoteSchemaBuff.end()); errCode = remoteDeviceSchema_.Put(deviceId, remoteSchema); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp index aeebb9fe3a3bd65e3fa4438d19adeff4e8f03db2..eedb063cd3a08bcc5667af2e6fe911dedc5dea84 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp @@ -88,7 +88,7 @@ void RelationalSyncDataInserter::SetLocalTable(TableInfo localTable) localTable_ = std::move(localTable); } -const TableInfo &RelationalSyncDataInserter::GetLocalTable() +const TableInfo &RelationalSyncDataInserter::GetLocalTable() const { return localTable_; } @@ -208,7 +208,6 @@ int RelationalSyncDataInserter::GetDeleteSyncDataStmt(sqlite3 *db, sqlite3_stmt int RelationalSyncDataInserter::GetSaveLogStatement(sqlite3 *db, sqlite3_stmt *&logStmt, sqlite3_stmt *&queryStmt) { - std::string devName = DBCommon::TransferHashString(deviceId_); const std::string tableName = DBConstant::RELATIONAL_PREFIX + query_.GetTableName() + "_log"; std::string dataFormat = "?, '" + deviceId_ + "', ?, ?, ?, ?, ?"; std::string columnList = "data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key"; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h index 0a9bb827492c030c7bcf694c91574e7222575600..a81d141081448ab26f8e4632c826120536ce0068 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.h @@ -49,11 +49,11 @@ public: void SetDeviceId(std::string deviceId); // Set remote fields in cid order - void SetRemoteFields(std::vector fields); + void SetRemoteFields(std::vector remoteFields); void SetEntries(std::vector entries); void SetLocalTable(TableInfo localTable); - const TableInfo &GetLocalTable(); + const TableInfo &GetLocalTable() const; void SetQuery(QueryObject query); void SetInsertTableName(std::string tableName); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 59e7c7908e682d653faa662c9f4f8d52a59cb04f..288d5443677c366de9a702d17f1e4315be0b6e00 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -441,9 +441,9 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std } TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap - if (!tableName.empty() && tables.find(tableName) == tables.end()) { - LOGW("Remove device data with table name which is not a distributed table or not exist."); - return E_OK; + if (tables.empty() || (!tableName.empty() && tables.find(tableName) == tables.end())) { + LOGE("Remove device data with table name which is not a distributed table or no distributed table found."); + return -E_DISTRIBUTED_SCHEMA_NOT_FOUND; } int errCode = E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp index ae76af04c3de7c189986ab982e956476fb680931..9ad4757add427bb603e8cbe80212a6657a51be57 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp @@ -829,8 +829,19 @@ int SqliteQueryHelper::GetSubscribeCondition(const std::string &accessStr, std:: conditionStr += " (1 = 1) "; return E_OK; } - // json_extract_by_path function will return error when value is empty, check it before - conditionStr += "((length(" + accessStr + "value) != 0 AND " + accessStr + "value IS NOT NULL) AND "; + + bool hasQueryByValue = std::any_of(queryObjNodes_.begin(), queryObjNodes_.end(), [](const QueryObjNode &it) { + return GetSymbolType(it.operFlag) == SymbolType::COMPARE_SYMBOL || + GetSymbolType(it.operFlag) == SymbolType::RELATIONAL_SYMBOL || + GetSymbolType(it.operFlag) == SymbolType::RANGE_SYMBOL; + }); + if (hasQueryByValue) { + // json_extract_by_path function will return error when value is empty, check it before when query by value + conditionStr += "((length(" + accessStr + "value) != 0 AND " + accessStr + "value IS NOT NULL) AND "; + } else { + conditionStr += "("; + } + if (hasPrefixKey_) { conditionStr += "(hex(" + accessStr + "key) LIKE '" + DBCommon::VectorToHexString(prefixKey_) + "%')"; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 02c5c7a6f1892811624dbaf4a9ce7825b8b62bd2..c69e6a40efff37ef38efaa9cd0b89bdf24651271 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -683,33 +683,33 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statemen } int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncDataItem(const DataItem &dataItem, - RelationalSyncDataInserter &inserter, sqlite3_stmt *&stmt) + RelationalSyncDataInserter &inserter, sqlite3_stmt *&rmDataStmt) { - if (stmt == nullptr) { - int errCode = inserter.GetDeleteSyncDataStmt(dbHandle_, stmt); + if (rmDataStmt == nullptr) { + int errCode = inserter.GetDeleteSyncDataStmt(dbHandle_, rmDataStmt); if (errCode != E_OK) { LOGE("[DeleteSyncDataItem] Get statement fail!, errCode:%d", errCode); return errCode; } } - int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hash_key index + int errCode = SQLiteUtils::BindBlobToStatement(rmDataStmt, 1, dataItem.hashKey); // 1 means hash_key index if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(rmDataStmt, true, errCode); return errCode; } if (mode_ != DistributedTableMode::COLLABORATION) { - errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index + errCode = SQLiteUtils::BindTextToStatement(rmDataStmt, 2, dataItem.dev); // 2 means device index if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(rmDataStmt, true, errCode); return errCode; } } - errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_); + errCode = SQLiteUtils::StepWithRetry(rmDataStmt, isMemDb_); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; } - SQLiteUtils::ResetStatement(stmt, false, errCode); // Finalize outside. + SQLiteUtils::ResetStatement(rmDataStmt, false, errCode); // Finalize outside. return errCode; } @@ -745,33 +745,33 @@ int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(const DataItem &d } int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncLog(const DataItem &dataItem, - RelationalSyncDataInserter &inserter, sqlite3_stmt *&stmt) + RelationalSyncDataInserter &inserter, sqlite3_stmt *&rmLogStmt) { - if (stmt == nullptr) { - int errCode = inserter.GetDeleteLogStmt(dbHandle_, stmt); + if (rmLogStmt == nullptr) { + int errCode = inserter.GetDeleteLogStmt(dbHandle_, rmLogStmt); if (errCode != E_OK) { LOGE("[DeleteSyncLog] Get statement fail!"); return errCode; } } - int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hashkey index + int errCode = SQLiteUtils::BindBlobToStatement(rmLogStmt, 1, dataItem.hashKey); // 1 means hashkey index if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(rmLogStmt, true, errCode); return errCode; } if (mode_ != DistributedTableMode::COLLABORATION) { - errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index + errCode = SQLiteUtils::BindTextToStatement(rmLogStmt, 2, dataItem.dev); // 2 means device index if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(rmLogStmt, true, errCode); return errCode; } } - errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_); + errCode = SQLiteUtils::StepWithRetry(rmLogStmt, isMemDb_); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; } - SQLiteUtils::ResetStatement(stmt, false, errCode); // Finalize outside. + SQLiteUtils::ResetStatement(rmLogStmt, false, errCode); // Finalize outside. return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp index 687b40b4aad9b3a652e0550b0db53df18b5c0403..7d222b79ce142d12bfad08ad675f181bbe1201de 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp @@ -248,12 +248,6 @@ int SQLiteUtils::BindTextToStatement(sqlite3_stmt *statement, int index, const s return -E_INVALID_ARGS; } - // Check empty value. - if (str.empty()) { - sqlite3_bind_null(statement, index); - return E_OK; - } - int errCode = sqlite3_bind_text(statement, index, str.c_str(), str.length(), SQLITE_TRANSIENT); if (errCode != SQLITE_OK) { LOGE("[SQLiteUtil][Bind text]Failed to bind the value:%d", errCode); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp index 8a8e8cda3efc6d58c2733f94367c8c96f6dadf15..84e6cb817f7b10f7abb404f1bae1dbe6cbecd549 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp @@ -42,61 +42,67 @@ StorageEngine::~StorageEngine() CloseExecutor(); } -int StorageEngine::Init() +int StorageEngine::InitReadWriteExecutors() { - if (isInitialized_.load()) { - LOGD("Storage engine has been initialized!"); - return E_OK; - } - int errCode = E_OK; - { - std::scoped_lock initLock(writeMutex_, readMutex_); - // only for create the database avoid the minimum number is 0. - StorageExecutor *handle = nullptr; - if (engineAttr_.minReadNum == 0 && engineAttr_.minWriteNum == 0) { - errCode = CreateNewExecutor(true, handle); - if (errCode != E_OK) { - goto END; - } - - if (handle != nullptr) { - delete handle; - handle = nullptr; - } + std::scoped_lock initLock(writeMutex_, readMutex_); + // only for create the database avoid the minimum number is 0. + StorageExecutor *handle = nullptr; + if (engineAttr_.minReadNum == 0 && engineAttr_.minWriteNum == 0) { + errCode = CreateNewExecutor(true, handle); + if (errCode != E_OK) { + return errCode; } - for (uint32_t i = 0; i < engineAttr_.minWriteNum; i++) { + if (handle != nullptr) { + delete handle; handle = nullptr; - errCode = CreateNewExecutor(true, handle); - if (errCode != E_OK) { - goto END; - } - AddStorageExecutor(handle); } + } - for (uint32_t i = 0; i < engineAttr_.minReadNum; i++) { - handle = nullptr; - errCode = CreateNewExecutor(false, handle); - if (errCode != E_OK) { - goto END; - } - AddStorageExecutor(handle); + for (uint32_t i = 0; i < engineAttr_.minWriteNum; i++) { + handle = nullptr; + errCode = CreateNewExecutor(true, handle); + if (errCode != E_OK) { + return errCode; } + AddStorageExecutor(handle); } -END: + for (uint32_t i = 0; i < engineAttr_.minReadNum; i++) { + handle = nullptr; + errCode = CreateNewExecutor(false, handle); + if (errCode != E_OK) { + return errCode; + } + AddStorageExecutor(handle); + } + return E_OK; +} + + +int StorageEngine::Init() +{ + if (isInitialized_.load()) { + LOGD("Storage engine has been initialized!"); + return E_OK; + } + + int errCode = InitReadWriteExecutors(); if (errCode == E_OK) { isInitialized_.store(true); + initCondition_.notify_all(); return E_OK; } else if (errCode == -E_EKEYREVOKED) { // Assumed file system has classification function, can only get one write handle std::unique_lock lock(writeMutex_); if (!writeIdleList_.empty() || !writeUsingList_.empty()) { isInitialized_.store(true); + initCondition_.notify_all(); return E_OK; } } + initCondition_.notify_all(); Release(); return errCode; } @@ -109,10 +115,16 @@ StorageExecutor *StorageEngine::FindExecutor(bool writable, OperatePerm perm, in return nullptr; } - if (!isInitialized_.load()) { - LOGE("Storage engine is not initialized"); - errCode = -E_BUSY; // Usually in reinitialize engine, return BUSY - return nullptr; + { + std::unique_lock lock(initMutex_); + bool result = initCondition_.wait_for(lock, std::chrono::seconds(waitTime), [this]() { + return isInitialized_.load(); + }); + if (!result || !isInitialized_.load()) { + LOGE("Storage engine is not initialized"); + errCode = -E_BUSY; // Usually in reinitialize engine, return BUSY + return nullptr; + } } if (writable) { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h index 1a9dd227a735d5b6168b8fd11b5fd694dec31c15..cb9a7d21a8cbdcfbebfdb8aa52b11f4a8c74d331 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h @@ -89,6 +89,8 @@ protected: static bool CheckEngineAttr(const StorageEngineAttr &poolSize); + int InitReadWriteExecutors(); + StorageEngineAttr engineAttr_; bool isUpdated_; std::atomic isMigrating_; @@ -114,6 +116,8 @@ private: static const int MAX_WRITE_SIZE; static const int MAX_READ_SIZE; + std::mutex initMutex_; + std::condition_variable initCondition_; std::atomic isInitialized_; OperatePerm perm_; bool operateAbort_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.cpp index 0c5e86ca0b66ba6fddd98be67027eb8fd6ff144c..811eca0ab4545f05055687c2ded645fb7eb19777 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.cpp @@ -66,7 +66,7 @@ void SyncAbleEngine::Close() void SyncAbleEngine::EnableAutoSync(bool enable) { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.EnableAutoSync(enable); @@ -85,7 +85,7 @@ int SyncAbleEngine::DisableManualSync(void) // Get The current virtual timestamp uint64_t SyncAbleEngine::GetTimestamp() { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.GetTimestamp(); @@ -93,7 +93,7 @@ uint64_t SyncAbleEngine::GetTimestamp() int SyncAbleEngine::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash, const std::string &tableName) { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.EraseDeviceWaterMark(deviceId, isNeedHash, tableName); @@ -176,6 +176,15 @@ void SyncAbleEngine::StopSyncerWithNoLock(bool isClosedOperation) void SyncAbleEngine::UserChangeHandle() { + if (store_ == nullptr) { + LOGD("[SyncAbleEngine] RDB got null sync interface in userChange."); + return; + } + bool isSyncDualTupleMode = store_->GetDbProperties().GetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, false); + if (!isSyncDualTupleMode) { + LOGD("[SyncAbleEngine] no use syncDualTupleMode, abort userChange"); + return; + } std::unique_lock lock(syncerOperateLock_); if (closed_) { LOGI("RDB is already closed"); @@ -270,4 +279,11 @@ int SyncAbleEngine::RemoteQuery(const std::string &device, const RemoteCondition } return syncer_.RemoteQuery(device, condition, timeout, connectionId, result); } + +bool SyncAbleEngine::NeedStartSyncer() const +{ + // don't start when check callback got not active + // equivalent to !(!isSyncNeedActive_ && isSyncModuleActiveCheck_) + return !started_ && (isSyncNeedActive_ || !isSyncModuleActiveCheck_); +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.h index 9afc0ff9c969cef01e135b2fc91aa6a9d06dac09..0747d1fd41dfe709a118626eb005b7cd65815785 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_engine.h @@ -75,6 +75,8 @@ private: void ChangeUserListener(); + bool NeedStartSyncer() const; + SyncerProxy syncer_; // use for sync Interactive std::atomic started_; std::atomic closed_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp index 711621e3ce1071c8752ce9b4e4b4bc398894aeee..1e9507d57dbba1976203398e27b447e2e3ef88b1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp @@ -92,7 +92,7 @@ int SyncAbleKvDB::Sync(const ISyncer::SyncParma &parma, uint64_t connectionId) void SyncAbleKvDB::EnableAutoSync(bool enable) { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.EnableAutoSync(enable); @@ -100,7 +100,7 @@ void SyncAbleKvDB::EnableAutoSync(bool enable) void SyncAbleKvDB::WakeUpSyncer() { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } } @@ -232,6 +232,12 @@ void SyncAbleKvDB::UserChangeHandle() LOGF("KvDB got null sync interface."); return; } + bool isSyncDualTupleMode = syncInterface->GetDbProperties(). + GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false); + if (!isSyncDualTupleMode) { + LOGD("[SyncAbleKvDB] no use syncDualTupleMode, abort userChange"); + return; + } std::unique_lock lock(syncerOperateLock_); if (closed_) { LOGI("kvDB is already closed"); @@ -264,7 +270,7 @@ void SyncAbleKvDB::ChangeUserListener() // Get The current virtual timestamp uint64_t SyncAbleKvDB::GetTimestamp() { - if (!started_ && !isSyncModuleActiveCheck_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.GetTimestamp(); @@ -278,7 +284,7 @@ uint32_t SyncAbleKvDB::GetAppendedLen() const int SyncAbleKvDB::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash) { - if (!started_) { + if (NeedStartSyncer()) { StartSyncer(); } return syncer_.EraseDeviceWaterMark(deviceId, isNeedHash); @@ -378,11 +384,17 @@ void SyncAbleKvDB::NotifyRemotePushFinishedInner(const std::string &targetId) co int SyncAbleKvDB::SetSyncRetry(bool isRetry) { + if (NeedStartSyncer()) { + StartSyncer(); + } return syncer_.SetSyncRetry(isRetry); } int SyncAbleKvDB::SetEqualIdentifier(const std::string &identifier, const std::vector &targets) { + if (NeedStartSyncer()) { + StartSyncer(); + } return syncer_.SetEqualIdentifier(identifier, targets); } @@ -401,4 +413,11 @@ int SyncAbleKvDB::GetSyncDataSize(const std::string &device, size_t &size) const { return syncer_.GetSyncDataSize(device, size); } + +bool SyncAbleKvDB::NeedStartSyncer() const +{ + // don't start when check callback got not active + // equivalent to !(!isSyncNeedActive_ && isSyncModuleActiveCheck_) + return !started_ && (isSyncNeedActive_ || !isSyncModuleActiveCheck_); +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h index 86171bbac587c69ec2fb505d3d1231dad8e20a51..ceb1c08885acab7ecd62c1f2581df6994e18162b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h @@ -119,6 +119,8 @@ protected: private: int RegisterEventType(EventType type); + bool NeedStartSyncer() const; + SyncerProxy syncer_; std::atomic started_; std::atomic closed_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp index 8227f3c29e28f45645da4bfee396cd75ea6bc2d0..76952725f2127fe24c2873ca7be16543662629f5 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp @@ -284,10 +284,26 @@ int GenericSyncer::StopSync(uint64_t connectionId) uint64_t GenericSyncer::GetTimestamp() { - if (timeHelper_ == nullptr) { + std::shared_ptr timeHelper = nullptr; + ISyncInterface *storage = nullptr; + { + std::lock_guard lock(syncerLock_); + timeHelper = timeHelper_; + if (syncInterface_ != nullptr) { + storage = syncInterface_; + storage->IncRefCount(); + } + } + if (storage == nullptr) { + return TimeHelper::GetSysCurrentTime(); + } + if (timeHelper == nullptr) { + storage->DecRefCount(); return TimeHelper::GetSysCurrentTime(); } - return timeHelper_->GetTime(); + uint64_t timestamp = timeHelper->GetTime(); + storage->DecRefCount(); + return timestamp; } void GenericSyncer::QueryAutoSync(const InternalSyncParma ¶m) @@ -446,13 +462,11 @@ bool GenericSyncer::IsValidMode(int mode) const return true; } -int GenericSyncer::SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const +int GenericSyncer::SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, ISyncInterface *storage) const { - (void)query; - (void)mode; - (void)isQuerySync; - (void)(devices); + (void)param; + (void)engine; + (void)storage; return E_OK; } @@ -785,20 +799,34 @@ int GenericSyncer::StatusCheck() const int GenericSyncer::SyncPreCheck(const SyncParma ¶m) const { - std::lock_guard lock(syncerLock_); - int errCode = StatusCheck(); - if (errCode != E_OK) { - return errCode; - } - if (!IsValidDevices(param.devices) || !IsValidMode(param.mode)) { - return -E_INVALID_ARGS; - } - if (IsQueuedManualSyncFull(param.mode, param.wait)) { - LOGE("[Syncer] -E_BUSY"); - return -E_BUSY; + ISyncEngine *engine = nullptr; + ISyncInterface *storage = nullptr; + int errCode = E_OK; + { + std::lock_guard lock(syncerLock_); + errCode = StatusCheck(); + if (errCode != E_OK) { + return errCode; + } + if (!IsValidDevices(param.devices) || !IsValidMode(param.mode)) { + return -E_INVALID_ARGS; + } + if (IsQueuedManualSyncFull(param.mode, param.wait)) { + LOGE("[Syncer] -E_BUSY"); + return -E_BUSY; + } + storage = syncInterface_; + engine = syncEngine_; + if (storage == nullptr || engine == nullptr) { + return -E_BUSY; + } + storage->IncRefCount(); + RefObject::IncObjRef(engine); } - QuerySyncObject syncQuery = param.syncQuery; - return SyncConditionCheck(syncQuery, param.mode, param.isQuerySync, param.devices); + errCode = SyncConditionCheck(param, engine, storage); + storage->DecRefCount(); + RefObject::DecObjRef(engine); + return errCode; } void GenericSyncer::InitSyncOperation(SyncOperation *operation, const SyncParma ¶m) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.h index 7d89adbfa14df566dbd95886b4fbfe81b21c538f..2b7ea6c4cfac79b306b78cccfb3f97b6eb3a00cf 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.h @@ -143,8 +143,7 @@ protected: // Check if the mode arg is valid bool IsValidMode(int mode) const; - virtual int SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const; + virtual int SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, ISyncInterface *storage) const; // Check if the devices arg is valid bool IsValidDevices(const std::vector &devices) const; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/query_sync_water_mark_helper.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/query_sync_water_mark_helper.cpp index 70c37ffa604f6a4a4d341705b9df7f80cf0035ce..e15ba593d1be8c20872b4d5e7d003f9648243cd5 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/query_sync_water_mark_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/query_sync_water_mark_helper.cpp @@ -301,6 +301,8 @@ DeviceID QuerySyncWaterMarkHelper::GetHashQuerySyncDeviceId(const DeviceID &devi int QuerySyncWaterMarkHelper::GetDeleteSyncWaterMark(const std::string &deviceId, DeleteWaterMark &deleteWaterMark) { std::string hashId = GetHashDeleteSyncDeviceId(deviceId); + // lock prevent different thread visit deleteSyncCache_ + std::lock_guard autoLock(deleteSyncLock_); return GetDeleteWaterMarkFromCache(hashId, deleteWaterMark); } @@ -308,9 +310,10 @@ int QuerySyncWaterMarkHelper::SetSendDeleteSyncWaterMark(const DeviceID &deviceI { std::string hashId = GetHashDeleteSyncDeviceId(deviceId); DeleteWaterMark deleteWaterMark; + // lock prevent different thread visit deleteSyncCache_ + std::lock_guard autoLock(deleteSyncLock_); GetDeleteWaterMarkFromCache(hashId, deleteWaterMark); deleteWaterMark.sendWaterMark = waterMark; - std::lock_guard autoLock(deleteSyncLock_); return UpdateDeleteSyncCacheAndSave(hashId, deleteWaterMark); } @@ -318,9 +321,10 @@ int QuerySyncWaterMarkHelper::SetRecvDeleteSyncWaterMark(const DeviceID &deviceI { std::string hashId = GetHashDeleteSyncDeviceId(deviceId); DeleteWaterMark deleteWaterMark; + // lock prevent different thread visit deleteSyncCache_ + std::lock_guard autoLock(deleteSyncLock_); GetDeleteWaterMarkFromCache(hashId, deleteWaterMark); deleteWaterMark.recvWaterMark = waterMark; - std::lock_guard autoLock(deleteSyncLock_); return UpdateDeleteSyncCacheAndSave(hashId, deleteWaterMark); } @@ -340,8 +344,6 @@ int QuerySyncWaterMarkHelper::UpdateDeleteSyncCacheAndSave(const std::string &db int QuerySyncWaterMarkHelper::GetDeleteWaterMarkFromCache(const DeviceID &hashDeviceId, DeleteWaterMark &deleteWaterMark) { - // lock prevent different thread visit deleteSyncCache_ - std::lock_guard autoLock(deleteSyncLock_); // if not found if (deleteSyncCache_.find(hashDeviceId) == deleteSyncCache_.end()) { DeleteWaterMark waterMark; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp index c4c3272a93f8189387e26f396074b57dbc0a9649..f2ee817c191e0362457250e61433dbc37ddea5ff 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp @@ -1691,6 +1691,10 @@ void SingleVerDataSync::FillRequestReSendPacket(const SingleVerSyncTaskContext * std::vector reserved {reSendInfo.packetId}; packet->SetReserved(reserved); } + if (reSendMode == SyncModeType::PULL) { + // resend pull packet dont set compress type + return; + } bool needCompressOnSync = false; uint8_t compressionRate = DBConstant::DEFAULT_COMPTRESS_RATE; (void)storage_->GetCompressionOption(needCompressOnSync, compressionRate); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp index 4f099ff91d5927f588baca1a17632e19380d2361..c5fd92349d0b5c6e25b335216eb1fc31fa17290f 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.cpp @@ -159,29 +159,30 @@ void SingleVerKVSyncer::RemoteDataChanged(const std::string &device) static_cast(syncEngine_)->PutUnfinishedSubQueries(device, syncQueries); } -int SingleVerKVSyncer::SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const +int SingleVerKVSyncer::SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, + ISyncInterface *storage) const { - if (!isQuerySync) { + if (!param.isQuerySync) { return E_OK; } - int errCode = static_cast(syncInterface_)->CheckAndInitQueryCondition(query); + QuerySyncObject query = param.syncQuery; + int errCode = static_cast(storage)->CheckAndInitQueryCondition(query); if (errCode != E_OK) { LOGE("[SingleVerKVSyncer] QuerySyncObject check failed"); return errCode; } - if (mode != SUBSCRIBE_QUERY) { + if (param.mode != SUBSCRIBE_QUERY) { return E_OK; } if (query.HasLimit() || query.HasOrderBy()) { LOGE("[SingleVerKVSyncer] subscribe query not support limit,offset or orderby"); return -E_NOT_SUPPORT; } - if (devices.size() > MAX_DEVICES_NUM) { + if (param.devices.size() > MAX_DEVICES_NUM) { LOGE("[SingleVerKVSyncer] devices is overlimit"); return -E_MAX_LIMITS; } - return syncEngine_->SubscribeLimitCheck(devices, query); + return engine->SubscribeLimitCheck(param.devices, query); } void SingleVerKVSyncer::TriggerSubscribe(const std::string &device, const QuerySyncObject &query) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.h index 60bf8f58941d1f2ac8d46ad5ca1e3eeca326dfad..6ca4a03fc35aad93d4bd27843fe169ce60d1fbe8 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_kv_syncer.h @@ -38,8 +38,7 @@ public: SyncerBasicInfo DumpSyncerBasicInfo() override; protected: - int SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const override; + int SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, ISyncInterface *storage) const override; private: // if trigger full sync, no need to trigger query sync again diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp index 1daf4e20bce64c813ff4a3712476056f72c47be9..1b00d4e8f4564e26d9f89033d211e30c86f4fb3c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp @@ -167,18 +167,19 @@ void SingleVerRelationalSyncer::SchemaChangeCallback() syncEngine_->SchemaChange(); } -int SingleVerRelationalSyncer::SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const +int SingleVerRelationalSyncer::SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, + ISyncInterface *storage) const { - if (!isQuerySync) { + if (!param.isQuerySync) { return E_OK; } - int errCode = static_cast(syncInterface_)->CheckAndInitQueryCondition(query); + QuerySyncObject query = param.syncQuery; + int errCode = static_cast(storage)->CheckAndInitQueryCondition(query); if (errCode != E_OK) { LOGE("[SingleVerRelationalSyncer] QuerySyncObject check failed"); return errCode; } - if (mode == SUBSCRIBE_QUERY) { + if (param.mode == SUBSCRIBE_QUERY) { return -E_NOT_SUPPORT; } return E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.h index 8a733a064bbf9bc3b4fc0a0cf2101af9ab55218f..04102c8d95fe97e0f03e3b03dc751cd3a98cd20c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.h @@ -35,8 +35,7 @@ protected: int PrepareSync(const SyncParma ¶m, uint32_t syncId, uint64_t connectionId) override; - int SyncConditionCheck(QuerySyncObject &query, int mode, bool isQuerySync, - const std::vector &devices) const override; + int SyncConditionCheck(const SyncParma ¶m, const ISyncEngine *engine, ISyncInterface *storage) const override; private: diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.h b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.h index cb4035b1260d616eb3e8d53262eb31dfec749a22..33f19fc7b0a20aba16e3d2f6fb6f308395dd42f9 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.h @@ -16,6 +16,7 @@ #ifndef SINGLE_VER_SERIALIZE_MANAGER_NEW_H #define SINGLE_VER_SERIALIZE_MANAGER_NEW_H +#include #include "icommunicator.h" #include "isync_packet.h" #include "message_transform.h" diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp index 278ff798adb1945653a24bbaa9e4317c08b48ebc..aa753b1d753a64a767a0f473df26abc2a7da0aac 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.cpp @@ -490,6 +490,7 @@ void SingleVerSyncTaskContext::SaveLastPushTaskExecStatus(int finalStatus) if (mode_ == SyncModeType::PUSH || mode_ == SyncModeType::PUSH_AND_PULL || mode_ == SyncModeType::RESPONSE_PULL) { lastFullSyncTaskStatus_ = finalStatus; } else if (mode_ == SyncModeType::QUERY_PUSH || mode_ == SyncModeType::QUERY_PUSH_PULL) { + std::lock_guard autoLock(queryTaskStatusMutex_); lastQuerySyncTaskStatusMap_[syncOperation_->GetQueryId()] = finalStatus; } } @@ -515,6 +516,7 @@ int SingleVerSyncTaskContext::GetCorrectedSendWaterMarkForCurrentTask(const Sync void SingleVerSyncTaskContext::ResetLastPushTaskStatus() { lastFullSyncTaskStatus_ = SyncOperation::OP_WAITING; + std::lock_guard autoLock(queryTaskStatusMutex_); lastQuerySyncTaskStatusMap_.clear(); } @@ -536,6 +538,7 @@ bool SingleVerSyncTaskContext::IsCurrentSyncTaskCanBeSkippedInner(const SyncOper if (operation == nullptr) { return true; } + std::lock_guard autoLock(queryTaskStatusMutex_); auto it = lastQuerySyncTaskStatusMap_.find(operation->GetQueryId()); if (it == lastQuerySyncTaskStatusMap_.end()) { // no last query_push and push diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.h b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.h index 4aff0679c6657f3a46355d1d41abcf85d5eb1fc6..19145a8baf08a58aacadcc26209977bf714845d3 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_sync_task_context.h @@ -145,7 +145,7 @@ protected: bool isQuerySync_ = false; // for merge sync task - int lastFullSyncTaskStatus_ = SyncOperation::Status::OP_WAITING; + volatile int lastFullSyncTaskStatus_ = SyncOperation::Status::OP_WAITING; private: int GetCorrectedSendWaterMarkForCurrentTask(const SyncOperation *operation, uint64_t &waterMark) const; @@ -172,6 +172,7 @@ private: // For subscribe manager std::shared_ptr subManager_; + mutable std::mutex queryTaskStatusMutex_; // std::unordered_map lastQuerySyncTaskStatusMap_; }; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp index 97499394e7f1e68ab4ae5af16e657259f3d881d2..297c3b25a71afef0e5e6a1069a59cd50d384f5a3 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp @@ -89,13 +89,20 @@ int SyncTaskContext::AddSyncTarget(ISyncTarget *target) return -E_INVALID_ARGS; } } - CancelCurrentSyncRetryIfNeed(targetMode); + RefObject::IncObjRef(this); + int errCode = RuntimeContext::GetInstance()->ScheduleTask([this, targetMode]() { + CancelCurrentSyncRetryIfNeed(targetMode); + RefObject::DecObjRef(this); + }); + if (errCode != E_OK) { + RefObject::DecObjRef(this); + } if (taskExecStatus_ == RUNNING) { return E_OK; } if (onSyncTaskAdd_) { RefObject::IncObjRef(this); - int errCode = RuntimeContext::GetInstance()->ScheduleTask([this]() { + errCode = RuntimeContext::GetInstance()->ScheduleTask([this]() { onSyncTaskAdd_(); RefObject::DecObjRef(this); }); diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/delegate_fuzzer/delegate_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/delegate_fuzzer/delegate_fuzzer.cpp index fb3a4cb7f40e7c7d34cde2fdaf3791370ff1e569..c2e20ea205748212bfeae57ee4308946fd72cfab 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/delegate_fuzzer/delegate_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/delegate_fuzzer/delegate_fuzzer.cpp @@ -36,21 +36,29 @@ std::vector CreateEntries(const uint8_t* data, size_t size, std::vectorUnRegisterObserver(observer); + delete observer; return; } auto valueCallback = [&value] (DBStatus status, const Value &getValue) { @@ -82,9 +92,10 @@ void MultiCombineFuzzer(const uint8_t* data, size_t size, KvStoreDelegate::Optio kvDelegatePtr->DeleteBatch(keys); kvDelegatePtr->Clear(); kvDelegatePtr->UnRegisterObserver(observer); + delete observer; kvDelegatePtr->ReleaseKvStoreSnapshot(kvStoreSnapshotPtr); - kvManger.CloseKvStore(kvDelegatePtr); - kvManger.DeleteKvStore("distributed_delegate_test"); + g_kvManger.CloseKvStore(kvDelegatePtr); + g_kvManger.DeleteKvStore("distributed_delegate_test"); DistributedDBToolsTest::RemoveTestDbFiles(config.dataDir); } } diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp index 983271bda04cc5d44e19f63658b5d91671d4d0cd..2b1e494bf0f74e24c007132b103a6fdf74e123cf 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp @@ -178,6 +178,8 @@ void FuzzCURD(const uint8_t* data, size_t size, KvStoreNbDelegate *kvNbDelegateP } kvNbDelegatePtr->DeleteBatch(keys); kvNbDelegatePtr->UnRegisterObserver(observer); + delete observer; + observer = nullptr; kvNbDelegatePtr->PutLocalBatch(tmp); kvNbDelegatePtr->DeleteLocalBatch(keys); std::string tmpStoreId = kvNbDelegatePtr->GetStoreId(); diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/relationalstoredelegate_fuzzer/relationalstoredelegate_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/relationalstoredelegate_fuzzer/relationalstoredelegate_fuzzer.cpp index 9a3e1ecb8bd535fd8e617c94f59ceb42ca8e2c00..64d5d60f91b0d210128fc6d60a1f1e0be2b8e108 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/relationalstoredelegate_fuzzer/relationalstoredelegate_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/relationalstoredelegate_fuzzer/relationalstoredelegate_fuzzer.cpp @@ -23,7 +23,7 @@ #include "virtual_communicator_aggregator.h" #include "query.h" #include "store_types.h" -#include "result_set.h" +#include "distributeddb/result_set.h" #include "runtime_context.h" namespace OHOS { diff --git a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_kv_crud_test.cpp b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_kv_crud_test.cpp index b9ee63b181c366c4dce38013bf65a8784769cacb..9623e8235b2151e1690111bddd49cfc029c0f6b2 100644 --- a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_kv_crud_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_kv_crud_test.cpp @@ -651,21 +651,6 @@ HWTEST_F(DistributeddbKvCrudTest, ComplexDataTest006, TestSize.Level1) EXPECT_TRUE(valueResult.size() == 0); } -/* - * @tc.name: ComplexDataTest 007 - * @tc.desc: Verify that can operate chinese string key and value. - * @tc.type: FUNC - * @tc.require: SR000BUH3J - * @tc.author: luqianfu - */ -HWTEST_F(DistributeddbKvCrudTest, ComplexDataTest007, TestSize.Level1) -{ - /* - * @tc.steps: step1. create kv db and put(k,OK_VALUE_1) that k="中文"and get. - * @tc.expected: step1. put successfully and get the value of k is OK_VALUE_1. - */ -} - /* * @tc.name: ReadWritePerformance 001 * @tc.desc: calculate the time of put-get in 16b-100b/16b-100kb, 1k times' random-put&get. @@ -710,12 +695,12 @@ HWTEST_F(DistributeddbKvCrudTest, ReadWritePerformance001, TestSize.Level3) }; for (int ps = 0; ps < PERFORMANCE_SIZE; ++ps) { - DistributedTestTools::CalculateOpenPerformance(performanceData[ps]); - DistributedTestTools::CalculateInsertPerformance(performanceData[ps]); - DistributedTestTools::CalculateGetPutPerformance(performanceData[ps]); - DistributedTestTools::CalculateUpdatePerformance(performanceData[ps]); - DistributedTestTools::CalculateGetUpdatePerformance(performanceData[ps]); - DistributedTestTools::CalculateUseClearPerformance(performanceData[ps]); + EXPECT_TRUE(DistributedTestTools::CalculateOpenPerformance(performanceData[ps])); + EXPECT_TRUE(DistributedTestTools::CalculateInsertPerformance(performanceData[ps])); + EXPECT_TRUE(DistributedTestTools::CalculateGetPutPerformance(performanceData[ps])); + EXPECT_TRUE(DistributedTestTools::CalculateUpdatePerformance(performanceData[ps])); + EXPECT_TRUE(DistributedTestTools::CalculateGetUpdatePerformance(performanceData[ps])); + EXPECT_TRUE(DistributedTestTools::CalculateUseClearPerformance(performanceData[ps])); } } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp index e5a96775640805b4dc8b7f8e87bb3d02968f565f..652b94146abd4391ffd92a853ef9bba804bcf77f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp @@ -146,11 +146,16 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, WaitAndRetrySend001, TestSize.Level2 g_commBB->RegOnMessageCallback([&msgForBB](const std::string &srcTarget, Message *inMsg) { msgForBB = inMsg; }, nullptr); + Message *msgForCA = nullptr; + g_commCA->RegOnMessageCallback([&msgForCA](const std::string &srcTarget, Message *inMsg) { + msgForCA = inMsg; + }, nullptr); /** * @tc.steps: step1. connect device A with device B */ AdapterStub::ConnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); + AdapterStub::ConnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceC.adapterHandle); std::this_thread::sleep_for(std::chrono::milliseconds(200)); // Wait 200 ms to make sure quiet /** @@ -167,8 +172,16 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, WaitAndRetrySend001, TestSize.Level2 SendConfig conf = {true, false, 0}; int errCode = g_commAB->SendMessage(DEVICE_NAME_B, msgForAB, conf); EXPECT_EQ(errCode, E_OK); + + Message *msgForAA = BuildRegedTinyMessage(); + ASSERT_NE(msgForAA, nullptr); + errCode = g_commAA->SendMessage(DEVICE_NAME_C, msgForAA, conf); + EXPECT_EQ(errCode, E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Wait 100 ms EXPECT_EQ(msgForBB, nullptr); + EXPECT_NE(msgForCA, nullptr); + delete msgForCA; + msgForCA = nullptr; /** * @tc.steps: step4. device A simulate sendable feedback diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_test.cpp index c8a083ca6ea15e4c193554574569080934a23b69..625c4e4b5c44e147989ff32169d50e8af1db1ba2 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_test.cpp @@ -1303,6 +1303,33 @@ namespace { } LOGD("Succeed %d times", totalNum); } + + void FreqOpenClose001() + { + std::string storeId = "FrqOpenClose001"; + std::thread t1(OpenCloseDatabase, storeId); + std::thread t2(OpenCloseDatabase, storeId); + std::thread t3(OpenCloseDatabase, storeId); + std::thread t4(OpenCloseDatabase, storeId); + t1.join(); + t2.join(); + t3.join(); + t4.join(); + EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); + } + + void FreqOpenCloseDel001() + { + std::string storeId = "FrqOpenCloseDelete001"; + std::thread t1(OpenCloseDatabase, storeId); + std::thread t2([&]() { + for (int i = 0; i < 10000; i++) { // loop 10000 times + g_mgr.DeleteKvStore(storeId); + } + }); + t1.join(); + t2.join(); + } } /** @@ -1314,15 +1341,7 @@ namespace { */ HWTEST_F(DistributedDBInterfacesDatabaseTest, FreqOpenCloseDel001, TestSize.Level2) { - std::string storeId = "FrqOpenCloseDelete001"; - std::thread t1(OpenCloseDatabase, storeId); - std::thread t2([&]() { - for (int i = 0; i < 10000; i++) { - g_mgr.DeleteKvStore(storeId); - } - }); - t1.join(); - t2.join(); + ASSERT_NO_FATAL_FAILURE(FreqOpenCloseDel001()); } /** @@ -1334,16 +1353,7 @@ HWTEST_F(DistributedDBInterfacesDatabaseTest, FreqOpenCloseDel001, TestSize.Leve */ HWTEST_F(DistributedDBInterfacesDatabaseTest, FreqOpenClose001, TestSize.Level2) { - std::string storeId = "FrqOpenClose001"; - std::thread t1(OpenCloseDatabase, storeId); - std::thread t2(OpenCloseDatabase, storeId); - std::thread t3(OpenCloseDatabase, storeId); - std::thread t4(OpenCloseDatabase, storeId); - t1.join(); - t2.join(); - t3.join(); - t4.join(); - EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); + ASSERT_NO_FATAL_FAILURE(FreqOpenClose001()); } /** @@ -1407,6 +1417,56 @@ HWTEST_F(DistributedDBInterfacesDatabaseTest, CompressionRate1, TestSize.Level1) EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); } +/** + * @tc.name: CompressionRate2 + * @tc.desc: Open the kv store with again with different compression option. + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesDatabaseTest, CompressionRate2, TestSize.Level1) +{ + /** + * @tc.steps: step1. Open the kv store with the option that comressionRate is invalid. + * @tc.expected: step1. Open kv store successfully. Returns OK. + */ + KvStoreNbDelegate::Option option; + option.isNeedCompressOnSync = true; + option.compressionRate = 70; // 70 compression rate. + const std::string storeId("CompressionRate1"); + g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + + /** + * @tc.steps: step2. Open again with different compression option + * @tc.expected: step2. Open kv store failed. Returns INVALID_ARGS. + */ + DBStatus status; + KvStoreNbDelegate *delegate = nullptr; + auto callback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, + placeholders::_1, placeholders::_2, std::ref(status), std::ref(delegate)); + + option.compressionRate = 80; // 80 compression rate. + g_mgr.GetKvStore(storeId, option, callback); + ASSERT_TRUE(delegate == nullptr); + EXPECT_TRUE(status == INVALID_ARGS); + + option.isNeedCompressOnSync = false; + option.compressionRate = 70; // 70 compression rate. + g_mgr.GetKvStore(storeId, option, callback); + ASSERT_TRUE(delegate == nullptr); + EXPECT_TRUE(status == INVALID_ARGS); + + /** + * @tc.steps: step3. Close kv store + * @tc.expected: step3. OK. + */ + g_mgr.CloseKvStore(g_kvNbDelegatePtr); + g_kvNbDelegatePtr = nullptr; + EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); +} + HWTEST_F(DistributedDBInterfacesDatabaseTest, DataInterceptor1, TestSize.Level1) { /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_device_identifier_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_device_identifier_test.cpp index 7cb509e4f0150809ed108dc3edcf40aee1544215..b670fdbaf4b60089b5d877b5db67525904158967 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_device_identifier_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_device_identifier_test.cpp @@ -519,6 +519,18 @@ HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest001, TestSize.Level storageEngine->Release(); } +namespace { +void StorageEngineTest002() +{ + std::string exportFileName = g_testDir + "/" + STORE_ID + ".dump"; + int fd = open(exportFileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP)); + ASSERT_TRUE(fd >= 0); + g_store->Dump(fd); + close(fd); + OS::RemoveDBDirectory(exportFileName); +} +} + /** * @tc.name: StorageEngineTest002 * @tc.desc: Test the interface of Dump @@ -528,12 +540,7 @@ HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest001, TestSize.Level */ HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest002, TestSize.Level1) { - std::string exportFileName = g_testDir + "/" + STORE_ID + ".dump"; - int fd = open(exportFileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP)); - ASSERT_TRUE(fd >= 0); - g_store->Dump(fd); - close(fd); - OS::RemoveDBDirectory(exportFileName); + ASSERT_NO_FATAL_FAILURE(StorageEngineTest002()); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_encrypt_delegate_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_encrypt_delegate_test.cpp index 938c0ff852f21eec23946b681901f7159fe1419b..1d15ede5232339600ddaff7041cb8196866f3263 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_encrypt_delegate_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_encrypt_delegate_test.cpp @@ -542,17 +542,6 @@ HWTEST_F(DistributedDBInterfacesEncryptDelegateTest, EncryptedDbSwitch004, TestS EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID1), OK); } -/** - * @tc.name: EncryptedDbSwitch008 - * @tc.desc: Test the multi version db Rekey function return BUSY because of Snapshot not close. - * @tc.type: FUNC - * @tc.require: AR000CQDT7 - * @tc.author: wumin - */ -HWTEST_F(DistributedDBInterfacesEncryptDelegateTest, EncryptedDbSwitch008, TestSize.Level1) -{ -} - /** * @tc.name: EncryptedDbSwitch009 * @tc.desc: Test the single version db Rekey function from password1 to password2. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp index 367c74658bdc7d53ec372d1c57c339518ce1e673..40cddf0ce681cb79bc7575e031a99f4345b44d4b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp @@ -2411,6 +2411,57 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, LocalStore002, TestSize.Level1) EXPECT_EQ(mgr.CloseKvStore(localDelegate), OK); } +/** + * @tc.name: PutSync001 + * @tc.desc: put data and sync at same time + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, PutSync001, TestSize.Level3) +{ + /** + * @tc.steps:step1. Create database with localOnly. + * @tc.expected: step1. Returns a non-null store. + */ + KvStoreDelegateManager mgr(APP_ID, USER_ID); + mgr.SetKvStoreConfig(g_config); + const KvStoreNbDelegate::Option option = {true, false, false}; + mgr.GetKvStore(STORE_ID_1, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_EQ(g_kvDelegateStatus, OK); + /** + * @tc.steps:step2. Put data async. + * @tc.expected: step2. Always returns OK. + */ + std::atomic finish = false; + std::thread putThread([&finish]() { + while (!finish) { + EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK); + } + }); + /** + * @tc.steps:step3. Call sync async. + * @tc.expected: step3. Always returns OK. + */ + std::thread syncThread([]() { + std::vector devices; + devices.emplace_back(""); + Key key = {'k'}; + for (int i = 0; i < 100; ++i) { // sync 100 times + Query query = Query::Select().PrefixKey(key); + DBStatus status = g_kvNbDelegatePtr->Sync(devices, SYNC_MODE_PULL_ONLY, nullptr, query, true); + EXPECT_EQ(status, OK); + } + }); + syncThread.join(); + finish = true; + putThread.join(); + EXPECT_EQ(mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + g_kvNbDelegatePtr = nullptr; + EXPECT_EQ(mgr.DeleteKvStore(STORE_ID_1), OK); +} + /** * @tc.name: ResultSetLimitTest001 * @tc.desc: Get result set over limit diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp index 6fb13ca526bd26a9b5deca188e6b615eea923106..a974f4a722600bfebcc39a2752a7ecc7d986c6ad 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp @@ -71,6 +71,15 @@ namespace { level INTEGER ))""; + const std::string ALL_FIELD_TYPE_TABLE_SQL = R""(CREATE TABLE IF NOT EXISTS tbl_all_type( + id INTEGER PRIMARY KEY, + f_int INT, + f_real REAL, + f_text TEXT, + f_blob BLOB, + f_none + ))""; + void FakeOldVersionDB(sqlite3 *db) { std::string dropTrigger = "DROP TRIGGER IF EXISTS naturalbase_rdb_student_1_ON_UPDATE;"; @@ -851,4 +860,166 @@ HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest002, Tes EXPECT_EQ(sqlite3_column_int64(stmt, 3), 91); // 91 score return OK; }); +} + +/** + * @tc.name: SyncZeroBlobTest001 + * @tc.desc: Sync device with zero blob + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest001, TestSize.Level1) +{ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK); + AddDeviceSchema(g_deviceB, db, "tbl_all_type"); + + // prepare with zero blob data + std::string insertSql = "INSERT INTO tbl_all_type VALUES(?, ?, ?, ?, ?, ?)"; + int ret = RelationalTestUtils::ExecSql(db, insertSql, [] (sqlite3_stmt *stmt) { + sqlite3_bind_int64(stmt, 1, 1001); // 1, 1001 bind index, bind value + sqlite3_bind_int64(stmt, 2, 12344); // 2, 12344 bind index, bind value + sqlite3_bind_double(stmt, 3, 1.234); // 3, 1.234 bind index, bind value + SQLiteUtils::BindTextToStatement(stmt, 4, ""); // 4, bind index + SQLiteUtils::BindBlobToStatement(stmt, 5, {}); // 5,bind index + return E_OK; + }, nullptr); + EXPECT_EQ(ret, E_OK); + + std::vector devices = {DEVICE_B}; + Query query = Query::Select("tbl_all_type"); + int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query, + [&devices](const std::map> &devicesMap) { + EXPECT_EQ(devicesMap.size(), devices.size()); + for (const auto &itDev : devicesMap) { + for (const auto &itTbl : itDev.second) { + EXPECT_EQ(itTbl.status, OK); + } + } + }, true); + EXPECT_EQ(errCode, OK); + + std::vector data; + g_deviceB->GetAllSyncData("tbl_all_type", data); + EXPECT_EQ(data.size(), 1U); + for (const auto &it : data) { + DataValue val; + it.objectData.GetDataValue("id", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER); + it.objectData.GetDataValue("f_int", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER); + it.objectData.GetDataValue("f_real", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_REAL); + it.objectData.GetDataValue("f_text", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_TEXT); + it.objectData.GetDataValue("f_blob", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_BLOB); + it.objectData.GetDataValue("f_none", val); + EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_NULL); + } +} + +namespace { +struct TblAllType { + DataValue id_; + DataValue fInt_; + DataValue fReal_; + DataValue fText_; + DataValue fBlob_; + DataValue fNone_; + + TblAllType(int64_t id, int64_t fInt, double fReal, const std::string &fText, const Blob &fBlob) + { + id_ = id; + fInt_ = fInt; + fReal_ = fReal; + fText_ = fText; + fBlob_ = fBlob; + } + + VirtualRowData operator() () const + { + VirtualRowData virtualRowData; + virtualRowData.objectData.PutDataValue("id", id_); + virtualRowData.objectData.PutDataValue("f_int", fInt_); + virtualRowData.objectData.PutDataValue("f_real", fReal_); + virtualRowData.objectData.PutDataValue("f_text", fText_); + virtualRowData.objectData.PutDataValue("f_blob", fBlob_); + virtualRowData.objectData.PutDataValue("f_none", fNone_); + + virtualRowData.logInfo.dataKey = 4; // 4 fake datakey + virtualRowData.logInfo.device = DEVICE_B; + virtualRowData.logInfo.originDev = DEVICE_B; + virtualRowData.logInfo.timestamp = 3170194300891338180; // 3170194300891338180 fake timestamp + virtualRowData.logInfo.wTimestamp = 3170194300891338180; // 3170194300891338180 fake timestamp + virtualRowData.logInfo.flag = 2; // 2 fake flag + + std::vector hashKey; + DBCommon::CalcValueHash({}, hashKey); + virtualRowData.logInfo.hashKey = hashKey; + return virtualRowData; + } +}; +} + +/** + * @tc.name: SyncZeroBlobTest002 + * @tc.desc: Sync device with zero blob + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest002, TestSize.Level1) +{ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK); + AddDeviceSchema(g_deviceB, db, "tbl_all_type"); + + std::vector dataList; + g_deviceB->PutDeviceData("tbl_all_type", + std::vector {{1001, 12344, 1.234, "", {}}}); // 1001, 12344, 1.234 : fake data + + std::vector devices = {DEVICE_B}; + Query query = Query::Select("tbl_all_type"); + int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, + [&devices](const std::map> &devicesMap) { + EXPECT_EQ(devicesMap.size(), devices.size()); + for (const auto &itDev : devicesMap) { + for (const auto &itTbl : itDev.second) { + EXPECT_EQ(itTbl.status, OK); + } + } + }, true); + EXPECT_EQ(errCode, OK); + + std::string devictTbl = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "tbl_all_type"); + std::string insertSql = "SELECT * FROM " + devictTbl; + int resCnt = 0; + int ret = RelationalTestUtils::ExecSql(db, insertSql, nullptr, [&resCnt](sqlite3_stmt *stmt) { + EXPECT_EQ(sqlite3_column_type(stmt, 0), SQLITE_INTEGER); + EXPECT_EQ(sqlite3_column_int(stmt, 0), 1001); // 1001: fake data + + EXPECT_EQ(sqlite3_column_type(stmt, 1), SQLITE_INTEGER); // 1: column index + EXPECT_EQ(sqlite3_column_int(stmt, 1), 12344); // 1: column index; 12344: fake data + + EXPECT_EQ(sqlite3_column_type(stmt, 2), SQLITE_FLOAT); // 2: column index + EXPECT_EQ(sqlite3_column_double(stmt, 2), 1.234); // 2: column index; 1.234: fake data + + EXPECT_EQ(sqlite3_column_type(stmt, 3), SQLITE_TEXT); // 3: column index + std::string strVal; + SQLiteUtils::GetColumnTextValue(stmt, 3, strVal); // 3: column index + EXPECT_EQ(strVal, ""); + + EXPECT_EQ(sqlite3_column_type(stmt, 4), SQLITE_BLOB); // 4: column index + std::vector blobVal; + SQLiteUtils::GetColumnBlobValue(stmt, 4, blobVal); // 4: column index + EXPECT_EQ(blobVal, std::vector {}); + + EXPECT_EQ(sqlite3_column_type(stmt, 5), SQLITE_NULL); // 5: column index + resCnt++; + return E_OK; + }); + EXPECT_EQ(resCnt, 1); + EXPECT_EQ(ret, E_OK); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index dacc87d20b7594dc1eb11569981d257d31b9b0d0..30ac553382052cc5698ae1799861850ceda0b003 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -729,9 +729,15 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest00 * @tc.steps:step3. Remove device data * @tc.expected: step3. ok */ + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), DISTRIBUTED_SCHEMA_NOT_FOUND); + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), DISTRIBUTED_SCHEMA_NOT_FOUND); + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data"), DISTRIBUTED_SCHEMA_NOT_FOUND); + EXPECT_EQ(delegate->CreateDistributedTable("sync_data"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_B"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_C", "sync_data"), OK); + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), OK); + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data_A"), DISTRIBUTED_SCHEMA_NOT_FOUND); /** * @tc.steps:step4. Remove device data with invalid args diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/runtime_context_process_system_api_adapter_impl_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/runtime_context_process_system_api_adapter_impl_test.cpp index efc54f8b65e8dfa30bfbfeb27c1533b9c399400e..5c280f774a85bd7ff2d6d3a83a753deb35022bfd 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/runtime_context_process_system_api_adapter_impl_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/runtime_context_process_system_api_adapter_impl_test.cpp @@ -241,15 +241,8 @@ void FuncCheckDeviceSecurityAbility() RuntimeContext::GetInstance()->CheckDeviceSecurityAbility("", SecurityOption()); return; } -} -/** - * @tc.name: CheckDeviceSecurityAbility002 - * @tc.desc: Check device security ability with getkvstore frequency. - * @tc.type: FUNC - * @tc.require: AR000EV1G2 - */ -HWTEST_F(RuntimeContextProcessSystemApiAdapterImplTest, CheckDeviceSecurityAbility002, TestSize.Level1) +void CheckDeviceSecurityAbility002() { g_config.dataDir = g_testDir; g_mgr.SetKvStoreConfig(g_config); @@ -267,11 +260,21 @@ HWTEST_F(RuntimeContextProcessSystemApiAdapterImplTest, CheckDeviceSecurityAbili g_mgr.CloseKvStore(g_kvNbDelegatePtr); } }); - std::thread t3(FuncCheckDeviceSecurityAbility); t1.join(); t2.join(); - t3.join(); +} +} + +/** + * @tc.name: CheckDeviceSecurityAbility002 + * @tc.desc: Check device security ability with getkvstore frequency. + * @tc.type: FUNC + * @tc.require: AR000EV1G2 + */ +HWTEST_F(RuntimeContextProcessSystemApiAdapterImplTest, CheckDeviceSecurityAbility002, TestSize.Level1) +{ + ASSERT_NO_FATAL_FAILURE(CheckDeviceSecurityAbility002()); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp index 28c64083d83c19594e5a87df54f9d6a59ea6f79a..47a2e1524813a7fa5d7a3e5a8c468e0d3db132cd 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp @@ -261,6 +261,22 @@ void SetRemoteSchema(const RelationalSyncAbleStorage *store, const std::string & uint8_t remoteSchemaType = static_cast(store->GetSchemaInfo().GetSchemaType()); const_cast(store)->SaveRemoteDeviceSchema(deviceID, remoteSchema, remoteSchemaType); } + +void SetNextBeginTime001() +{ + QueryObject query(Query::Select(g_tableName)); + std::unique_ptr token = + std::make_unique(SyncTimeRange {}, query); + ASSERT_TRUE(token != nullptr); + + DataItem dataItem; + dataItem.timestamp = INT64_MAX; + token->SetNextBeginTime(dataItem); + + dataItem.flag = DataItem::DELETE_FLAG; + token->FinishGetData(); + token->SetNextBeginTime(dataItem); +} } class DistributedDBRelationalGetDataTest : public testing::Test { @@ -1596,18 +1612,7 @@ HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1) */ HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1) { - QueryObject query(Query::Select(g_tableName)); - std::unique_ptr token = - std::make_unique(SyncTimeRange {}, query); - ASSERT_TRUE(token != nullptr); - - DataItem dataItem; - dataItem.timestamp = INT64_MAX; - token->SetNextBeginTime(dataItem); - - dataItem.flag = DataItem::DELETE_FLAG; - token->FinishGetData(); - token->SetNextBeginTime(dataItem); + ASSERT_NO_FATAL_FAILURE(SetNextBeginTime001()); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_executor_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_executor_test.cpp index 6467e541b53ef582d01bb49f6c1fb6ac3c48e954..8782ba42678e1c88415b7638e56a1b2460a98fe6 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_executor_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_executor_test.cpp @@ -54,7 +54,7 @@ public: void DistributedDBStorageSQLiteSingleVerNaturalExecutorTest::SetUpTestCase(void) { DistributedDBToolsUnitTest::TestDirInit(g_testDir); - LOGD("DistributedDBStorageSQLiteSingleVerNaturalExecutorTest dir is %s", g_testDir.c_str()); + LOGI("DistributedDBStorageSQLiteSingleVerNaturalExecutorTest dir is %s", g_testDir.c_str()); std::string oriIdentifier = APP_ID + "-" + USER_ID + "-" + "TestGeneralNBExecutor"; std::string identifier = DBCommon::TransferHashString(oriIdentifier); g_identifier = DBCommon::TransferStringToHex(identifier); @@ -926,7 +926,6 @@ HWTEST_F(DistributedDBStorageSQLiteSingleVerNaturalExecutorTest, ExecutorCache00 /** * @tc.steps: step3. Change executor to MAIN_ATTACH_CACHE - * @tc.expected: step3. Expect SQL_STATE_ERR */ auto executor2 = std::make_unique( sqlHandle, false, false, ExecutorState::MAIN_ATTACH_CACHE); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_subscribe_query_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_subscribe_query_test.cpp index 7248ae2f766ce8c1f8d46792f630ad7fdb7fe92e..c485778696ad0c5ab8c817bcbf500241e2cda948 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_subscribe_query_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_subscribe_query_test.cpp @@ -815,4 +815,50 @@ HWTEST_F(DistributedDBStorageSubscribeQueryTest, AddSubscribeTest003, TestSize.L */ RefObject::KillAndDecObjRef(store); KvDBManager::ReleaseDatabaseConnection(conn); +} + +/** + * @tc.name: AddSubscribeTest004 + * @tc.desc: Add subscribe with query by prefixKey + * @tc.type: FUNC + * @tc.require: + * @tc.author: xulianhui + */ +HWTEST_F(DistributedDBStorageSubscribeQueryTest, AddSubscribeTest004, TestSize.Level1) +{ + /** + * @tc.steps:step1. Create a json schema db, get the natural store instance. + * @tc.expected: Get results OK and non-null store. + */ + SQLiteSingleVerNaturalStoreConnection *conn = nullptr; + SQLiteSingleVerNaturalStore *store = nullptr; + CreateAndGetStore("SubscribeTest02", "", conn, store); + + /** + * @tc.steps:step2. Add subscribe with query by prefixKey + * @tc.expected: step2. add success + */ + Query query = Query::Select().PrefixKey(NULL_KEY_1); + QueryObject queryObj(query); + int errCode = store->AddSubscribe(SUBSCRIBE_ID, queryObj, false); + EXPECT_EQ(errCode, E_OK); + + IOption syncIOpt {IOption::SYNC_DATA}; + EXPECT_EQ(conn->Put(syncIOpt, KEY_1, {}), E_OK); + + Value valGot; + EXPECT_EQ(conn->Get(syncIOpt, KEY_1, valGot), E_OK); + EXPECT_EQ(valGot, Value {}); + + std::string subKey = DBConstant::SUBSCRIBE_QUERY_PREFIX + DBCommon::TransferHashString(SUBSCRIBE_ID); + Key metaKey(subKey.begin(), subKey.end()); + EXPECT_EQ(store->GetMetaData(metaKey, valGot), E_OK); + EXPECT_NE(valGot.size(), 0u); + + /** + * @tc.steps:step3. Close natural store + * @tc.expected: step3. Close ok + */ + RefObject::KillAndDecObjRef(store); + KvDBManager::ReleaseDatabaseConnection(conn); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index 9e688a50dbdf7f530bf3938c3341da4c9af696c7..1bde06faac50cd51935b9730faf87af3e6b256fa 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -117,6 +117,7 @@ void Init(MockSingleVerStateMachine &stateMachine, MockSyncTaskContext *syncTask MockCommunicator &communicator, VirtualSingleVerSyncDBInterface *dbSyncInterface) { std::shared_ptr metadata = std::make_shared(); + ASSERT_EQ(metadata->Initialize(dbSyncInterface), E_OK); (void)syncTaskContext->Initialize("device", dbSyncInterface, metadata, &communicator); (void)stateMachine.Initialize(syncTaskContext, dbSyncInterface, metadata, &communicator); } @@ -166,6 +167,206 @@ void ConstructPacel(Parcel &parcel, uint32_t conditionCount, const std::string & parcel.WriteString(key); parcel.WriteString(value); } + +void StateMachineCheck013() +{ + MockSingleVerStateMachine stateMachine; + auto *syncTaskContext = new (std::nothrow) MockSyncTaskContext(); + auto *dbSyncInterface = new (std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_NE(syncTaskContext, nullptr); + EXPECT_NE(dbSyncInterface, nullptr); + if (dbSyncInterface == nullptr) { + RefObject::KillAndDecObjRef(syncTaskContext); + return; + } + MockCommunicator communicator; + Init(stateMachine, syncTaskContext, communicator, dbSyncInterface); + EXPECT_CALL(*syncTaskContext, Clear()).WillRepeatedly(Return()); + syncTaskContext->RegForkGetDeviceIdFunc([]() { + std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2s + }); + auto token = new VirtualContinueToken(); + syncTaskContext->SetContinueToken(static_cast(token)); + RefObject::KillAndDecObjRef(syncTaskContext); + delete dbSyncInterface; + std::this_thread::sleep_for(std::chrono::seconds(5)); // sleep 5s and wait for task exist +} + +void AutoLaunchCheck001() +{ + MockAutoLaunch mockAutoLaunch; + /** + * @tc.steps: step1. put AutoLaunchItem in cache to simulate a connection was auto launched + */ + std::string id = "TestAutoLaunch"; + std::string userId = "userId"; + AutoLaunchItem item; + mockAutoLaunch.SetAutoLaunchItem(id, userId, item); + EXPECT_CALL(mockAutoLaunch, TryCloseConnection(_)).WillOnce(Return()); + /** + * @tc.steps: step2. send close signal to simulate a connection was unused in 1 min + * @tc.expected: 10 thread try to close the connection and one thread close success + */ + const int loopCount = 10; + int finishCount = 0; + std::mutex mutex; + std::unique_lock lock(mutex); + std::condition_variable cv; + for (int i = 0; i < loopCount; i++) { + std::thread t = std::thread([&finishCount, &mockAutoLaunch, &id, &userId, &mutex, &cv] { + mockAutoLaunch.CallExtConnectionLifeCycleCallbackTask(id, userId); + finishCount++; + if (finishCount == loopCount) { + std::unique_lock lockInner(mutex); + cv.notify_one(); + } + }); + t.detach(); + } + cv.wait(lock, [&finishCount, &loopCount]() { return finishCount == loopCount; }); +} + +void AbilitySync004() +{ + /** + * @tc.steps: step1. set table TEST is permitSync + */ + auto *context = new (std::nothrow) SingleVerKvSyncTaskContext(); + ASSERT_NE(context, nullptr); + /** + * @tc.steps: step2. test context recv dbAbility in diff thread + */ + const int loopCount = 1000; + std::atomic finishCount = 0; + std::mutex mutex; + std::unique_lock lock(mutex); + std::condition_variable cv; + for (int i = 0; i < loopCount; i++) { + std::thread t = std::thread([&] { + DbAbility dbAbility; + context->SetDbAbility(dbAbility); + finishCount++; + if (finishCount == loopCount) { + cv.notify_one(); + } + }); + t.detach(); + } + cv.wait(lock, [&]() { return finishCount == loopCount; }); + RefObject::KillAndDecObjRef(context); +} + +void SyncLifeTest001() +{ + std::shared_ptr syncer = std::make_shared(); + VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); + VirtualSingleVerSyncDBInterface *syncDBInterface = new VirtualSingleVerSyncDBInterface(); + syncer->Initialize(syncDBInterface, true); + syncer->EnableAutoSync(true); + for (int i = 0; i < 1000; i++) { // trigger 1000 times auto sync check + syncer->LocalDataChanged(static_cast(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT)); + } + syncer = nullptr; + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); + delete syncDBInterface; +} + +void SyncLifeTest002() +{ + std::shared_ptr syncer = std::make_shared(); + VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); + const std::string DEVICE_B = "deviceB"; + VirtualSingleVerSyncDBInterface *syncDBInterface = new VirtualSingleVerSyncDBInterface(); + std::string userId = "userid_0"; + std::string storeId = "storeId_0"; + std::string appId = "appid_0"; + std::string identifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, appId, storeId); + std::vector identifierVec(identifier.begin(), identifier.end()); + syncDBInterface->SetIdentifier(identifierVec); + for (int i = 0; i < 100; i++) { // run 100 times + syncer->Initialize(syncDBInterface, true); + syncer->EnableAutoSync(true); + virtualCommunicatorAggregator->OnlineDevice(DEVICE_B); + std::thread writeThread([syncer]() { + syncer->LocalDataChanged( + static_cast(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT)); + }); + std::thread closeThread([syncer, &syncDBInterface]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + syncer->Close(true); + }); + closeThread.join(); + writeThread.join(); + } + syncer = nullptr; + std::this_thread::sleep_for(std::chrono::seconds(1)); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); + delete syncDBInterface; +} + +void SyncLifeTest003() +{ + VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); + TestInterface *syncDBInterface = new TestInterface(); + const std::string DEVICE_B = "deviceB"; + std::string userId = "userId_0"; + std::string storeId = "storeId_0"; + std::string appId = "appId_0"; + std::string identifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, appId, storeId); + std::vector identifierVec(identifier.begin(), identifier.end()); + syncDBInterface->TestSetIdentifier(identifierVec); + syncDBInterface->Initialize(); + virtualCommunicatorAggregator->OnlineDevice(DEVICE_B); + syncDBInterface->TestLocalChange(); + virtualCommunicatorAggregator->OfflineDevice(DEVICE_B); + syncDBInterface->Close(); + RefObject::KillAndDecObjRef(syncDBInterface); + RuntimeContext::GetInstance()->StopTaskPool(); + std::this_thread::sleep_for(std::chrono::seconds(1)); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); +} + +void MockRemoteQuery002() +{ + MockRemoteExecutor *executor = new (std::nothrow) MockRemoteExecutor(); + ASSERT_NE(executor, nullptr); + executor->CallResponseFailed(0, 0, 0, "DEVICE"); + RefObject::KillAndDecObjRef(executor); +} + +void SyncerCheck001() +{ + std::shared_ptr syncer = std::make_shared(); + syncer->SetSyncRetry(true); + syncer = nullptr; +} + +void TimeSync001() +{ + auto *communicator = new(std::nothrow) MockCommunicator(); + ASSERT_NE(communicator, nullptr); + auto *storage = new(std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_NE(storage, nullptr); + std::shared_ptr metadata = std::make_shared(); + + EXPECT_CALL(*communicator, SendMessage(_, _, _, _)).WillRepeatedly(Return(DB_ERROR)); + const int loopCount = 100; + const int timeDriverMs = 100; + for (int i = 0; i < loopCount; ++i) { + MockTimeSync timeSync; + timeSync.Initialize(communicator, metadata, storage, "DEVICES_A"); + timeSync.ModifyTimer(timeDriverMs); + std::this_thread::sleep_for(std::chrono::milliseconds(timeDriverMs)); + timeSync.Close(); + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + metadata = nullptr; + delete storage; + delete communicator; +} } class DistributedDBMockSyncModuleTest : public testing::Test { @@ -489,28 +690,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, StateMachineCheck012, TestSize.Level1) */ HWTEST_F(DistributedDBMockSyncModuleTest, StateMachineCheck013, TestSize.Level1) { - MockSingleVerStateMachine stateMachine; - auto *syncTaskContext = new (std::nothrow) MockSyncTaskContext(); - auto *dbSyncInterface = new (std::nothrow) VirtualSingleVerSyncDBInterface(); - ASSERT_NE(syncTaskContext, nullptr); - EXPECT_NE(dbSyncInterface, nullptr); - if (dbSyncInterface == nullptr) { - RefObject::KillAndDecObjRef(syncTaskContext); - return; - } - MockCommunicator communicator; - Init(stateMachine, syncTaskContext, communicator, dbSyncInterface); - EXPECT_CALL(*syncTaskContext, Clear()).WillRepeatedly(Return()); - syncTaskContext->RegForkGetDeviceIdFunc([]() { - std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2s - }); - int token = 1; - int *tokenPtr = &token; - syncTaskContext->SetContinueToken(tokenPtr); - RefObject::KillAndDecObjRef(syncTaskContext); - delete dbSyncInterface; - std::this_thread::sleep_for(std::chrono::seconds(5)); // sleep 5s and wait for task exist - tokenPtr = nullptr; + ASSERT_NO_FATAL_FAILURE(StateMachineCheck013()); } /** @@ -600,6 +780,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, DataSyncCheck003, TestSize.Level1) delete message; } #endif + /** * @tc.name: AutoLaunchCheck001 * @tc.desc: Test autoLaunch close connection. @@ -609,36 +790,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, DataSyncCheck003, TestSize.Level1) */ HWTEST_F(DistributedDBMockSyncModuleTest, AutoLaunchCheck001, TestSize.Level1) { - MockAutoLaunch mockAutoLaunch; - /** - * @tc.steps: step1. put AutoLaunchItem in cache to simulate a connection was auto launched - */ - std::string id = "TestAutoLaunch"; - std::string userId = "userId"; - AutoLaunchItem item; - mockAutoLaunch.SetAutoLaunchItem(id, userId, item); - EXPECT_CALL(mockAutoLaunch, TryCloseConnection(_)).WillOnce(Return()); - /** - * @tc.steps: step2. send close signal to simulate a connection was unused in 1 min - * @tc.expected: 10 thread try to close the connection and one thread close success - */ - const int loopCount = 10; - int finishCount = 0; - std::mutex mutex; - std::unique_lock lock(mutex); - std::condition_variable cv; - for (int i = 0; i < loopCount; i++) { - std::thread t = std::thread([&finishCount, &mockAutoLaunch, &id, &userId, &mutex, &cv] { - mockAutoLaunch.CallExtConnectionLifeCycleCallbackTask(id, userId); - finishCount++; - if (finishCount == loopCount) { - std::unique_lock lockInner(mutex); - cv.notify_one(); - } - }); - t.detach(); - } - cv.wait(lock, [&finishCount, &loopCount]() { return finishCount == loopCount; }); + ASSERT_NO_FATAL_FAILURE(AutoLaunchCheck001()); } /** @@ -833,32 +985,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, AbilitySync003, TestSize.Level1) */ HWTEST_F(DistributedDBMockSyncModuleTest, AbilitySync004, TestSize.Level1) { - /** - * @tc.steps: step1. set table TEST is permitSync - */ - auto *context = new (std::nothrow) SingleVerKvSyncTaskContext(); - ASSERT_NE(context, nullptr); - /** - * @tc.steps: step2. test context recv dbAbility in diff thread - */ - const int loopCount = 1000; - std::atomic finishCount = 0; - std::mutex mutex; - std::unique_lock lock(mutex); - std::condition_variable cv; - for (int i = 0; i < loopCount; i++) { - std::thread t = std::thread([&] { - DbAbility dbAbility; - context->SetDbAbility(dbAbility); - finishCount++; - if (finishCount == loopCount) { - cv.notify_one(); - } - }); - t.detach(); - } - cv.wait(lock, [&]() { return finishCount == loopCount; }); - RefObject::KillAndDecObjRef(context); + ASSERT_NO_FATAL_FAILURE(AbilitySync004()); } /** @@ -870,18 +997,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, AbilitySync004, TestSize.Level1) */ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest001, TestSize.Level3) { - std::shared_ptr syncer = std::make_shared(); - VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); - RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); - VirtualSingleVerSyncDBInterface *syncDBInterface = new VirtualSingleVerSyncDBInterface(); - syncer->Initialize(syncDBInterface, true); - syncer->EnableAutoSync(true); - for (int i = 0; i < 1000; i++) { // trigger 1000 times auto sync check - syncer->LocalDataChanged(static_cast(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT)); - } - syncer = nullptr; - RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); - delete syncDBInterface; + ASSERT_NO_FATAL_FAILURE(SyncLifeTest001()); } /** @@ -893,36 +1009,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest001, TestSize.Level3) */ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest002, TestSize.Level3) { - std::shared_ptr syncer = std::make_shared(); - VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); - RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); - const std::string DEVICE_B = "deviceB"; - VirtualSingleVerSyncDBInterface *syncDBInterface = new VirtualSingleVerSyncDBInterface(); - std::string userId = "userid_0"; - std::string storeId = "storeId_0"; - std::string appId = "appid_0"; - std::string identifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, appId, storeId); - std::vector identifierVec(identifier.begin(), identifier.end()); - syncDBInterface->SetIdentifier(identifierVec); - for (int i = 0; i < 100; i++) { // run 100 times - syncer->Initialize(syncDBInterface, true); - syncer->EnableAutoSync(true); - virtualCommunicatorAggregator->OnlineDevice(DEVICE_B); - std::thread writeThread([syncer]() { - syncer->LocalDataChanged( - static_cast(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT)); - }); - std::thread closeThread([syncer, &syncDBInterface]() { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - syncer->Close(true); - }); - closeThread.join(); - writeThread.join(); - } - syncer = nullptr; - std::this_thread::sleep_for(std::chrono::seconds(1)); - RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); - delete syncDBInterface; + ASSERT_NO_FATAL_FAILURE(SyncLifeTest002()); } /** @@ -934,25 +1021,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest002, TestSize.Level3) */ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest003, TestSize.Level3) { - VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); - RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); - TestInterface *syncDBInterface = new TestInterface(); - const std::string DEVICE_B = "deviceB"; - std::string userId = "userId_0"; - std::string storeId = "storeId_0"; - std::string appId = "appId_0"; - std::string identifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, appId, storeId); - std::vector identifierVec(identifier.begin(), identifier.end()); - syncDBInterface->TestSetIdentifier(identifierVec); - syncDBInterface->Initialize(); - virtualCommunicatorAggregator->OnlineDevice(DEVICE_B); - syncDBInterface->TestLocalChange(); - virtualCommunicatorAggregator->OfflineDevice(DEVICE_B); - syncDBInterface->Close(); - RefObject::KillAndDecObjRef(syncDBInterface); - RuntimeContext::GetInstance()->StopTaskPool(); - std::this_thread::sleep_for(std::chrono::seconds(1)); - RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); + ASSERT_NO_FATAL_FAILURE(SyncLifeTest003()); } /** @@ -979,8 +1048,8 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncLifeTest004, TestSize.Level3) syncer->EnableAutoSync(true); incRefCount = 0; syncer->RemoteDataChanged(""); - EXPECT_EQ(incRefCount, 1); // refCount is 1 std::this_thread::sleep_for(std::chrono::seconds(1)); + EXPECT_EQ(incRefCount, 2); // refCount is 2 syncer = nullptr; RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); delete syncDBInterface; @@ -1431,10 +1500,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, MockRemoteQuery001, TestSize.Level3) */ HWTEST_F(DistributedDBMockSyncModuleTest, MockRemoteQuery002, TestSize.Level3) { - MockRemoteExecutor *executor = new (std::nothrow) MockRemoteExecutor(); - ASSERT_NE(executor, nullptr); - executor->CallResponseFailed(0, 0, 0, "DEVICE"); - RefObject::KillAndDecObjRef(executor); + ASSERT_NO_FATAL_FAILURE(MockRemoteQuery002()); } /** @@ -1456,6 +1522,62 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncTaskContextCheck001, TestSize.Leve EXPECT_EQ(syncTaskContext.CallIsCurrentSyncTaskCanBeSkipped(), true); } +/** + * @tc.name: SyncTaskContextCheck002 + * @tc.desc: test context check task can be skipped in push mode. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, SyncTaskContextCheck002, TestSize.Level1) +{ + /** + * @tc.steps: step1. create context and operation + */ + auto syncTaskContext = new(std::nothrow) MockSyncTaskContext(); + ASSERT_NE(syncTaskContext, nullptr); + auto operation = new SyncOperation(1u, {}, static_cast(SyncModeType::QUERY_PUSH), nullptr, false); + ASSERT_NE(operation, nullptr); + QuerySyncObject querySyncObject; + operation->SetQuery(querySyncObject); + syncTaskContext->SetSyncOperation(operation); + syncTaskContext->SetLastFullSyncTaskStatus(SyncOperation::Status::OP_FAILED); + syncTaskContext->CallSetSyncMode(static_cast(SyncModeType::QUERY_PUSH)); + EXPECT_CALL(*syncTaskContext, IsTargetQueueEmpty()).WillRepeatedly(Return(false)); + + const int loopCount = 1000; + /** + * @tc.steps: step2. loop 1000 times for writing data into lastQuerySyncTaskStatusMap_ async + */ + std::thread writeThread([&syncTaskContext]() { + for (int i = 0; i < loopCount; ++i) { + syncTaskContext->SaveLastPushTaskExecStatus(static_cast(SyncOperation::Status::OP_FAILED)); + } + }); + /** + * @tc.steps: step3. loop 100000 times for clear lastQuerySyncTaskStatusMap_ async + */ + std::thread clearThread([&syncTaskContext]() { + for (int i = 0; i < 100000; ++i) { // loop 100000 times + syncTaskContext->ResetLastPushTaskStatus(); + } + }); + /** + * @tc.steps: step4. loop 1000 times for read data from lastQuerySyncTaskStatusMap_ async + */ + std::thread readThread([&syncTaskContext]() { + for (int i = 0; i < loopCount; ++i) { + EXPECT_EQ(syncTaskContext->CallIsCurrentSyncTaskCanBeSkipped(), false); + } + }); + writeThread.join(); + clearThread.join(); + readThread.join(); + RefObject::KillAndDecObjRef(operation); + syncTaskContext->SetSyncOperation(nullptr); + RefObject::KillAndDecObjRef(syncTaskContext); +} + #ifdef RUN_AS_ROOT /** * @tc.name: TimeChangeListenerTest001 @@ -1531,9 +1653,52 @@ HWTEST_F(DistributedDBMockSyncModuleTest, TimeChangeListenerTest002, TestSize.Le */ HWTEST_F(DistributedDBMockSyncModuleTest, SyncerCheck001, TestSize.Level1) { + ASSERT_NO_FATAL_FAILURE(SyncerCheck001()); +} + +/** + * @tc.name: SyncerCheck002 + * @tc.desc: Test syncer call get timestamp with close and open. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, SyncerCheck002, TestSize.Level1) +{ + /** + * @tc.steps: step1. create context and syncer + */ std::shared_ptr syncer = std::make_shared(); - syncer->SetSyncRetry(true); + auto virtualCommunicatorAggregator = new(std::nothrow) VirtualCommunicatorAggregator(); + ASSERT_NE(virtualCommunicatorAggregator, nullptr); + auto syncDBInterface = new VirtualSingleVerSyncDBInterface(); + ASSERT_NE(syncDBInterface, nullptr); + std::vector identifier(COMM_LABEL_LENGTH, 1u); + syncDBInterface->SetIdentifier(identifier); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); + /** + * @tc.steps: step2. get timestamp by syncer over and over again + */ + std::atomic finish = false; + std::thread t([&finish, &syncer]() { + while (!finish) { + (void) syncer->GetTimestamp(); + } + }); + /** + * @tc.steps: step3. re init syncer over and over again + * @tc.expected: step3. dont crash here. + */ + for (int i = 0; i < 100; ++i) { // loop 100 times + syncer->Initialize(syncDBInterface, false); + syncer->Close(true); + } + finish = true; + t.join(); + delete syncDBInterface; syncer = nullptr; + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); + RuntimeContext::GetInstance()->StopTaskPool(); } /** @@ -1562,24 +1727,5 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SessionId001, TestSize.Level1) */ HWTEST_F(DistributedDBMockSyncModuleTest, TimeSync001, TestSize.Level1) { - auto *communicator = new(std::nothrow) MockCommunicator(); - ASSERT_NE(communicator, nullptr); - auto *storage = new(std::nothrow) VirtualSingleVerSyncDBInterface(); - ASSERT_NE(storage, nullptr); - std::shared_ptr metadata = std::make_shared(); - - EXPECT_CALL(*communicator, SendMessage(_, _, _, _)).WillRepeatedly(Return(DB_ERROR)); - const int loopCount = 100; - const int timeDriverMs = 100; - for (int i = 0; i < loopCount; ++i) { - MockTimeSync timeSync; - timeSync.Initialize(communicator, metadata, storage, "DEVICES_A"); - timeSync.ModifyTimer(timeDriverMs); - std::this_thread::sleep_for(std::chrono::milliseconds(timeDriverMs)); - timeSync.Close(); - } - std::this_thread::sleep_for(std::chrono::seconds(1)); - metadata = nullptr; - delete storage; - delete communicator; + ASSERT_NO_FATAL_FAILURE(TimeSync001()); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp index e8824554bcd8aae6ff5d32e6827e772fe648ada4..15917ba4dd2d1528f388224575a3c6c0cdccd6ac 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp @@ -878,7 +878,7 @@ HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser010, TestSize.Level1) }); /** * @tc.steps: step2. openstore1 in dual tuple sync mode - * @tc.expected: step2. it should be activity finally + * @tc.expected: step2. it should be activated finally */ OpenStore1(true); /** @@ -913,4 +913,61 @@ HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser011, TestSize.Level1) EXPECT_EQ(rdbDeletegatePtr, nullptr); CloseStore(); } +} + +/** + * @tc.name: multi user 012 + * @tc.desc: test dont check sync active when open store with normal store + * @tc.type: FUNC + * @tc.require: AR000GK58G + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser012, TestSize.Level1) +{ + uint32_t callCount = 0u; + /** + * @tc.steps: step1. set SyncActivationCheckCallback and record call count + */ + RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId, + const std::string &storeId) -> bool { + callCount++; + return true; + }); + /** + * @tc.steps: step2. openStore in no dual tuple sync mode + * @tc.expected: step2. it should be activated finally, and callCount should be zero + */ + OpenStore1(false); + EXPECT_EQ(callCount, 0u); + CloseStore(); +} + +/** + * @tc.name: multi user 013 + * @tc.desc: test dont check sync active when open store with normal store + * @tc.type: FUNC + * @tc.require: AR000GK58G + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser013, TestSize.Level1) +{ + uint32_t callCount = 0u; + /** + * @tc.steps: step1. set SyncActivationCheckCallback and record call count + */ + RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId, + const std::string &storeId) -> bool { + callCount++; + return true; + }); + /** + * @tc.steps: step2. openStore in dual tuple sync mode + * @tc.expected: step2. it should not be activated finally, and callCount should be 2 + */ + OpenStore1(true); + EXPECT_EQ(callCount, 2u); + callCount = 0u; + EXPECT_EQ(g_rdbDelegatePtr1->RemoveDeviceData("DEVICE"), OK); + EXPECT_EQ(callCount, 0u); + CloseStore(); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index 1ab5d57cc6009a585589dc315aa80d14cdc4ff8f..83f4342b2d8e8f076342717e381537913833e50a 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -1082,6 +1082,7 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync008, TestSize.Level0) std::vector targetData; g_deviceB->GetAllSyncData(g_tableName, targetData); ASSERT_EQ(targetData.size(), 0u); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp index 515150a2a4fae97d126a1beb9494f770af15475c..3676e58e5fc1807252e6e577d0cb73287df52364 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp @@ -795,7 +795,7 @@ HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser011, TestSize.Level1) }); /** * @tc.steps: step2. openstore1 in dual tuple sync mode - * @tc.expected: step2. it should be activity finally + * @tc.expected: step2. it should be activated finally */ OpenStore1(true); /** @@ -843,4 +843,61 @@ HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser012, TestSize.Level1) std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_3_SECONDS)); subThread.join(); CloseStore(); +} + +/** + * @tc.name: MultiUser013 + * @tc.desc: test dont check sync active when open store with normal store + * @tc.type: FUNC + * @tc.require: AR000E8S2T + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser013, TestSize.Level1) +{ + uint32_t callCount = 0u; + /** + * @tc.steps: step1. set SyncActivationCheckCallback and record call count + */ + KvStoreDelegateManager::SetSyncActivationCheckCallback( + [&callCount] (const std::string &userId, const std::string &appId, const std::string &storeId) -> bool { + callCount++; + return true; + }); + /** + * @tc.steps: step2. openStore in no dual tuple sync mode + * @tc.expected: step2. it should be activated finally, and callCount should be zero + */ + OpenStore1(false); + EXPECT_EQ(callCount, 0u); + CloseStore(); +} + +/** + * @tc.name: MultiUser014 + * @tc.desc: test active callback call count + * @tc.type: FUNC + * @tc.require: AR000E8S2T + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser014, TestSize.Level1) +{ + uint32_t callCount = 0u; + /** + * @tc.steps: step1. set SyncActivationCheckCallback and record call count + */ + KvStoreDelegateManager::SetSyncActivationCheckCallback( + [&callCount] (const std::string &userId, const std::string &appId, const std::string &storeId) -> bool { + callCount++; + return false; + }); + /** + * @tc.steps: step2. openStore in dual tuple sync mode + * @tc.expected: step2. it should not be activated finally, and callCount should be 2 + */ + OpenStore1(true); + EXPECT_EQ(callCount, 2u); // 2 is call count + callCount = 0u; + EXPECT_EQ(g_kvDelegatePtr1->RemoveDeviceData(), OK); + EXPECT_EQ(callCount, 0u); + CloseStore(); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp index dfa5b3c64e1ab1e0b97ddb63dfa896941ec1b6eb..a27d48401abb88667a4d29d5d8804582bb725067 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp @@ -125,6 +125,49 @@ namespace { EXPECT_TRUE(resultvalue == value); } } + + void DataSync005() + { + SingleVerDataSync *dataSync = new (std::nothrow) SingleVerDataSync(); + ASSERT_TRUE(dataSync != nullptr); + dataSync->SendSaveDataNotifyPacket(nullptr, 0, 0, 0, TIME_SYNC_MESSAGE); + delete dataSync; + } + + void DataSync008() + { + SingleVerDataSync *dataSync = new (std::nothrow) SingleVerDataSync(); + ASSERT_TRUE(dataSync != nullptr); + dataSync->PutDataMsg(nullptr); + delete dataSync; + } + + void ReSetWaterDogTest001() + { + /** + * @tc.steps: step1. put 10 key/value + * @tc.expected: step1, put return OK. + */ + for (int i = 0; i < 5; i++) { // put 5 key + Key key = DistributedDBToolsUnitTest::GetRandPrefixKey({'a', 'b'}, 1024); // rand num 1024 for test + Value value; + DistributedDBToolsUnitTest::GetRandomKeyValue(value, 10 * 50 * 1024u); // 10 * 50 * 1024 = 500k + EXPECT_EQ(g_kvDelegatePtr->Put(key, value), OK); + } + /** + * @tc.steps: step2. SetDeviceMtuSize + * @tc.expected: step2, return OK. + */ + g_communicatorAggregator->SetDeviceMtuSize(DEVICE_A, 50 * 1024u); // 50 * 1024u = 50k + g_communicatorAggregator->SetDeviceMtuSize(DEVICE_B, 50 * 1024u); // 50 * 1024u = 50k + /** + * @tc.steps: step3. deviceA,deviceB sync to each other at same time + * @tc.expected: step3. sync should return OK. + */ + g_deviceB->Sync(DistributedDB::SYNC_MODE_PULL_ONLY, true); + g_communicatorAggregator->SetDeviceMtuSize(DEVICE_A, 5 * 1024u * 1024u); // 5 * 1024u * 1024u = 5m + g_communicatorAggregator->SetDeviceMtuSize(DEVICE_B, 5 * 1024u * 1024u); // 5 * 1024u * 1024u = 5m + } } class DistributedDBSingleVerP2PComplexSyncTest : public testing::Test { @@ -977,10 +1020,7 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DataSync004, TestSize.Level1) */ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DataSync005, TestSize.Level1) { - SingleVerDataSync *dataSync = new (std::nothrow) SingleVerDataSync(); - ASSERT_TRUE(dataSync != nullptr); - dataSync->SendSaveDataNotifyPacket(nullptr, 0, 0, 0, TIME_SYNC_MESSAGE); - delete dataSync; + ASSERT_NO_FATAL_FAILURE(DataSync005()); } /** @@ -1040,10 +1080,7 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DataSync007, TestSize.Level1) */ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DataSync008, TestSize.Level1) { - SingleVerDataSync *dataSync = new (std::nothrow) SingleVerDataSync(); - ASSERT_TRUE(dataSync != nullptr); - dataSync->PutDataMsg(nullptr); - delete dataSync; + ASSERT_NO_FATAL_FAILURE(DataSync008()); } /** @@ -1240,37 +1277,68 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, SyncRetry004, TestSize.Level3 } /** - * @tc.name: ReSetWatchDogTest001 - * @tc.desc: trigger resetWatchDog while pull + * @tc.name: SyncRetry005 + * @tc.desc: use sync retry sync use pull by compress * @tc.type: FUNC * @tc.require: AR000CKRTD AR000CQE0E - * @tc.author: zhuwentao + * @tc.author: zhangqiquan */ -HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, ReSetWaterDogTest001, TestSize.Level3) +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, SyncRetry005, TestSize.Level3) { + if (g_kvDelegatePtr != nullptr) { + ASSERT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK); + g_kvDelegatePtr = nullptr; + } /** - * @tc.steps: step1. put 10 key/value - * @tc.expected: step1, put return OK. + * @tc.steps: step1. open db use Compress + * @tc.expected: step1, Pragma return OK. */ - for (int i = 0; i < 5; i++) { - Key key = DistributedDBToolsUnitTest::GetRandPrefixKey({'a', 'b'}, 1024); // rand num 1024 for test - Value value; - DistributedDBToolsUnitTest::GetRandomKeyValue(value, 10 * 50 * 1024u); - EXPECT_EQ(g_kvDelegatePtr->Put(key, value), OK); - } + KvStoreNbDelegate::Option option; + option.isNeedCompressOnSync = true; + g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback); + ASSERT_TRUE(g_kvDelegateStatus == OK); + ASSERT_TRUE(g_kvDelegatePtr != nullptr); + + g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, DATA_SYNC_MESSAGE); + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + /** - * @tc.steps: step1. SetDeviceMtuSize - * @tc.expected: step1, return OK. + * @tc.steps: step2. set sync retry + * @tc.expected: step2, Pragma return OK. */ - g_communicatorAggregator->SetDeviceMtuSize(DEVICE_A, 50 * 1024u); // 4k - g_communicatorAggregator->SetDeviceMtuSize(DEVICE_B, 50 * 1024u); // 4k + int pragmaData = 1; + PragmaData input = static_cast(&pragmaData); + EXPECT_TRUE(g_kvDelegatePtr->Pragma(SET_SYNC_RETRY, input) == OK); + /** - * @tc.steps: step2. deviceA,deviceB sync to each other at same time - * @tc.expected: step2. sync should return OK. + * @tc.steps: step3. deviceA call sync and wait + * @tc.expected: step3. sync should return OK. + */ + std::map result; + ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result) == OK); + + /** + * @tc.expected: step4. onComplete should be called, and status is time_out */ - g_deviceB->Sync(DistributedDB::SYNC_MODE_PULL_ONLY, true); - g_communicatorAggregator->SetDeviceMtuSize(DEVICE_A, 5 * 1024u * 1024u); // 4k - g_communicatorAggregator->SetDeviceMtuSize(DEVICE_B, 5 * 1024u * 1024u); // 4k + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_EQ(pair.second, OK); + } + g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, UNKNOW_MESSAGE); +} + +/** + * @tc.name: ReSetWatchDogTest001 + * @tc.desc: trigger resetWatchDog while pull + * @tc.type: FUNC + * @tc.require: AR000CKRTD AR000CQE0E + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, ReSetWaterDogTest001, TestSize.Level3) +{ + ASSERT_NO_FATAL_FAILURE(ReSetWaterDogTest001()); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp index 36e4121669ee1aa8e44160643bdaddbdc2aa9cf8..4a928773d3532eb01293bc4996faf87b20a04252 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp @@ -895,6 +895,78 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, GetQueryWaterMark002, TestSize. EXPECT_EQ(w1, w); } +/** + * @tc.name: GetQueryWaterMark 003 + * @tc.desc: check time offset after remove water mark + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, GetQueryWaterMark003, TestSize.Level1) +{ + VirtualSingleVerSyncDBInterface storage; + Metadata meta; + + int errCode = meta.Initialize(&storage); + ASSERT_EQ(errCode, E_OK); + + const std::string DEVICE_B = "DEVICE_B"; + TimeOffset offset = 100; // 100: offset + meta.SaveTimeOffset(DEVICE_B, offset); + + WaterMark w1 = 2; // 2: watermark + meta.SavePeerWaterMark(DBCommon::TransferHashString(DEVICE_B), w1, false); + + TimeOffset offsetGot; + meta.GetTimeOffset(DEVICE_B, offsetGot); + EXPECT_EQ(offsetGot, offset); +} + +/** + * @tc.name: GetDeleteWaterMark001 + * @tc.desc: Test metaData save and get deleteWaterMark. + * @tc.type: FUNC + * @tc.require: AR000FN6G9 + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, GetDeleteWaterMark001, TestSize.Level1) +{ + VirtualSingleVerSyncDBInterface storage; + Metadata meta; + + /** + * @tc.steps: step1. initialize meta with storage + * @tc.expected: step1. E_OK + */ + int errCode = meta.Initialize(&storage); + ASSERT_EQ(errCode, E_OK); + + /** + * @tc.steps: step2. set and get recv/send delete watermark + * @tc.expected: step2. set E_OK and get water mark is equal with last set + */ + const std::string device = "DEVICE"; + const WaterMark maxWaterMark = 1000u; + std::thread recvThread([&meta, &device, &maxWaterMark]() { + for (WaterMark expectRecv = 0u; expectRecv < maxWaterMark; ++expectRecv) { + EXPECT_EQ(meta.SetRecvDeleteSyncWaterMark(device, expectRecv), E_OK); + WaterMark actualRecv = 0u; + EXPECT_EQ(meta.GetRecvDeleteSyncWaterMark(device, actualRecv), E_OK); + EXPECT_EQ(actualRecv, expectRecv); + } + }); + std::thread sendThread([&meta, &device, &maxWaterMark]() { + for (WaterMark expectSend = 0u; expectSend < maxWaterMark; ++expectSend) { + EXPECT_EQ(meta.SetSendDeleteSyncWaterMark(device, expectSend), E_OK); + WaterMark actualSend = 0u; + EXPECT_EQ(meta.GetSendDeleteSyncWaterMark(device, actualSend), E_OK); + EXPECT_EQ(actualSend, expectSend); + } + }); + recvThread.join(); + sendThread.join(); +} + /** * @tc.name: ClearQueryWaterMark 001 * @tc.desc: Test metaData clear watermark function. @@ -1830,31 +1902,4 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, AllPredicateQuerySync004, TestS EXPECT_TRUE(item == value); key.pop_back(); } -} - -/** - * @tc.name: GetQueryWaterMark 003 - * @tc.desc: check time offset after remove water mark - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, GetQueryWaterMark003, TestSize.Level1) -{ - VirtualSingleVerSyncDBInterface storage; - Metadata meta; - - int errCode = meta.Initialize(&storage); - ASSERT_EQ(errCode, E_OK); - - const std::string DEVICE_B = "DEVICE_B"; - TimeOffset offset = 100; // 100: offset - meta.SaveTimeOffset(DEVICE_B, offset); - - WaterMark w1 = 2; // 2: watermark - meta.SavePeerWaterMark(DBCommon::TransferHashString(DEVICE_B), w1, false); - - TimeOffset offsetGot; - meta.GetTimeOffset(DEVICE_B, offsetGot); - EXPECT_EQ(offsetGot, offset); -} +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp index cd6eb2ec51fb59adf34028993c4edd1db7dcc8a0..e45adfdd7f0ce9080e66498d2c6415778da74f79 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp @@ -349,7 +349,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, ControlAckTest001, TestSize * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager001, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager001, TestSize.Level1) { SubscribeManager subManager; std::string device = "device_A"; @@ -420,7 +420,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager001, TestSi * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager002, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager002, TestSize.Level1) { SubscribeManager subManager; std::string device = "device_A"; @@ -476,7 +476,7 @@ ASSERT_TRUE(subscribeQueryId.size() == 4); * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager003, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager003, TestSize.Level1) { SubscribeManager subManager; std::string device = "device_"; @@ -526,7 +526,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager003, TestSi * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager004, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager004, TestSize.Level1) { SubscribeManager subManager; std::string device = "device_"; @@ -577,7 +577,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager004, TestSi * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager005, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager005, TestSize.Level1) { SubscribeManager subManager; std::vector subscribeQueries; @@ -647,7 +647,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager005, TestSi * @tc.require: * @tc.author: zhangshijie */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager006, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeManager006, TestSize.Level1) { /** * @tc.steps: step1. active a query sync object which is not in local subscribe map @@ -711,7 +711,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeManager006, TestSi * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync001, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync001, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -776,7 +776,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync001, TestSize. * @tc.require: AR000FN6G9 * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync002, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync002, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -820,7 +820,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync002, TestSize. * @tc.require: AR000GOHO7 * @tc.author: lidongwei */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync003, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync003, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -829,6 +829,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync003, TestSize. InitSubSchemaDb(); std::vector devices; devices.push_back(g_deviceB->GetDeviceId()); + g_deviceB->Online(); /** * @tc.steps: step2. deviceB subscribe inkeys(k2k4) query to deviceA diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h index 39dbab055e441b9f84aa0479b73839d6388b8763..9cb58cc816e453832f7a77420e17ed8d88a22359 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h @@ -92,6 +92,11 @@ public: } return SingleVerKvSyncTaskContext::GetDeviceId(); } + + void SetSyncOperation(SyncOperation *operation) + { + syncOperation_ = operation; + } private: std::function forkGetDeviceIdFunc_; }; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp index 778b08f98f0cc000adcba814eedc981d24e8d48a..9ef22110b6b54a3d3d31a8b1ccd73e05628a04b1 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp @@ -138,6 +138,11 @@ int VirtualSingleVerSyncDBInterface::GetSyncDataNext(std::vector &data void VirtualSingleVerSyncDBInterface::ReleaseContinueToken(ContinueToken& continueStmtToken) const { + VirtualContinueToken *token = static_cast(continueStmtToken); + if (token != nullptr) { + delete token; + continueStmtToken = nullptr; + } return; } @@ -553,12 +558,12 @@ bool VirtualSingleVerSyncDBInterface::GetDataInner(Timestamp begin, Timestamp en { bool isFinished = true; for (const auto &data : dbData_) { - if (dataItems.size() >= dataSizeInfo.packetSize) { - LOGD("virtual device dataItem size reach to packetSize=%u", dataSizeInfo.packetSize); - isFinished = false; - break; - } if (data.isLocal) { + if (dataItems.size() >= dataSizeInfo.packetSize) { + LOGD("virtual device dataItem size reach to packetSize=%u", dataSizeInfo.packetSize); + isFinished = false; + break; + } if (data.writeTimestamp >= begin && data.writeTimestamp < end) { dataItems.push_back(data); currentWaterMark = data.writeTimestamp; diff --git a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn index cfc75bdbdef6c77e93571f133eee87f993234eca..b78a26d2ab000fda1b0e4dbdd7638872dd0e1323 100644 --- a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn +++ b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn @@ -47,7 +47,6 @@ config("distributeddatafwk_public_config") { include_dirs = [ "include", "../../../frameworks/innerkitsimpl/distributeddatafwk/include", - "//commonlibrary/c_utils/base/include", ] } @@ -99,7 +98,7 @@ external_deps_config = [ "hitrace_native:libhitracechain", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", - "ipc:ipc_core", + "ipc:ipc_single", "samgr:samgr_proxy", ] diff --git a/kv_store/interfaces/innerkits/distributeddata/include/blob.h b/kv_store/interfaces/innerkits/distributeddata/include/blob.h index 88d4fff6f23a7320a2de4c1b7251c2debccf6cb5..b7a59494d2b800ead0585137d94ca4f4965ec424 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/blob.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/blob.h @@ -25,26 +25,44 @@ namespace DistributedKv { class Blob { public: + /** + * @brief Constructor. + */ API_EXPORT Blob(); + /** + * @brief Destructor. + */ API_EXPORT ~Blob() = default; /** * @brief Copy constructor for Blob. */ API_EXPORT Blob(const Blob &blob); + + /** + * @brief Operator =. + */ API_EXPORT Blob &operator=(const Blob &blob); /** * @brief Move constructor for Blob. */ API_EXPORT Blob(Blob &&blob); + + /** + * @brief Operator =. + */ API_EXPORT Blob &operator=(Blob &&blob); /** * @brief Construct a Blob use std::string. */ API_EXPORT Blob(const std::string &str); + + /** + * @brief Operator =. + */ API_EXPORT Blob &operator=(const std::string &str); /** @@ -56,6 +74,10 @@ public: * @brief Construct a Blob use char pointer. */ API_EXPORT Blob(const char *str); + + /** + * @brief Operator =. + */ API_EXPORT Blob &operator=(const char *str); /** @@ -73,8 +95,14 @@ public: */ API_EXPORT const std::vector &Data() const; + /** + * @brief Return std::vector &. + */ API_EXPORT operator const std::vector &() const; + /** + * @brief Return std::vector &&. + */ API_EXPORT operator std::vector &&() noexcept; /** @@ -102,6 +130,9 @@ public: */ API_EXPORT uint8_t operator[](size_t n) const; + /** + * @brief Operator ==. + */ API_EXPORT bool operator==(const Blob &) const; /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/change_notification.h b/kv_store/interfaces/innerkits/distributeddata/include/change_notification.h index d4cc84a911f2f6342e26ed97defa0fd5fb88100b..c6bc3df1d50b52fb744365f8b2f8628ec1001102 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/change_notification.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/change_notification.h @@ -34,6 +34,9 @@ public: API_EXPORT ChangeNotification(std::vector &&insertEntries, std::vector &&updateEntries, std::vector &&deleteEntries, const std::string &deviceId, bool isClear); + /** + * @brief Destructor. + */ API_EXPORT ~ChangeNotification(); /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/data_query.h b/kv_store/interfaces/innerkits/distributeddata/include/data_query.h index dc70626ec2fc2ac466f2b28a6edc0045d067532b..5daafcc939c8b3d5c994014b89cb11e97c9bd24a 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/data_query.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/data_query.h @@ -28,8 +28,14 @@ namespace OHOS { namespace DistributedKv { class API_EXPORT DataQuery { public: + /** + * @brief Constructor. + */ DataQuery(); + /** + * @brief Destructor. + */ ~DataQuery() = default; /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h b/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h index 016a079afd8ee7181fb8742fb27def6b900f188a..d87a7a2dfb2dded88fcdbf5d496d40b986a0fbec 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h @@ -27,8 +27,14 @@ namespace OHOS { namespace DistributedKv { class API_EXPORT DistributedKvDataManager final { public: + /** + * @brief Constructor. + */ API_EXPORT DistributedKvDataManager(); + /** + * @brief Destructor. + */ API_EXPORT ~DistributedKvDataManager(); /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/kvstore.h b/kv_store/interfaces/innerkits/distributeddata/include/kvstore.h index 420461949bbd40693a5a420ac61eadfb5e626337..0e2e41b531d498a400206c60a6cf543ae0579fa1 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/kvstore.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/kvstore.h @@ -24,12 +24,24 @@ namespace OHOS { namespace DistributedKv { class API_EXPORT KvStore { public: + /** + * @brief Constructor. + */ API_EXPORT KvStore() = default; - // forbidden copy constructor. + /** + * @brief Forbidden copy constructor. + */ KvStore(const KvStore &) = delete; + + /** + * @brief Forbidden copy constructor. + */ KvStore &operator=(const KvStore &) = delete; + /** + * @brief Destructor. + */ API_EXPORT virtual ~KvStore() {} /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_observer.h b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_observer.h index 5cec165cdbc47e2e7b16c6a5d8babc2c30a7a1fb..f50754d775d12e114e86d7b8b55d31c9c5b6a7c4 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_observer.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_observer.h @@ -24,8 +24,14 @@ namespace DistributedKv { // client implement this class to watch kvstore change. class API_EXPORT KvStoreObserver { public: + /** + * @brief Constructor. + */ API_EXPORT KvStoreObserver() = default; + /** + * @brief Destructor. + */ API_EXPORT virtual ~KvStoreObserver() {} /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_result_set.h b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_result_set.h index 8965c7e56ee3a296f3e719db48e600beebabff49..42723c94d19bd2ca909c750ede77b8bdc3ade04d 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_result_set.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_result_set.h @@ -24,6 +24,10 @@ class KvStoreResultSet { public: inline static constexpr int INVALID_COUNT = -ALREADY_CLOSED; inline static constexpr int INVALID_POSITION = -ALREADY_CLOSED; + + /** + * @brief Destructor. + */ API_EXPORT virtual ~KvStoreResultSet() {} /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_sync_callback.h b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_sync_callback.h index 5820482a706cb01659a086b5f3ccdc4db515eb3d..3558026efc47994e3395bfb206184689296e7c27 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/kvstore_sync_callback.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/kvstore_sync_callback.h @@ -24,8 +24,14 @@ namespace DistributedKv { // client implement this class to watch kvstore change. class KvStoreSyncCallback { public: + /** + * @brief Constructor. + */ API_EXPORT KvStoreSyncCallback() = default; + /** + * @brief Destructor. + */ API_EXPORT virtual ~KvStoreSyncCallback() {} /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h b/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h index 3dfa8c008400781efe4de82bd89e6c513a01c407..41d2e31771ffc00893a584d88a79e52383e52e80 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h @@ -30,8 +30,14 @@ namespace DistributedKv { // This class provides put, delete, search, sync and subscribe functions of a key-value store. class API_EXPORT SingleKvStore : public virtual KvStore { public: + /** + * @brief Constructor. + */ API_EXPORT SingleKvStore() = default; + /** + * @brief Destructor. + */ API_EXPORT virtual ~SingleKvStore() {} /** diff --git a/kv_store/interfaces/innerkits/distributeddata/include/types.h b/kv_store/interfaces/innerkits/distributeddata/include/types.h index 467ca2ac0361c44cc8677c9ba06aff0a3368081e..85819700d285291f44ec2e7e9c4fd17f91b5466b 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/types.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/types.h @@ -66,6 +66,9 @@ struct API_EXPORT AppId { return appId; } + /** + * @brief Check appId. + */ inline bool IsValid() const { if (appId.empty() || appId.size() > MAX_APP_ID_LEN) { @@ -111,11 +114,17 @@ struct API_EXPORT StoreId { return storeId; } + /** + * @brief Operator <. + */ bool operator<(const StoreId &id) const noexcept { return this->storeId < id.storeId; } + /** + * @brief Check storeId. + */ inline bool IsValid() const { if (storeId.empty() || storeId.size() > MAX_STORE_ID_LEN) { diff --git a/kv_store/test/fuzztest/typesutil_fuzzer/BUILD.gn b/kv_store/test/fuzztest/typesutil_fuzzer/BUILD.gn index 7298912cd9d237f44ae553cd7a95f2202a5a98a6..77818a65f3add11f07fb806f915094957937228e 100644 --- a/kv_store/test/fuzztest/typesutil_fuzzer/BUILD.gn +++ b/kv_store/test/fuzztest/typesutil_fuzzer/BUILD.gn @@ -49,7 +49,7 @@ ohos_fuzztest("TypesUtilFuzzTest") { external_deps = [ "c_utils:utils", "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", + "ipc:ipc_single", "kv_store:distributeddata_inner", ] } diff --git a/mock/include/CMakeLists.txt b/mock/include/CMakeLists.txt index efa79ace793c0602b782b7499820c6d635d6c36d..4041c7a0a6200e9d304ef1b5a477609ed6138115 100644 --- a/mock/include/CMakeLists.txt +++ b/mock/include/CMakeLists.txt @@ -101,7 +101,7 @@ include_directories(${MOCK_DIR}/innerkits/napi/ace_napi/include/napi) include_directories(${MOCK_DIR}/innerkits/device_profile_core/distributed_device_profile_client/include) include_directories(${MOCK_DIR}/innerkits/hiview/libfaultlogger/include) include_directories(${MOCK_DIR}/innerkits/syscap_codec/syscap_interface_shared/include) -include_directories(${MOCK_DIR}/innerkits/ipc/ipc_single/include) +#include_directories(${MOCK_DIR}/innerkits/ipc/ipc_single/include) include_directories(${MOCK_DIR}/innerkits/ipc/ipc_core/include) include_directories(${MOCK_DIR}/innerkits/ipc/libdbinder/include) include_directories(${MOCK_DIR}/innerkits/i18n/zone_util/include) diff --git a/mock/innerkits/bundle_framework/appexecfwk_base/include/ability_info.h b/mock/innerkits/bundle_framework/appexecfwk_base/include/ability_info.h index eb1c98d501fb063c02eb2589d87b04599797a04e..23bbbf613f293a411ca2ee8b070c659419c2f0bc 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_base/include/ability_info.h +++ b/mock/innerkits/bundle_framework/appexecfwk_base/include/ability_info.h @@ -33,6 +33,15 @@ enum AbilityInfoFlag { GET_ABILITY_INFO_WITH_DISABLE = 0x00000100, }; +enum class GetAbilityInfoFlag { + GET_ABILITY_INFO_DEFAULT = 0x00000000, + GET_ABILITY_INFO_WITH_PERMISSION = 0x00000001, + GET_ABILITY_INFO_WITH_APPLICATION = 0x00000002, + GET_ABILITY_INFO_WITH_METADATA = 0x00000004, + GET_ABILITY_INFO_WITH_DISABLE = 0x00000008, + GET_ABILITY_INFO_ONLY_SYSTEM_APP = 0x00000010, +}; + enum class AbilityType { UNKNOWN = 0, PAGE, @@ -79,15 +88,9 @@ enum class DisplayOrientation { enum class LaunchMode { SINGLETON = 0, STANDARD, // support more than one instance - SINGLETOP, SPECIFIED, }; -enum class CompileMode { - JS_BUNDLE = 0, - ES_MODULE, -}; - enum class SupportWindowMode { FULLSCREEN = 0, SPLIT, @@ -159,7 +162,6 @@ struct CompatibleAbilityInfo : public Parcelable { virtual bool Marshalling(Parcel& parcel) const override; static CompatibleAbilityInfo* Unmarshalling(Parcel& parcel); - void CopyToDest(CompatibleAbilityInfo& dest) const; void ConvertToAbilityInfo(AbilityInfo& abilityInfo) const; }; @@ -214,6 +216,7 @@ struct AbilityInfo : public Parcelable { std::string codePath; // ability main code path with name std::string resourcePath; // resource path for resource init + std::string hapPath; std::string srcEntrance; std::vector metadata; @@ -229,6 +232,8 @@ struct AbilityInfo : public Parcelable { int32_t startWindowBackgroundId; // whether to display in the missions list bool excludeFromMissions = false; + // whether to support recover UI interface + bool recoverable = false; // support windows mode std::vector windowModes; @@ -238,6 +243,9 @@ struct AbilityInfo : public Parcelable { uint32_t minWindowWidth = 0; uint32_t maxWindowHeight = 0; uint32_t minWindowHeight = 0; + // for NAPI, save self query cache + int32_t uid = -1; + CompileMode compileMode = CompileMode::JS_BUNDLE; // unused std::string originalBundleName; @@ -257,7 +265,6 @@ struct AbilityInfo : public Parcelable { AbilitySubType subType = AbilitySubType::UNSPECIFIED; std::string libPath; std::string deviceId; - CompileMode compileMode = CompileMode::JS_BUNDLE; bool ReadFromParcel(Parcel &parcel); virtual bool Marshalling(Parcel &parcel) const override; diff --git a/mock/innerkits/bundle_framework/appexecfwk_base/include/appexecfwk_errors.h b/mock/innerkits/bundle_framework/appexecfwk_base/include/appexecfwk_errors.h index 0b6094e723ab7ef80877a6472fb079d909f1b869..586e5a1e2f969873cc33f13e676f659545a65839 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_base/include/appexecfwk_errors.h +++ b/mock/innerkits/bundle_framework/appexecfwk_base/include/appexecfwk_errors.h @@ -38,6 +38,7 @@ enum { ERR_APPEXECFWK_PARCEL_ERROR, ERR_APPEXECFWK_FAILED_SERVICE_DIED, ERR_APPEXECFWK_OPERATION_TIME_OUT, + ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR, }; // Error code for AppMgr @@ -95,6 +96,19 @@ enum { ERR_APPEXECFWK_INSTALL_TYPE_ERROR, ERR_APPEXECFWK_INSTALL_SDK_INCOMPATIBLE, ERR_APPEXECFWK_INSTALL_SO_INCOMPATIBLE, + ERR_APPEXECFWK_INSTALL_AN_INCOMPATIBLE, + ERR_APPEXECFWK_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME, + ERR_APPEXECFWK_INSTALL_INCONSISTENT_MODULE_NAME, + ERR_APPEXECFWK_INSTALL_SINGLETON_INCOMPATIBLE, + ERR_APPEXECFWK_INSTALL_DEVICE_TYPE_NOT_SUPPORTED, + ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED, + ERR_APPEXECFWK_INSTALL_DEPENDENT_MODULE_NOT_EXIST, + ERR_APPEXECFWK_INSTALL_ASAN_ENABLED_NOT_SAME, + ERR_APPEXECFWK_INSTALL_ASAN_NOT_SUPPORT, + ERR_APPEXECFWK_BUNDLE_TYPE_NOT_SAME, + ERR_APPEXECFWK_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, + ERR_APPEXECFWK_INSTALL_COMPATIBLE_POLICY_NOT_SAME, + ERR_APPEXECFWK_INSTALL_FILE_IS_SHARED_LIBRARY, // signature errcode ERR_APPEXECFWK_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH = 8519740, @@ -130,6 +144,8 @@ enum { ERR_APPEXECFWK_SANDBOX_INSTALL_NO_SANDBOX_APP_INFO, ERR_APPEXECFWK_SANDBOX_INSTALL_UNKNOWN_INSTALL_TYPE, ERR_APPEXECFWK_SANDBOX_INSTALL_DELETE_APP_INDEX_FAILED, + ERR_APPEXECFWK_SANDBOX_APP_NOT_SUPPORTED, + ERR_APPEXECFWK_SANDBOX_INSTALL_GET_PERMISSIONS_FAILED, // sandbox app query ERR_APPEXECFWK_SANDBOX_QUERY_PARAM_ERROR, @@ -148,7 +164,10 @@ enum { ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP, ERR_APPEXECFWK_PARSE_PERMISSION_ERROR, ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR, + ERR_APPEXECFWK_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR, ERR_APPEXECFWK_PARSE_RPCID_FAILED, + ERR_APPEXECFWK_PARSE_NATIVE_SO_FAILED, + ERR_APPEXECFWK_PARSE_AN_FAILED, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR, ERR_APPEXECFWK_INSTALLD_GET_PROXY_ERROR, @@ -162,6 +181,7 @@ enum { ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED, ERR_APPEXECFWK_INSTALLD_COPY_FILE_FAILED, ERR_APPEXECFWK_INSTALLD_MKDIR_FAILED, + ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED, ERR_APPEXECFWK_UNINSTALL_SYSTEM_APP_ERROR, ERR_APPEXECFWK_UNINSTALL_KILLING_APP_ERROR, @@ -171,6 +191,9 @@ enum { ERR_APPEXECFWK_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR, ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_BUNDLE, ERR_APPEXECFWK_UNINSTALL_MISSING_INSTALLED_MODULE, + ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST, + ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED, + ERR_APPEXECFWK_UNINSTALL_BUNDLE_IS_SHARED_LIBRARY, ERR_APPEXECFWK_FAILED_GET_INSTALLER_PROXY, ERR_APPEXECFWK_FAILED_GET_BUNDLE_INFO, @@ -178,17 +201,142 @@ enum { ERR_APPEXECFWK_FAILED_GET_RESOURCEMANAGER, ERR_APPEXECFWK_FAILED_GET_REMOTE_PROXY, ERR_APPEXECFWK_PERMISSION_DENIED, + ERR_APPEXECFWK_INPUT_WRONG_TYPE_FILE, + ERR_APPEXECFWK_ENCODE_BASE64_FILE_FAILED, ERR_APPEXECFWK_RECOVER_GET_BUNDLEPATH_ERROR = APPEXECFWK_BUNDLEMGR_ERR_OFFSET + 0x0201, // 8520193 ERR_APPEXECFWK_RECOVER_INVALID_BUNDLE_NAME, + ERR_APPEXECFWK_RECOVER_NOT_ALLOWED, ERR_APPEXECFWK_USER_NOT_EXIST = APPEXECFWK_BUNDLEMGR_ERR_OFFSET + 0x0301, - ERR_APPEXECFWK_USER_CREATE_FALIED, - ERR_APPEXECFWK_USER_REMOVE_FALIED, + ERR_APPEXECFWK_USER_CREATE_FAILED, + ERR_APPEXECFWK_USER_REMOVE_FAILED, ERR_APPEXECFWK_USER_NOT_INSTALL_HAP, // error code in prebundle sacn - ERR_APPEXECFWK_PARSE_FILE_FAILED + ERR_APPEXECFWK_PARSE_FILE_FAILED, + + // debug mode + ERR_BUNDLEMANAGER_SET_DEBUG_MODE_INTERNAL_ERROR, + ERR_BUNDLEMANAGER_SET_DEBUG_MODE_PARCEL_ERROR, + ERR_BUNDLEMANAGER_SET_DEBUG_MODE_SEND_REQUEST_ERROR, + ERR_BUNDLEMANAGER_SET_DEBUG_MODE_UID_CHECK_FAILED, + ERR_BUNDLEMANAGER_SET_DEBUG_MODE_INVALID_PARAM, + + // overlay installation errcode + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR = 8520600, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_EXTERNAL_OVERLAY_EXISTED_SIMULTANEOUSLY, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_OVERLAY_TYPE_NOT_SAME, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_NOT_STAGE_MODULE, + ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_SERVICE, + + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_PARAM_ERROR, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_BUNDLE, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_MODULE, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_BUNDLE, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_MODULE, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_BUNDLE_NOT_EXISTED, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_MODULE_NOT_EXISTED, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NO_OVERLAY_BUNDLE_INFO, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NO_OVERLAY_MODULE_INFO, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_PERMISSION_DENIED, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE, + ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE, + ERR_BUNDLEMANAGER_OVERLAY_SET_OVERLAY_PARAM_ERROR, + + // quick fix errcode + ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR = APPEXECFWK_BUNDLEMGR_ERR_OFFSET + 0x0401, // 8520705 + ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR, + ERR_BUNDLEMANAGER_QUICK_FIX_PROFILE_PARSE_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_BUNDLE_NAME_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_VERSION_CODE_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_VERSION_NAME_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_PATCH_VERSION_CODE_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_PATCH_VERSION_NAME_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_PATCH_TYPE_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_MODULE_NAME_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_UNKNOWN_QUICK_FIX_TYPE, + ERR_BUNDLEMANAGER_QUICK_FIX_SO_INCOMPATIBLE, + ERR_BUNDLEMANAGER_QUICK_FIX_BUNDLE_NAME_NOT_EXIST, + ERR_BUNDLEMANAGER_QUICK_FIX_MODULE_NAME_NOT_EXIST, + ERR_BUNDLEMANAGER_QUICK_FIX_SIGNATURE_INFO_NOT_SAME, + ERR_BUNDLEMANAGER_QUICK_FIX_ADD_HQF_FAILED, // 8520720 + ERR_BUNDLEMANAGER_QUICK_FIX_SAVE_APP_QUICK_FIX_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_VERSION_CODE_ERROR, + ERR_BUNDLEMANAGER_QUICK_FIX_EXTRACT_DIFF_FILES_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_APPLY_DIFF_PATCH_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_NO_PATCH_IN_DATABASE, + ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATCH_STATUS, + ERR_BUNDLEMANAGER_QUICK_FIX_NOT_EXISTED_BUNDLE_INFO, + ERR_BUNDLEMANAGER_QUICK_FIX_REMOVE_PATCH_PATH_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_CREATE_PATCH_PATH_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_MOVE_PATCH_FILE_FAILED, // 8520730 + ERR_BUNDLEMANAGER_QUICK_FIX_HOT_RELOAD_NOT_SUPPORT_RELEASE_BUNDLE, + ERR_BUNDLEMANAGER_QUICK_FIX_PATCH_ALREADY_EXISTED, + ERR_BUNDLEMANAGER_QUICK_FIX_HOT_RELOAD_ALREADY_EXISTED, + ERR_BUNDLEMANAGER_QUICK_FIX_NO_PATCH_INFO_IN_BUNDLE_INFO, + ERR_BUNDLEMANAGER_QUICK_FIX_OLD_PATCH_OR_HOT_RELOAD_IN_DB, + ERR_BUNDLEMANAGER_QUICK_FIX_SEND_REQUEST_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_REAL_PATH_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATH, + ERR_BUNDLEMANAGER_QUICK_FIX_OPEN_SOURCE_FILE_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_CREATE_FD_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_TARGET_DIR, + ERR_BUNDLEMANAGER_QUICK_FIX_CREATE_TARGET_DIR_FAILED, + ERR_BUNDLEMANAGER_QUICK_FIX_PERMISSION_DENIED, + ERR_BUNDLEMANAGER_QUICK_FIX_WRITE_FILE_FAILED, + + ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR = APPEXECFWK_BUNDLEMGR_ERR_OFFSET + 0x0501, // 8520961 + ERR_BUNDLE_MANAGER_APP_CONTROL_PERMISSION_DENIED, + ERR_BUNDLE_MANAGER_APP_CONTROL_RULE_TYPE_INVALID, + ERR_BUNDLE_MANAGER_BUNDLE_NOT_SET_CONTROL, + ERR_BUNDLE_MANAGER_APP_CONTROL_DISALLOWED_INSTALL, + ERR_BUNDLE_MANAGER_APP_CONTROL_DISALLOWED_UNINSTALL, + // query errcode + ERR_BUNDLE_MANAGER_INTERNAL_ERROR = APPEXECFWK_BUNDLEMGR_ERR_OFFSET + 0x0601, // 8521217 + ERR_BUNDLE_MANAGER_INVALID_PARAMETER, + ERR_BUNDLE_MANAGER_INVALID_USER_ID, + ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST, + ERR_BUNDLE_MANAGER_ABILITY_NOT_EXIST, + ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST, + ERR_BUNDLE_MANAGER_ABILITY_DISABLED, + ERR_BUNDLE_MANAGER_APPLICATION_DISABLED, + ERR_BUNDLE_MANAGER_PARAM_ERROR, + ERR_BUNDLE_MANAGER_PERMISSION_DENIED, + ERR_BUNDLE_MANAGER_IPC_TRANSACTION, + ERR_BUNDLE_MANAGER_GLOBAL_RES_MGR_ENABLE_DISABLED, + ERR_BUNDLE_MANAGER_CAN_NOT_CLEAR_USER_DATA, + ERR_BUNDLE_MANAGER_QUERY_PERMISSION_DEFINE_FAILED, + ERR_BUNDLE_MANAGER_DEVICE_ID_NOT_EXIST, + ERR_BUNDLE_MANAGER_PROFILE_NOT_EXIST, + ERR_BUNDLE_MANAGER_INVALID_UID, + ERR_BUNDLE_MANAGER_INVALID_HAP_PATH, + ERR_BUNDLE_MANAGER_DEFAULT_APP_NOT_EXIST, + ERR_BUNDLE_MANAGER_INVALID_TYPE, + ERR_BUNDLE_MANAGER_ABILITY_AND_TYPE_MISMATCH, + ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED, + // zlib errcode + ERR_ZLIB_SRC_FILE_DISABLED, + ERR_ZLIB_DEST_FILE_DISABLED, + ERR_ZLIB_SERVICE_DISABLED, }; // Error code for Hidump diff --git a/mock/innerkits/bundle_framework/appexecfwk_base/include/application_info.h b/mock/innerkits/bundle_framework/appexecfwk_base/include/application_info.h index 12460bcb2c1ca4d6bdd578a2194fcb1e461c197f..56b6e0d6065012931b60cfd1226461b4e5b2a1c2 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_base/include/application_info.h +++ b/mock/innerkits/bundle_framework/appexecfwk_base/include/application_info.h @@ -27,7 +27,8 @@ namespace OHOS { namespace AppExecFwk { namespace { - const std::string AVAILABLELEVEL_NORMAL = "normal"; + static const std::string AVAILABLELEVEL_NORMAL = "normal"; + static const std::string DEFAULT_ENTITY_TYPE = "unspecified"; } enum ApplicationFlag { GET_BASIC_APPLICATION_INFO = 0x00000000, @@ -38,6 +39,24 @@ enum ApplicationFlag { GET_ALL_APPLICATION_INFO = 0xFFFF0000, }; +enum class GetApplicationFlag { + GET_APPLICATION_INFO_DEFAULT = 0x00000000, + GET_APPLICATION_INFO_WITH_PERMISSION = 0x00000001, + GET_APPLICATION_INFO_WITH_METADATA = 0x00000002, + GET_APPLICATION_INFO_WITH_DISABLE = 0x00000004, +}; + +enum class BundleType { + APP = 0, + ATOMIC_SERVICE = 1, +}; + +enum class CompatiblePolicy { + NORMAL = 0, + BACK_COMPATIBLE = 1, + PRECISE_MATCH = 2, +}; + struct Metadata : public Parcelable { std::string name; std::string value; @@ -140,10 +159,17 @@ struct ApplicationInfo : public Parcelable { bool singleton = false; bool userDataClearable = true; bool accessible = false; + bool runningResourcesApply = false; + bool associatedWakeUp = false; + bool hideDesktopIcon = false; + bool formVisibleNotify = false; + std::vector allowCommonEvent; bool isSystemApp = false; bool isLauncherApp = false; bool isFreeInstallApp = false; + bool asanEnabled = false; + std::string asanLogPath; std::string codePath; std::string dataDir; @@ -155,7 +181,7 @@ struct ApplicationInfo : public Parcelable { bool debug = false; std::string deviceId; bool distributedNotificationEnabled = true; - std::string entityType; + std::string entityType = DEFAULT_ENTITY_TYPE; std::string process; int32_t supportedModes = 0; // returns 0 if the application does not support the driving mode std::string vendor; @@ -168,12 +194,15 @@ struct ApplicationInfo : public Parcelable { // user related fields, assign when calling the get interface uint32_t accessTokenId = 0; + uint64_t accessTokenIdEx = 0; bool enabled = false; int32_t uid = -1; // native so std::string nativeLibraryPath; std::string cpuAbi; + std::string arkNativeFilePath; + std::string arkNativeFileAbi; // assign when calling the get interface std::vector permissions; @@ -196,12 +225,27 @@ struct ApplicationInfo : public Parcelable { // switch bool multiProjects = false; + // app detail ability + bool needAppDetail = false; + std::string appDetailAbilityLibraryPath; + + // overlay installation + std::string targetBundleName; + int32_t targetPriority; + int32_t overlayState; + + bool split = true; + BundleType bundleType = BundleType::APP; + + CompatiblePolicy compatiblePolicy = CompatiblePolicy::NORMAL; + bool ReadFromParcel(Parcel &parcel); bool ReadMetaDataFromParcel(Parcel &parcel); virtual bool Marshalling(Parcel &parcel) const override; static ApplicationInfo *Unmarshalling(Parcel &parcel); void Dump(std::string prefix, int fd); void ConvertToCompatibleApplicationInfo(CompatibleApplicationInfo& compatibleApplicationInfo) const; + bool CheckNeedPreload(const std::string &moduleName) const; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/mock/innerkits/ipc/ipc_single/include/iremote_stub.h b/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_common_event.h similarity index 39% rename from mock/innerkits/ipc/ipc_single/include/iremote_stub.h rename to mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_common_event.h index 3151a93a4caef1defa61401e61376507e54d3fa6..ec4d5cb6aa21f9510d1177457256d06e427f10d9 100644 --- a/mock/innerkits/ipc/ipc_single/include/iremote_stub.h +++ b/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_common_event.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,32 +13,24 @@ * limitations under the License. */ -#ifndef OHOS_IPC_IREMOTE_STUB_H -#define OHOS_IPC_IREMOTE_STUB_H +#ifndef FOUNDATION_BUNDLEMANAGER_BUNDLE_FRAMEWORK_INNERKITS_APPEXECFWK_BASE_INCLUDE_BUNDLE_COMMON_EVENT_H +#define FOUNDATION_BUNDLEMANAGER_BUNDLE_FRAMEWORK_INNERKITS_APPEXECFWK_BASE_INCLUDE_BUNDLE_COMMON_EVENT_H #include -#include "iremote_broker.h" -#include "ipc_object_stub.h" namespace OHOS { -template class IRemoteStub : public IPCObjectStub, public INTERFACE { -public: - IRemoteStub(); - virtual ~IRemoteStub() = default; - sptr AsObject() override; - sptr AsInterface() override; -}; - -template IRemoteStub::IRemoteStub() : IPCObjectStub(INTERFACE::GetDescriptor()) {} - -template sptr IRemoteStub::AsInterface() -{ - return this; -} - -template sptr IRemoteStub::AsObject() -{ - return this; -} -} // namespace OHOS -#endif // OHOS_IPC_IREMOTE_STUB_H +namespace AppExecFwk { +const std::string COMMON_EVENT_SANDBOX_PACKAGE_ADDED = "usual.event.SANDBOX_PACKAGE_ADDED"; + +const std::string COMMON_EVENT_SANDBOX_PACKAGE_REMOVED = "usual.event.SANDBOX_PACKAGE_REMOVED"; + +const std::string COMMON_EVENT_BUNDLE_SCAN_FINISHED = "usual.event.BUNDLE_SCAN_FINISHED"; + +const std::string OVERLAY_ADD_ACTION = "usual.event.OVERLAY_PACKAGE_ADDED"; + +const std::string OVERLAY_CHANGED_ACTION = "usual.event.OVERLAY_PACKAGE_CHANGED"; + +const std::string OVERLAY_STATE_CHANGED = "usual.event.OVERLAY_STATE_CHANGED"; +} // AppExecFwk +} // OHOS +#endif // FOUNDATION_BUNDLEMANAGER_BUNDLE_FRAMEWORK_INNERKITS_APPEXECFWK_BASE_INCLUDE_BUNDLE_COMMON_EVENT_H \ No newline at end of file diff --git a/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_info.h b/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_info.h index 80e9a745ce343761161f4231a1f9dca37202e7a9..2d271b3b816936ee07f37e53ee0ff58eb64d2fca 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_info.h +++ b/mock/innerkits/bundle_framework/appexecfwk_base/include/bundle_info.h @@ -42,6 +42,18 @@ enum BundleFlag { GET_BUNDLE_WITH_HASH_VALUE = 0x00000030, }; +enum class GetBundleInfoFlag { + GET_BUNDLE_INFO_DEFAULT = 0x00000000, + GET_BUNDLE_INFO_WITH_APPLICATION = 0x00000001, + GET_BUNDLE_INFO_WITH_HAP_MODULE = 0x00000002, + GET_BUNDLE_INFO_WITH_ABILITY = 0x00000004, + GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY = 0x00000008, + GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION = 0x00000010, + GET_BUNDLE_INFO_WITH_METADATA = 0x00000020, + GET_BUNDLE_INFO_WITH_DISABLE = 0x00000040, + GET_BUNDLE_INFO_WITH_SIGNATURE_INFO = 0x00000080, +}; + struct RequestPermissionUsedScene : public Parcelable { std::vector abilities; std::string when; @@ -61,6 +73,16 @@ struct RequestPermission : public Parcelable { virtual bool Marshalling(Parcel &parcel) const override; static RequestPermission *Unmarshalling(Parcel &parcel); }; + +struct SignatureInfo : public Parcelable { + std::string appId; + std::string fingerprint; + + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static SignatureInfo *Unmarshalling(Parcel &parcel); +}; + // configuration information about a bundle struct BundleInfo : public Parcelable { std::string name; @@ -83,7 +105,6 @@ struct BundleInfo : public Parcelable { std::string mainEntry; // modulePackage std::string entryModuleName; // moduleName bool entryInstallationFree = false; // application : false; atomic service : true - std::string appId; // user related fields, assign when calling the get interface @@ -91,6 +112,7 @@ struct BundleInfo : public Parcelable { int gid = -1; int64_t installTime = 0; int64_t updateTime = 0; + int32_t appIndex = 0; // index for sandbox app ApplicationInfo applicationInfo; std::vector abilityInfos; @@ -106,6 +128,7 @@ struct BundleInfo : public Parcelable { std::vector defPermissions; std::vector reqPermissionStates; std::vector reqPermissionDetails; + std::vector overlayBundleInfos; // unused std::string cpuAbi; @@ -116,6 +139,9 @@ struct BundleInfo : public Parcelable { int32_t minSdkVersion = -1; int32_t maxSdkVersion = -1; bool isDifferentName = false; + int32_t overlayType = NON_OVERLAY_TYPE; + + SignatureInfo signatureInfo; bool ReadFromParcel(Parcel &parcel); virtual bool Marshalling(Parcel &parcel) const override; diff --git a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_installer_interface.h b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_installer_interface.h index 9cb7729d847602958caec78c6dabb038d73f7ff6..4b5e16bed71e479a84b7fdca91956ddd39fa5b7d 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_installer_interface.h +++ b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_installer_interface.h @@ -123,6 +123,7 @@ public: INSTALL_MULTIPLE_HAPS, UNINSTALL, UNINSTALL_MODULE, + UNINSTALL_BY_UNINSTALL_PARAM, RECOVER, INSTALL_SANDBOX_APP, UNINSTALL_SANDBOX_APP, diff --git a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h index ad77c945963914c91534055552a1d0244e9d4780..ae07463cd0f574ac6adbcc6c90df5b477e85d8ab 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h +++ b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h @@ -981,11 +981,7 @@ public: GET_BUNDLE_ARCHIVE_INFO, GET_HAP_MODULE_INFO, GET_LAUNCH_WANT_FOR_BUNDLE, - CHECK_PUBLICKEYS, GET_PERMISSION_DEF, - HAS_SYSTEM_CAPABILITY, - GET_SYSTEM_AVAILABLE_CAPABILITIES, - IS_SAFE_MODE, CLEAN_BUNDLE_CACHE_FILES, CLEAN_BUNDLE_DATA_FILES, REGISTER_BUNDLE_STATUS_CALLBACK, @@ -998,8 +994,6 @@ public: SET_ABILITY_ENABLED, GET_ABILITY_INFO, GET_ABILITY_INFO_WITH_MODULE_NAME, - GET_ABILITY_PIXELMAP_ICON, - GET_ABILITY_PIXELMAP_ICON_WITH_MODULE_NAME, GET_ALL_FORMS_INFO, GET_FORMS_INFO_BY_APP, GET_FORMS_INFO_BY_MODULE, @@ -1023,7 +1017,6 @@ public: QUERY_EXTENSION_INFO, QUERY_EXTENSION_INFO_BY_TYPE, VERIFY_CALLING_PERMISSION, - GET_ACCESSIBLE_APP_CODE_PATH, QUERY_EXTENSION_ABILITY_INFO_BY_URI, IS_MODULE_REMOVABLE, SET_MODULE_REMOVABLE, @@ -1036,15 +1029,45 @@ public: IMPLICIT_QUERY_INFOS, GET_ALL_DEPENDENT_MODULE_NAMES, GET_SANDBOX_APP_BUNDLE_INFO, - SET_DISPOSED_STATUS, - GET_DISPOSED_STATUS, QUERY_CALLING_BUNDLE_NAME, GET_DEFAULT_APP_PROXY, GET_BUNDLE_STATS, CHECK_ABILITY_ENABLE_INSTALL, GET_SANDBOX_APP_ABILITY_INFO, GET_SANDBOX_APP_EXTENSION_INFOS, - GET_SANDBOX_MODULE_INFO + GET_SANDBOX_MODULE_INFO, + GET_MEDIA_DATA, + GET_QUICK_FIX_MANAGER_PROXY, + GET_STRING_BY_ID, + GET_ICON_BY_ID, + GET_UDID_BY_NETWORK_ID, + GET_APP_CONTROL_PROXY, + SET_DEBUG_MODE, + QUERY_ABILITY_INFOS_V9, + QUERY_EXTENSION_INFO_WITHOUT_TYPE_V9, + QUERY_EXTENSION_INFO_V9, + GET_APPLICATION_INFOS_WITH_INT_FLAGS_V9, + GET_APPLICATION_INFO_WITH_INT_FLAGS_V9, + GET_BUNDLE_ARCHIVE_INFO_WITH_INT_FLAGS_V9, + GET_BUNDLE_INFO_WITH_INT_FLAGS_V9, + GET_BUNDLE_INFOS_WITH_INT_FLAGS_V9, + GET_SHORTCUT_INFO_V9, + REGISTER_BUNDLE_EVENT_CALLBACK, + UNREGISTER_BUNDLE_EVENT_CALLBACK, + GET_BUNDLE_INFO_FOR_SELF, + VERIFY_SYSTEM_API, + GET_OVERLAY_MANAGER_PROXY, + SILENT_INSTALL, + PROCESS_PRELOAD, + GET_APP_PROVISION_INFO, + GET_PROVISION_METADATA, + GET_BASE_SHARED_BUNDLE_INFOS, + GET_ALL_SHARED_BUNDLE_INFO, + GET_SHARED_BUNDLE_INFO, + GET_SHARED_BUNDLE_INFO_BY_SELF, + GET_SHARED_DEPENDENCIES, + GET_DEPENDENT_BUNDLE_INFO, + GET_UID_BY_DEBUG_BUNDLE_NAME, }; }; } // namespace AppExecFwk diff --git a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/status_receiver_interface.h b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/status_receiver_interface.h index d01af2307c49f621234b291bf6478cbc3f913ace..fad959e0b4fe27dd9bbf72dc0f8c224d99f66cf6 100644 --- a/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/status_receiver_interface.h +++ b/mock/innerkits/bundle_framework/appexecfwk_core/include/bundlemgr/status_receiver_interface.h @@ -86,6 +86,22 @@ public: ERR_INSTALL_TYPE_ERROR, ERR_INSTALL_SDK_INCOMPATIBLE, ERR_INSTALL_SO_INCOMPATIBLE, + ERR_INSTALL_AN_INCOMPATIBLE, + ERR_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME, + ERR_INSTALL_INCONSISTENT_MODULE_NAME, + ERR_INSTALL_SINGLETON_INCOMPATIBLE, + ERR_INSTALL_DISALLOWED, + ERR_INSTALL_DEVICE_TYPE_NOT_SUPPORTED, + ERR_INSTALL_DEPENDENT_MODULE_NOT_EXIST, + ERR_INSTALL_ASAN_ENABLED_NOT_SAME, + ERR_INSTALL_ASAN_ENABLED_NOT_SUPPORT, + ERR_INSTALL_BUNDLE_TYPE_NOT_SAME, + ERR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, + ERR_INSTALL_COMPATIBLE_POLICY_NOT_SAME, + ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST, + ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED, + ERR_APPEXECFWK_UNINSTALL_BUNDLE_IS_SHARED_LIBRARY, + ERR_INSTALL_FILE_IS_SHARED_LIBRARY, // signature errcode ERR_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH, @@ -117,7 +133,10 @@ public: ERR_INSTALL_PARSE_PROFILE_MISSING_PROP, ERR_INSTALL_PARSE_PERMISSION_ERROR, ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR, + ERR_INSTALL_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR, ERR_INSTALL_PARSE_RPCID_FAILED, + ERR_INSTALL_PARSE_NATIVE_SO_FAILED, + ERR_INSTALL_PARSE_AN_FAILED, ERR_INSTALLD_PARAM_ERROR, ERR_INSTALLD_GET_PROXY_ERROR, @@ -128,6 +147,29 @@ public: ERR_INSTALLD_EXTRACT_FILES_FAILED, ERR_INSTALLD_RNAME_DIR_FAILED, ERR_INSTALLD_CLEAN_DIR_FAILED, + ERR_INSTALLD_PERMISSION_DENIED, + + // overlay installation + ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR, + ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME, + ERR_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME, + ERR_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE, + ERR_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME, + ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_EXTERNAL_OVERLAY_EXISTED_SIMULTANEOUSLY, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME, + ERR_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY, + ERR_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE, + ERR_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION, + ERR_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME, + ERR_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY, + ERR_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE, + ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE, + ERR_OVERLAY_INSTALLATION_FAILED_OVERLAY_TYPE_NOT_SAME, + ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR, ERR_UNINSTALL_SYSTEM_APP_ERROR, ERR_UNINSTALL_KILLING_APP_ERROR, @@ -137,6 +179,7 @@ public: ERR_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR, ERR_UNINSTALL_MISSING_INSTALLED_BUNDLE, ERR_UNINSTALL_MISSING_INSTALLED_MODULE, + ERR_UNINSTALL_DISALLOWED, ERR_UNKNOWN, ERR_FAILED_GET_INSTALLER_PROXY, @@ -145,10 +188,11 @@ public: ERR_RECOVER_GET_BUNDLEPATH_ERROR = 201, ERR_RECOVER_INVALID_BUNDLE_NAME, + ERR_RECOVER_NOT_ALLOWED, ERR_USER_NOT_EXIST = 301, - ERR_USER_CREATE_FALIED, - ERR_USER_REMOVE_FALIED, + ERR_USER_CREATE_FAILED, + ERR_USER_REMOVE_FAILED, ERR_USER_NOT_INSTALL_HAP, }; }; diff --git a/mock/innerkits/ipc/ipc_core/include/ipc_object_proxy.h b/mock/innerkits/ipc/ipc_core/include/ipc_object_proxy.h index cf2ca6520469ced32ac8c875e06591d565a0cc62..3754d9b064f405e8a785432107f6d6196ae3d378 100644 --- a/mock/innerkits/ipc/ipc_core/include/ipc_object_proxy.h +++ b/mock/innerkits/ipc/ipc_core/include/ipc_object_proxy.h @@ -35,8 +35,6 @@ public: return true; }; - bool IsObjectDead() const; - int32_t GetObjectRefCount() override; int Dump(int fd, const std::vector &args) override; @@ -66,18 +64,18 @@ public: int InvokeListenThread(MessageParcel &data, MessageParcel &reply); int32_t NoticeServiceDie(); - std::string GetPidAndUidInfo(); - - std::string GetDataBusName(); - std::string TransDataBusName(uint32_t uid, uint32_t pid); + int GetPidUid(MessageParcel &reply); + std::string GetSessionName(); + std::string GetSessionNameForPidUid(uint32_t uid, uint32_t pid); + std::string GetGrantedSessionName(); int GetProto() const; void WaitForInit(); - std::u16string GetInterfaceDescriptor(); private: void MarkObjectDied(); int SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &optionoption); int SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + void ClearDeathRecipients(); #ifndef CONFIG_IPC_SINGLE void SetProto(int proto); @@ -88,7 +86,7 @@ private: int32_t IncRefToRemote(); - int GetSessionFromDBinderService(); + int GetProtoInfo(); bool AddDbinderDeathRecipient(); diff --git a/mock/innerkits/ipc/ipc_core/include/ipc_object_stub.h b/mock/innerkits/ipc/ipc_core/include/ipc_object_stub.h index 61ecd9aa401c9a4daa57a5f76fd1406a817e8ecd..a3f677ce0472662c13d3ab6fb3ffec6344237f69 100644 --- a/mock/innerkits/ipc/ipc_core/include/ipc_object_stub.h +++ b/mock/innerkits/ipc/ipc_core/include/ipc_object_stub.h @@ -64,8 +64,12 @@ public: uint32_t GetCallingTokenID(); + uint64_t GetCallingFullTokenID(); + uint32_t GetFirstTokenID(); + uint64_t GetFirstFullTokenID(); + virtual int OnRemoteDump(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); virtual int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); @@ -76,16 +80,15 @@ public: int32_t InvokerThread(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t NoticeServiceDie(MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t InvokerDataBusThread(MessageParcel &data, MessageParcel &reply); - int32_t IncStubRefs(MessageParcel &data, MessageParcel &reply); - int32_t DecStubRefs(MessageParcel &data, MessageParcel &reply); int32_t AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code); private: - int32_t GrantDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t TransDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - std::string CreateDatabusName(int uid, int pid); - std::string GetDataBusName(); - bool IsSamgrCall(uint32_t accessToken); + int GetPidUid(MessageParcel &data, MessageParcel &reply); + std::string GetSessionName(); + int32_t GetSessionNameForPidUid(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t GetGrantedSessionName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + std::string CreateSessionName(int uid, int pid); + bool IsSamgrCall(); #endif private: bool IsDeviceIdIllegal(const std::string &deviceID); diff --git a/mock/innerkits/ipc/ipc_core/include/ipc_skeleton.h b/mock/innerkits/ipc/ipc_core/include/ipc_skeleton.h index 4ea3c1a3bf9e224ffc41a3aca95f2e86989612ec..822b457d3f9535a7a8a119b80bf2af87367cce15 100644 --- a/mock/innerkits/ipc/ipc_core/include/ipc_skeleton.h +++ b/mock/innerkits/ipc/ipc_core/include/ipc_skeleton.h @@ -39,8 +39,14 @@ public: static uint32_t GetCallingTokenID(); + static uint64_t GetCallingFullTokenID(); + static uint32_t GetFirstTokenID(); + static uint64_t GetFirstFullTokenID(); + + static uint64_t GetSelfTokenID(); + static std::string GetLocalDeviceID(); static std::string GetCallingDeviceID(); diff --git a/mock/innerkits/ipc/ipc_core/include/ipc_types.h b/mock/innerkits/ipc/ipc_core/include/ipc_types.h index 66b46ad1b8ac72b24d874fd4f4b0fe615fc31716..97c4030075be09b60419257b9769ad62eb43f0f1 100644 --- a/mock/innerkits/ipc/ipc_core/include/ipc_types.h +++ b/mock/innerkits/ipc/ipc_core/include/ipc_types.h @@ -35,15 +35,15 @@ enum { SYSPROPS_TRANSACTION = ZIPC_PACK_CHARS('_', 'S', 'P', 'R'), SYNCHRONIZE_REFERENCE = ZIPC_PACK_CHARS('_', 'S', 'Y', 'C'), INVOKE_LISTEN_THREAD = ZIPC_PACK_CHARS('_', 'I', 'L', 'T'), + GET_PID_UID = ZIPC_PACK_CHARS('_', 'G', 'P', 'U'), GET_PROTO_INFO = ZIPC_PACK_CHARS('_', 'G', 'R', 'I'), - GET_UIDPID_INFO = ZIPC_PACK_CHARS('_', 'G', 'U', 'I'), - GRANT_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'G', 'D', 'N'), - TRANS_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'T', 'D', 'N'), + GET_SESSION_NAME = ZIPC_PACK_CHARS('_', 'G', 'S', 'N'), + GET_SESSION_NAME_PID_UID = ZIPC_PACK_CHARS('_', 'G', 'S', 'P'), + GET_GRANTED_SESSION_NAME = ZIPC_PACK_CHARS('_', 'G', 'G', 'S'), DBINDER_OBITUARY_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'O', 'T'), DBINDER_INCREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'I', 'T'), DBINDER_DECREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'D', 'T'), DBINDER_ADD_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'A', 'C'), - DBINDER_TRANS_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'T', 'C'), TRANS_SYNC = 0, TRANS_ASYNC = 1, }; diff --git a/mock/innerkits/ipc/ipc_core/include/iremote_broker.h b/mock/innerkits/ipc/ipc_core/include/iremote_broker.h index 7105ff7740465454e389109d59597a3791db237f..c09c4d47c21dec46c2e6a5dbf166ec493e991d06 100644 --- a/mock/innerkits/ipc/ipc_core/include/iremote_broker.h +++ b/mock/innerkits/ipc/ipc_core/include/iremote_broker.h @@ -40,18 +40,23 @@ public: class IRemoteBroker : public virtual RefBase { public: IRemoteBroker() = default; - virtual ~IRemoteBroker() = default; + virtual ~IRemoteBroker() override = default; virtual sptr AsObject() = 0; - static inline sptr AsImplement(const sptr &object) - { - (void)object; - return nullptr; - } +}; + +class BrokerDelegatorBase { +public: + BrokerDelegatorBase() = default; + virtual ~BrokerDelegatorBase() = default; + +public: + bool isSoUnloaded = false; + std::u16string descriptor_; }; #define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR) \ - static inline const std::u16string metaDescriptor_ = { DESCRIPTOR }; \ - static inline const std::u16string &GetDescriptor() \ + static constexpr const char16_t *metaDescriptor_ = DESCRIPTOR; \ + static inline const std::u16string GetDescriptor() \ { \ return metaDescriptor_; \ } @@ -61,7 +66,7 @@ class BrokerRegistration { public: static BrokerRegistration &Get(); - bool Register(const std::u16string &descriptor, const Constructor &creator); + bool Register(const std::u16string &descriptor, const Constructor &creator, const BrokerDelegatorBase *object); void Unregister(const std::u16string &descriptor); sptr NewInstance(const std::u16string &descriptor, const sptr &object); @@ -76,12 +81,14 @@ private: BrokerRegistration &operator = (BrokerRegistration &&) = delete; std::mutex creatorMutex_; std::unordered_map creators_; + std::vector objects_; + std::atomic isUnloading = false; }; -template class BrokerDelegator { +template class BrokerDelegator : public BrokerDelegatorBase { public: BrokerDelegator(); - ~BrokerDelegator(); + ~BrokerDelegator() override; private: BrokerDelegator(const BrokerDelegator &) = delete; @@ -94,14 +101,17 @@ template BrokerDelegator::BrokerDelegator() { const std::u16string descriptor = T::GetDescriptor(); BrokerRegistration ®istration = BrokerRegistration::Get(); - registration.Register(descriptor, BrokerCreator()); + if (registration.Register(descriptor, BrokerCreator(), this)) { + descriptor_ = T::GetDescriptor(); + } } template BrokerDelegator::~BrokerDelegator() { - const std::u16string descriptor = T::GetDescriptor(); - BrokerRegistration ®istration = BrokerRegistration::Get(); - registration.Unregister(descriptor); + if (!isSoUnloaded && !descriptor_.empty()) { + BrokerRegistration ®istration = BrokerRegistration::Get(); + registration.Unregister(descriptor_); + } } template inline sptr iface_cast(const sptr &object) diff --git a/mock/innerkits/ipc/ipc_core/include/iremote_object.h b/mock/innerkits/ipc/ipc_core/include/iremote_object.h index 67ef09e1ae44c5b11e85d7276a2194d886b690e1..6e4161b5de81b7daabf9a0d3920e2b9e5461cfdf 100644 --- a/mock/innerkits/ipc/ipc_core/include/iremote_object.h +++ b/mock/innerkits/ipc/ipc_core/include/iremote_object.h @@ -66,7 +66,7 @@ public: virtual bool RemoveDeathRecipient(const sptr &recipient) = 0; - bool Marshalling(Parcel &parcel) const override; + virtual bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &parcel); diff --git a/mock/innerkits/ipc/ipc_single/include/ipc_file_descriptor.h b/mock/innerkits/ipc/ipc_single/include/ipc_file_descriptor.h deleted file mode 100644 index 6f0c242d9a52a5612550dc431ace39f26b2195b0..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/ipc_file_descriptor.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IPC_FILE_DESCRIPTOR_H -#define OHOS_IPC_IPC_FILE_DESCRIPTOR_H - -#include "parcel.h" - -namespace OHOS { -class IPCFileDescriptor : public virtual Parcelable { -public: - IPCFileDescriptor(); - explicit IPCFileDescriptor(int fd); - ~IPCFileDescriptor(); - - bool Marshalling(Parcel &parcel) const override; - static bool Marshalling(Parcel &parcel, const sptr &object); - static IPCFileDescriptor *Unmarshalling(Parcel &parcel); - int GetFd() const; - void SetFd(int fd); - -private: - int fd_ = -1; -}; -} // namespace OHOS -#endif // OHOS_IPC_IPC_FILE_DESCRIPTOR_H diff --git a/mock/innerkits/ipc/ipc_single/include/ipc_object_proxy.h b/mock/innerkits/ipc/ipc_single/include/ipc_object_proxy.h deleted file mode 100644 index cf2ca6520469ced32ac8c875e06591d565a0cc62..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/ipc_object_proxy.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IPC_OBJECT_PROXY_H -#define OHOS_IPC_IPC_OBJECT_PROXY_H - -#include -#include - -#include "iremote_object.h" - -namespace OHOS { -class IPCObjectProxy : public IRemoteObject { -public: - explicit IPCObjectProxy(int handle, std::u16string descriptor = std::u16string(), - int proto = IRemoteObject::IF_PROT_DEFAULT); - ~IPCObjectProxy(); - - int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &optionoption) override; - - bool IsProxyObject() const override - { - return true; - }; - - bool IsObjectDead() const; - - int32_t GetObjectRefCount() override; - - int Dump(int fd, const std::vector &args) override; - - void OnFirstStrongRef(const void *objectId) override; - - void OnLastStrongRef(const void *objectId) override; - - bool AddDeathRecipient(const sptr &recipient) override; - - bool RemoveDeathRecipient(const sptr &recipient) override; - - void SendObituary(); - - bool IsSubscribeDeathNotice() const - { - if (recipients_.empty()) { - return false; - } - return true; - }; - - uint32_t GetHandle() const - { - return handle_; - }; - - int InvokeListenThread(MessageParcel &data, MessageParcel &reply); - int32_t NoticeServiceDie(); - std::string GetPidAndUidInfo(); - - std::string GetDataBusName(); - std::string TransDataBusName(uint32_t uid, uint32_t pid); - int GetProto() const; - void WaitForInit(); - std::u16string GetInterfaceDescriptor(); - -private: - void MarkObjectDied(); - int SendLocalRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &optionoption); - int SendRequestInner(bool isLocal, uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - -#ifndef CONFIG_IPC_SINGLE - void SetProto(int proto); - - int UpdateProto(); - - void ReleaseProto(); - - int32_t IncRefToRemote(); - - int GetSessionFromDBinderService(); - - bool AddDbinderDeathRecipient(); - - bool RemoveDbinderDeathRecipient(); - - void ReleaseDatabusProto(); - - void ReleaseBinderProto(); - - bool UpdateDatabusClientSession(int handle, MessageParcel &reply); - - bool CheckHaveSession(); -#endif - -private: - std::mutex initMutex_; - std::recursive_mutex mutex_; - - std::vector> recipients_; - const uint32_t handle_; - int proto_; - bool isFinishInit_; - bool isRemoteDead_; - std::u16string remoteDescriptor_; -}; -} // namespace OHOS -#endif // OHOS_IPC_IPC_OBJECT_PROXY_H diff --git a/mock/innerkits/ipc/ipc_single/include/ipc_object_stub.h b/mock/innerkits/ipc/ipc_single/include/ipc_object_stub.h deleted file mode 100644 index 61ecd9aa401c9a4daa57a5f76fd1406a817e8ecd..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/ipc_object_stub.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IPC_OBJECT_STUB_H -#define OHOS_IPC_IPC_OBJECT_STUB_H - -#include -#include "ipc_object_proxy.h" -#include "iremote_object.h" - -namespace OHOS { -struct RefCountNode { - int remotePid; - std::string deviceId; -}; - -class IPCObjectStub : public IRemoteObject { -public: - enum { - OBJECT_TYPE_NATIVE, - OBJECT_TYPE_JAVA, - OBJECT_TYPE_JAVASCRIPT, - }; - - explicit IPCObjectStub(std::u16string descriptor = std::u16string()); - ~IPCObjectStub(); - - bool IsProxyObject() const override - { - return false; - }; - - int32_t GetObjectRefCount() override; - - int Dump(int fd, const std::vector &args) override; - - virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - - int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - - void OnFirstStrongRef(const void *objectId) override; - - void OnLastStrongRef(const void *objectId) override; - - bool AddDeathRecipient(const sptr &recipient) override; - - bool RemoveDeathRecipient(const sptr &recipient) override; - - int GetCallingPid(); - - int GetCallingUid(); - - uint32_t GetCallingTokenID(); - - uint32_t GetFirstTokenID(); - - virtual int OnRemoteDump(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - - virtual int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - - virtual int GetObjectType() const; - -#ifndef CONFIG_IPC_SINGLE - int32_t InvokerThread(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t NoticeServiceDie(MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t InvokerDataBusThread(MessageParcel &data, MessageParcel &reply); - int32_t IncStubRefs(MessageParcel &data, MessageParcel &reply); - int32_t DecStubRefs(MessageParcel &data, MessageParcel &reply); - int32_t AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code); - -private: - int32_t GrantDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - int32_t TransDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); - std::string CreateDatabusName(int uid, int pid); - std::string GetDataBusName(); - bool IsSamgrCall(uint32_t accessToken); -#endif -private: - bool IsDeviceIdIllegal(const std::string &deviceID); -}; -} // namespace OHOS -#endif // OHOS_IPC_IPC_OBJECT_STUB_H diff --git a/mock/innerkits/ipc/ipc_single/include/ipc_skeleton.h b/mock/innerkits/ipc/ipc_single/include/ipc_skeleton.h deleted file mode 100644 index 4ea3c1a3bf9e224ffc41a3aca95f2e86989612ec..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/ipc_skeleton.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IPC_SKELETON_H -#define OHOS_IPC_IPC_SKELETON_H - -#include "iremote_object.h" - -namespace OHOS { -class IPCSkeleton { -public: - IPCSkeleton() = default; - ~IPCSkeleton() = default; - - // default max is 4, only if you need a customize value - static bool SetMaxWorkThreadNum(int maxThreadNum); - - // join current thread into work loop. - static void JoinWorkThread(); - - // remove current thread from work loop. - static void StopWorkThread(); - - static pid_t GetCallingPid(); - - static pid_t GetCallingUid(); - - static uint32_t GetCallingTokenID(); - - static uint32_t GetFirstTokenID(); - - static std::string GetLocalDeviceID(); - - static std::string GetCallingDeviceID(); - - static bool IsLocalCalling(); - - static IPCSkeleton &GetInstance(); - - static sptr GetContextObject(); - - static bool SetContextObject(sptr &object); - - static int FlushCommands(IRemoteObject *object); - - static std::string ResetCallingIdentity(); - - static bool SetCallingIdentity(std::string &identity); -}; -} // namespace OHOS -#endif // OHOS_IPC_IPC_SKELETON_H diff --git a/mock/innerkits/ipc/ipc_single/include/ipc_types.h b/mock/innerkits/ipc/ipc_single/include/ipc_types.h deleted file mode 100644 index 66b46ad1b8ac72b24d874fd4f4b0fe615fc31716..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/ipc_types.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IPC_TYPES_H -#define OHOS_IPC_IPC_TYPES_H - -#include -#include -#include "errors.h" - -namespace OHOS { -#define ZIPC_PACK_CHARS(c1, c2, c3, c4) ((((c1) << 24)) | (((c2) << 16)) | (((c3) << 8)) | (c4)) - -constexpr int REGISTRY_HANDLE = 0; - -enum { - FIRST_CALL_TRANSACTION = 0x00000001, - LAST_CALL_TRANSACTION = 0x00ffffff, - PING_TRANSACTION = ZIPC_PACK_CHARS('_', 'P', 'N', 'G'), - DUMP_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'M', 'P'), - SHELL_COMMAND_TRANSACTION = ZIPC_PACK_CHARS('_', 'C', 'M', 'D'), - INTERFACE_TRANSACTION = ZIPC_PACK_CHARS('_', 'N', 'T', 'F'), - SYSPROPS_TRANSACTION = ZIPC_PACK_CHARS('_', 'S', 'P', 'R'), - SYNCHRONIZE_REFERENCE = ZIPC_PACK_CHARS('_', 'S', 'Y', 'C'), - INVOKE_LISTEN_THREAD = ZIPC_PACK_CHARS('_', 'I', 'L', 'T'), - GET_PROTO_INFO = ZIPC_PACK_CHARS('_', 'G', 'R', 'I'), - GET_UIDPID_INFO = ZIPC_PACK_CHARS('_', 'G', 'U', 'I'), - GRANT_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'G', 'D', 'N'), - TRANS_DATABUS_NAME = ZIPC_PACK_CHARS('_', 'T', 'D', 'N'), - DBINDER_OBITUARY_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'O', 'T'), - DBINDER_INCREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'I', 'T'), - DBINDER_DECREFS_TRANSACTION = ZIPC_PACK_CHARS('_', 'D', 'D', 'T'), - DBINDER_ADD_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'A', 'C'), - DBINDER_TRANS_COMMAUTH = ZIPC_PACK_CHARS('_', 'D', 'T', 'C'), - TRANS_SYNC = 0, - TRANS_ASYNC = 1, -}; - -enum { - NO_ERROR = 0, - TRANSACTION_ERR, - FLATTEN_ERR = 3, - UNKNOWN_TRANSACTION = 4, - INVALID_DATA = 5, - OBJECT_NULL = 7, - INVALID_OPERATION = 8, - DEAD_OBJECT = -EPIPE, - UNKNOWN_ERROR, -}; - -constexpr int MIN_TRANSACTION_ID = 0x1; -constexpr int MAX_TRANSACTION_ID = 0x00ffffff; -constexpr int INVALID_FD = -1; - -enum { - ERR_NONE = 0, - ERR_TRANSACTION_FAILED = 1, - ERR_UNKNOWN_OBJECT = 2, - ERR_FLATTEN_OBJECT = 3, - ERR_UNKNOWN_TRANSACTION = 4, - ERR_INVALID_DATA = 5, - ERR_NULL_OBJECT = 7, - ERR_UNKNOWN_REASON, - ERR_INVALID_REPLY, - ERR_INVALID_STATE, - IPC_SKELETON_ERR = 100, - IPC_SKELETON_NULL_OBJECT_ERR, - IPC_PROXY_ERR = 200, - IPC_PROXY_DEAD_OBJECT_ERR, - IPC_PROXY_NULL_INVOKER_ERR, - IPC_PROXY_TRANSACTION_ERR, - IPC_PROXY_INVALID_CODE_ERR, - IPC_STUB_ERR = 300, - IPC_STUB_WRITE_PARCEL_ERR, - IPC_STUB_INVOKE_THREAD_ERR, - IPC_STUB_INVALID_DATA_ERR, - IPC_STUB_CURRENT_NULL_ERR, - IPC_STUB_UNKNOW_TRANS_ERR, - IPC_STUB_CREATE_BUS_SERVER_ERR, - IPC_INVOKER_ERR = 400, - IPC_INVOKER_WRITE_TRANS_ERR, - IPC_INVOKER_TRANSLATE_ERR, - IPC_INVOKER_CONNECT_ERR, - IPC_INVOKER_ON_TRANSACT_ERR, - IPC_INVOKER_INVALID_DATA_ERR, - IPC_INVOKER_INVALID_REPLY_ERR, - RPC_BASE_INVOKER_ERR = 500, - RPC_BASE_INVOKER_INVALID_REPLY_ERR, - RPC_BASE_INVOKER_WAIT_REPLY_ERR, - RPC_BASE_INVOKER_CURRENT_NULL_ERR, - RPC_BASE_INVOKER_INVALID_DATA_ERR, - RPC_BASE_INVOKER_WRITE_TRANS_ERR, - RPC_BASE_INVOKER_SEND_REPLY_ERR, - RPC_DATABUS_INVOKER_ERR = 600, - RPC_DATABUS_INVOKER_INVALID_DATA_ERR, - RPC_DATABUS_INVOKER_CLOSED_PEER_ERR, - RPC_DATABUS_INVOKER_INVALID_STUB_INDEX, - DBINDER_SERVICE_ERR = 700, - DBINDER_SERVICE_INVALID_DATA_ERR, - DBINDER_SERVICE_NOTICE_DIE_ERR, - DBINDER_SERVICE_PROCESS_PROTO_ERR, - DBINDER_SERVICE_UNKNOW_TRANS_ERR, - DBINDER_SERVICE_ADD_DEATH_ERR, - DBINDER_SERVICE_REMOVE_DEATH_ERR, - DBINDER_SERVICE_WRONG_SESSION, - SESSION_WRONG_FD_ERR = 800, - SESSION_INVOKER_NULL_ERR, - SESSION_UNAUTHENTICATED_ERR, - SESSION_UNOPEN_ERR = -1, - DBINDER_CALLBACK_ERR = 900, - DBINDER_CALLBACK_ADD_DEATH_ERR, - DBINDER_CALLBACK_RMV_DEATH_ERR, - DBINDER_CALLBACK_READ_OBJECT_ERR, - BINDER_CALLBACK_AUTHCOMM_ERR, - BINDER_CALLBACK_STUBINDEX_ERR -}; -} // namespace OHOS -#endif // OHOS_IPC_IPC_TYPES_H diff --git a/mock/innerkits/ipc/ipc_single/include/iremote_broker.h b/mock/innerkits/ipc/ipc_single/include/iremote_broker.h deleted file mode 100644 index e6832f359a00a875640beab1240cefdc0dca3573..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/iremote_broker.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IREMOTE_BROKER_H -#define OHOS_IPC_IREMOTE_BROKER_H - -#include -#include -#include -#include "iremote_object.h" -#include "refbase.h" - -namespace OHOS { -template class BrokerCreator { -public: - BrokerCreator() = default; - ~BrokerCreator() = default; - sptr operator () (const sptr &object) - { - T *proxy = new (std::nothrow) T(object); - if (proxy != nullptr) { - return static_cast(proxy); - } - return nullptr; - }; -}; - -class IRemoteBroker : public virtual RefBase { -public: - IRemoteBroker() = default; - virtual ~IRemoteBroker() = default; - virtual sptr AsObject() = 0; - static inline sptr AsImplement(const sptr &object) - { - (void)object; - return nullptr; - } -}; - -#define DECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR) \ - static inline const std::u16string metaDescriptor_ = { DESCRIPTOR }; \ - static inline const std::u16string &GetDescriptor() \ - { \ - return metaDescriptor_; \ - } - -class BrokerRegistration { - using Constructor = std::function(const sptr &object)>; - -public: - static BrokerRegistration &Get(); - bool Register(const std::u16string &descriptor, const Constructor &creator); - void Unregister(const std::u16string &descriptor); - sptr NewInstance(const std::u16string &descriptor, const sptr &object); - -protected: - BrokerRegistration() = default; - ~BrokerRegistration(); - -private: - BrokerRegistration(const BrokerRegistration &) = delete; - BrokerRegistration(BrokerRegistration &&) = delete; - BrokerRegistration &operator = (const BrokerRegistration &) = delete; - BrokerRegistration &operator = (BrokerRegistration &&) = delete; - std::mutex creatorMutex_; - std::unordered_map creators_; -}; - -template class BrokerDelegator { -public: - BrokerDelegator(); - ~BrokerDelegator(); - -private: - BrokerDelegator(const BrokerDelegator &) = delete; - BrokerDelegator(BrokerDelegator &&) = delete; - BrokerDelegator &operator = (const BrokerDelegator &) = delete; - BrokerDelegator &operator = (BrokerDelegator &&) = delete; -}; - -template BrokerDelegator::BrokerDelegator() -{ - const std::u16string descriptor = T::GetDescriptor(); - BrokerRegistration ®istration = BrokerRegistration::Get(); - registration.Register(descriptor, BrokerCreator()); -} - -template BrokerDelegator::~BrokerDelegator() -{ - const std::u16string descriptor = T::GetDescriptor(); - BrokerRegistration ®istration = BrokerRegistration::Get(); - registration.Unregister(descriptor); -} - -template inline sptr iface_cast(const sptr &object) -{ - const std::u16string descriptor = INTERFACE::GetDescriptor(); - BrokerRegistration ®istration = BrokerRegistration::Get(); - sptr broker = registration.NewInstance(descriptor, object); - return static_cast(broker.GetRefPtr()); -} -} // namespace OHOS -#endif // OHOS_IPC_IREMOTE_BROKER_H diff --git a/mock/innerkits/ipc/ipc_single/include/iremote_object.h b/mock/innerkits/ipc/ipc_single/include/iremote_object.h deleted file mode 100644 index 67ef09e1ae44c5b11e85d7276a2194d886b690e1..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/iremote_object.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IREMOTE_OBJECT_H -#define OHOS_IPC_IREMOTE_OBJECT_H - -#include -#include -#include -#include -#include "ipc_types.h" -#include "message_parcel.h" -#include "message_option.h" - -namespace OHOS { -class IRemoteBroker; -inline std::u16string to_utf16(const std::string &str) -{ - return std::wstring_convert, char16_t> {}.from_bytes(str); -} - -class IRemoteObject : public virtual Parcelable, public virtual RefBase { -public: - enum { - IF_PROT_DEFAULT, /* Invoker family. */ - IF_PROT_BINDER = IF_PROT_DEFAULT, - IF_PROT_DATABUS, - IF_PROT_ERROR, - }; - enum { - DATABUS_TYPE, - }; - class DeathRecipient : public RefBase { - public: - enum { - ADD_DEATH_RECIPIENT, - REMOVE_DEATH_RECIPIENT, - NOTICE_DEATH_RECIPIENT, - TEST_SERVICE_DEATH_RECIPIENT, - TEST_DEVICE_DEATH_RECIPIENT, - }; - virtual void OnRemoteDied(const wptr &object) = 0; - }; - - virtual int32_t GetObjectRefCount() = 0; - - virtual int SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) = 0; - - virtual bool IsProxyObject() const; - - virtual bool CheckObjectLegality() const; - - virtual bool AddDeathRecipient(const sptr &recipient) = 0; - - virtual bool RemoveDeathRecipient(const sptr &recipient) = 0; - - bool Marshalling(Parcel &parcel) const override; - - static sptr Unmarshalling(Parcel &parcel); - - static bool Marshalling(Parcel &parcel, const sptr &object); - - virtual sptr AsInterface(); - - virtual int Dump(int fd, const std::vector &args) = 0; - - const std::u16string descriptor_; - - std::u16string GetObjectDescriptor() const; - -protected: - explicit IRemoteObject(std::u16string descriptor = std::u16string()); - virtual ~IRemoteObject() = default; -}; -} // namespace OHOS -#endif // OHOS_IPC_IREMOTE_OBJECT_H diff --git a/mock/innerkits/ipc/ipc_single/include/iremote_proxy.h b/mock/innerkits/ipc/ipc_single/include/iremote_proxy.h deleted file mode 100644 index fff5bc5f21fb3c4602ed9e4b73f0edc812b5ab45..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/iremote_proxy.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_IREMOTE_PROXY_H -#define OHOS_IPC_IREMOTE_PROXY_H - -#include "iremote_broker.h" -#include "peer_holder.h" -#include "iremote_object.h" - -namespace OHOS { -template class IRemoteProxy : public PeerHolder, public INTERFACE { -public: - explicit IRemoteProxy(const sptr &object); - ~IRemoteProxy() override = default; - -protected: - sptr AsObject() override; -}; - -template -IRemoteProxy::IRemoteProxy(const sptr &object) : PeerHolder(object) -{ -} - -template sptr IRemoteProxy::AsObject() -{ - return Remote(); -} -} // namespace OHOS -#endif // OHOS_IPC_IREMOTE_PROXY_H diff --git a/mock/innerkits/ipc/ipc_single/include/message_parcel.h b/mock/innerkits/ipc/ipc_single/include/message_parcel.h deleted file mode 100644 index f59fad04b120b1395163125303c52a917465e64a..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/message_parcel.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_MESSAGE_PARCEL_H -#define OHOS_IPC_MESSAGE_PARCEL_H - -#include -#include "parcel.h" -#include "refbase.h" -#include -#include -#include - -namespace OHOS { -class IRemoteObject; -class MessageParcel : public Parcel { -public: - MessageParcel(); - ~MessageParcel(); - explicit MessageParcel(Allocator *allocator); - bool WriteRemoteObject(const sptr &object); - sptr ReadRemoteObject(); - bool WriteFileDescriptor(int fd); - int ReadFileDescriptor(); - bool ContainFileDescriptors() const; - bool WriteInterfaceToken(std::u16string name); - std::u16string ReadInterfaceToken(); - bool WriteRawData(const void *data, size_t size); - const void *ReadRawData(size_t size); - bool RestoreRawData(std::shared_ptr rawData, size_t size); - const void *GetRawData() const; - size_t GetRawDataSize() const; - size_t GetRawDataCapacity() const; - void WriteNoException(); - int32_t ReadException(); - bool WriteAshmem(sptr ashmem); - sptr ReadAshmem(); - void ClearFileDescriptor(); - void SetClearFdFlag() - { - needCloseFd_ = true; - }; - bool Append(MessageParcel &data); - -private: -#ifndef CONFIG_IPC_SINGLE - bool WriteDBinderProxy(const sptr &object, uint32_t handle, uint64_t stubIndex); -#endif - static constexpr size_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // 128M - static constexpr size_t MIN_RAWDATA_SIZE = 32 * 1024; // 32k - bool needCloseFd_ = false; - std::vector> holders_; - int writeRawDataFd_; - int readRawDataFd_; - void *kernelMappedWrite_; - void *kernelMappedRead_; - std::shared_ptr rawData_; - size_t rawDataSize_; - std::u16string token_; - std::queue> remoteObjects_; -}; -} // namespace OHOS -#endif // OHOS_IPC_MESSAGE_PARCEL_H diff --git a/mock/innerkits/ipc/ipc_single/include/peer_holder.h b/mock/innerkits/ipc/ipc_single/include/peer_holder.h deleted file mode 100644 index 9ca9c7bffe064794f7f647cc9821aa5d1f9b22ed..0000000000000000000000000000000000000000 --- a/mock/innerkits/ipc/ipc_single/include/peer_holder.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_IPC_PEER_HOLDER_H -#define OHOS_IPC_PEER_HOLDER_H - -#include "iremote_object.h" - -namespace OHOS { -class PeerHolder { -protected: - PeerHolder(const sptr &object); - - ~PeerHolder() = default; - - sptr Remote(); - -private: - const sptr remoteObject_; -}; -} // namespace OHOS -#endif // OHOS_IPC_PEER_HOLDER_H diff --git a/mock/innerkits/ipc/libdbinder/include/dbinder_service.h b/mock/innerkits/ipc/libdbinder/include/dbinder_service.h index 4bea9ad31227076498ab1ad1b1653a71ed2fd939..54758c523cca2be4d939e48011ce7f4db64bfc91 100644 --- a/mock/innerkits/ipc/libdbinder/include/dbinder_service.h +++ b/mock/innerkits/ipc/libdbinder/include/dbinder_service.h @@ -54,7 +54,8 @@ struct DHandleEntryTxRx { struct DHandleEntryHead head; uint32_t transType; uint32_t dBinderCode; - uint32_t rpcFeatureSet; + uint16_t fromPort; + uint16_t toPort; uint64_t stubIndex; uint32_t seqNumber; binder_uintptr_t binderObject; @@ -69,7 +70,8 @@ struct DHandleEntryTxRx { struct SessionInfo { uint32_t seqNumber; uint32_t type; - uint32_t rpcFeatureSet; + uint16_t toPort; + uint16_t fromPort; uint64_t stubIndex; uint32_t socketFd; std::string serviceName; @@ -80,16 +82,29 @@ enum DBinderCode { MESSAGE_AS_INVOKER = 1, MESSAGE_AS_REPLY = 2, MESSAGE_AS_OBITUARY = 3, + MESSAGE_AS_REMOTE_ERROR = 4, + MESSAGE_AS_REPLY_TOKENID = 5, }; -enum AfType { - IPV4_TYPE = 1, - IPV6_TYPE = 2, - DATABBUS_TYPE = 3, +enum DBinderErrorCode { + DBINDER_OK = 100, + STUB_INVALID = 101, + SEND_MESSAGE_FAILED = 102, + MAKE_THREADLOCK_FAILED = 103, + WAIT_REPLY_TIMEOUT = 104, + QUERY_REPLY_SESSION_FAILED = 105, + SA_NOT_FOUND = 106, + SA_INVOKE_FAILED = 107, + DEVICEID_INVALID = 108, + SESSION_NAME_NOT_FOUND = 109, + WRITE_PARCEL_FAILED = 110, + INVOKE_STUB_THREAD_FAILED = 111, + SESSION_NAME_INVALID = 112, }; struct ThreadLockInfo { std::mutex mutex; + std::string networkId; std::condition_variable condition; bool ready = false; }; @@ -100,12 +115,14 @@ public: virtual ~DBinderService(); public: static sptr GetInstance(); + static std::string ConvertToSecureDeviceID(const std::string &deviceID); bool StartDBinderService(std::shared_ptr &callbackImpl); sptr MakeRemoteBinder(const std::u16string &serviceName, - const std::string &deviceID, binder_uintptr_t binderObject, uint64_t pid = 0); + const std::string &deviceID, int32_t binderObject, uint32_t pid = 0, uint32_t uid = 0); bool RegisterRemoteProxy(std::u16string serviceName, sptr binderObject); bool RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId); - bool OnRemoteMessageTask(const struct DHandleEntryTxRx *message); + bool OnRemoteMessageTask(std::shared_ptr message); + void AddAsynMessageTask(std::shared_ptr message); std::shared_ptr QuerySessionObject(binder_uintptr_t stub); bool DetachDeathRecipient(sptr object); bool AttachDeathRecipient(sptr object, sptr deathRecipient); @@ -114,32 +131,33 @@ public: bool AttachCallbackProxy(sptr object, DBinderServiceStub *dbStub); int32_t NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID); int32_t NoticeDeviceDie(const std::string &deviceID); - bool AttachBusNameObject(IPCObjectProxy *proxy, const std::string &name); - bool DetachBusNameObject(IPCObjectProxy *proxy); std::string CreateDatabusName(int uid, int pid); bool DetachProxyObject(binder_uintptr_t binderObject); - std::string QueryBusNameObject(IPCObjectProxy *proxy); + void LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId, + const sptr& remoteObject); + bool ProcessOnSessionClosed(std::shared_ptr session); private: static std::shared_ptr GetRemoteListener(); static bool StartRemoteListener(); static void StopRemoteListener(); - static std::string ConvertToSecureDeviceID(const std::string &deviceID); std::u16string GetRegisterService(binder_uintptr_t binderObject); - bool InvokerRemoteDBinder(const sptr stub, uint32_t seqNumber); + int32_t InvokerRemoteDBinder(const sptr stub, uint32_t seqNumber, uint32_t pid, uint32_t uid); bool OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage); + bool OnRemoteErrorMessage(const struct DHandleEntryTxRx *replyMessage); void MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage); bool OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message); void WakeupThreadByStub(uint32_t seqNumber); void DetachThreadLockInfo(uint32_t seqNumber); - bool AttachThreadLockInfo(uint32_t seqNumber, std::shared_ptr object); + bool AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId, + std::shared_ptr object); std::shared_ptr QueryThreadLockInfo(uint32_t seqNumber); bool AttachProxyObject(sptr object, binder_uintptr_t binderObject); sptr QueryProxyObject(binder_uintptr_t binderObject); bool DetachSessionObject(binder_uintptr_t stub); bool AttachSessionObject(std::shared_ptr object, binder_uintptr_t stub); sptr FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId); - bool SendEntryToRemote(const sptr stub, uint32_t seqNumber); + bool SendEntryToRemote(const sptr stub, uint32_t seqNumber, uint32_t pid, uint32_t uid); uint16_t AllocFreeSocketPort(); std::string GetLocalDeviceID(); bool CheckBinderObject(const sptr &stub, binder_uintptr_t binderObject); @@ -155,38 +173,46 @@ private: std::list FindServicesByDeviceID(const std::string &deviceID); int32_t NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID); uint32_t GetRemoteTransType(); - bool OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage, - std::string &remoteDeviceId, int pid, int uid); + uint32_t OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy, struct DHandleEntryTxRx *replyMessage, + std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId); bool IsDeviceIdIllegal(const std::string &deviceID); std::string GetDatabusNameByProxy(IPCObjectProxy *proxy); uint32_t GetSeqNumber(); + bool StartThreadPool(); + bool StopThreadPool(); + bool AddAsynTask(const ThreadPool::Task &f); + bool IsSameSession(std::shared_ptr oldSession, std::shared_ptr newSession); bool RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder); bool CheckSystemAbilityId(int32_t systemAbilityId); - bool IsSameSession(std::shared_ptr oldSession, std::shared_ptr nowSession); bool HandleInvokeListenThread(IPCObjectProxy *proxy, uint64_t stubIndex, std::string serverSessionName, struct DHandleEntryTxRx *replyMessage); bool ReStartRemoteListener(); - bool ReGrantPermission(const std::string &sessionName); + bool IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId, + std::shared_ptr loadSaItem); + std::shared_ptr PopLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId); + void SendMessageToRemote(uint32_t dBinderCode, uint32_t reason, + std::shared_ptr replyMessage); private: DISALLOW_COPY_AND_MOVE(DBinderService); static std::mutex instanceMutex_; - static constexpr int WAIT_FOR_REPLY_MAX_SEC = 4; + static constexpr int WAIT_FOR_REPLY_MAX_SEC = 8; static constexpr int RETRY_TIMES = 2; static std::shared_ptr remoteListener_; static bool mainThreadCreated_; static sptr instance_; std::shared_mutex remoteBinderMutex_; - std::shared_mutex busNameMutex_; std::shared_mutex proxyMutex_; std::shared_mutex deathRecipientMutex_; std::shared_mutex sessionMutex_; + std::shared_mutex loadSaMutex_; std::mutex handleEntryMutex_; std::mutex threadLockMutex_; std::mutex callbackProxyMutex_; std::mutex deathNotificationMutex_; + std::mutex threadPoolMutex_; uint32_t seqNumber_ = 0; /* indicate make remote binder message sequence number, and can be overflow */ std::list> DBinderStubRegisted_; @@ -196,7 +222,9 @@ private: std::map> sessionObject_; std::map, DBinderServiceStub *> noticeProxy_; std::map, sptr> deathRecipients_; - std::map busNameObject_; + bool threadPoolStarted_ = false; + int32_t threadPoolNumber_ = 4; + std::unique_ptr threadPool_ = nullptr; static constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000001; static constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff; diff --git a/mock/innerkits/ipc/libdbinder/include/dbinder_service_stub.h b/mock/innerkits/ipc/libdbinder/include/dbinder_service_stub.h index 93c8f1267d298aa30a9c974c708b6c93ce41ef24..e502acd4fa2fc5f1a161fdff59338ff2e2c630c4 100644 --- a/mock/innerkits/ipc/libdbinder/include/dbinder_service_stub.h +++ b/mock/innerkits/ipc/libdbinder/include/dbinder_service_stub.h @@ -21,18 +21,22 @@ #include "ipc_object_stub.h" namespace OHOS { +#ifdef BINDER_IPC_32BIT +typedef unsigned int binder_uintptr_t; +#else typedef unsigned long long binder_uintptr_t; +#endif class DBinderServiceStub : public IPCObjectStub { public: - explicit DBinderServiceStub(const std::string& serviceName, const std::string& deviceID, + explicit DBinderServiceStub(const std::string &serviceName, const std::string &deviceID, binder_uintptr_t binderObject); ~DBinderServiceStub(); int32_t ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - const std::string& GetServiceName(); - const std::string& GetDeviceID(); + const std::string &GetServiceName(); + const std::string &GetDeviceID(); binder_uintptr_t GetBinderObject() const; private: diff --git a/mock/src/mock_ipc.cpp b/mock/src/mock_ipc.cpp index 38a2cd7a85f833c0d7bb07b288cf0093cd623044..5c8f16aabd979c4897b603ec039e9b9f12845143 100644 --- a/mock/src/mock_ipc.cpp +++ b/mock/src/mock_ipc.cpp @@ -26,33 +26,88 @@ namespace OHOS { BrokerRegistration &BrokerRegistration::Get() { - static OHOS::BrokerRegistration brokerRegistration; - return brokerRegistration; -}; + static BrokerRegistration instance; + return instance; +} -bool BrokerRegistration::Register(const std::u16string &descriptor, const BrokerRegistration::Constructor &creator) +BrokerRegistration::~BrokerRegistration() { - creators_[descriptor] = creator; - return true; + isUnloading = true; + std::lock_guard lockGuard(creatorMutex_); + for (auto it = creators_.begin(); it != creators_.end();) { + it = creators_.erase(it); + } + for (auto it1 = objects_.begin(); it1 != objects_.end();) { + BrokerDelegatorBase *object = reinterpret_cast(*it1); + object->isSoUnloaded = true; + it1 = objects_.erase(it1); + } +} + +bool BrokerRegistration::Register(const std::u16string &descriptor, const Constructor &creator, + const BrokerDelegatorBase *object) +{ + if (descriptor.empty()) { + return false; + } + + std::lock_guard lockGuard(creatorMutex_); + auto it = creators_.find(descriptor); + bool ret = false; + if (it == creators_.end()) { + ret = creators_.insert({ descriptor, creator }).second; + } + auto it1 = std::find_if(objects_.begin(), objects_.end(), [descriptor](uintptr_t id) { + const BrokerDelegatorBase *object = reinterpret_cast(id); + return object->descriptor_ == descriptor; + }); + if (it1 == objects_.end()) { + objects_.push_back(reinterpret_cast(object)); + } + return ret; } void BrokerRegistration::Unregister(const std::u16string &descriptor) { - creators_.erase(descriptor); + if (isUnloading) { +// ZLOGE(LABEL, "BrokerRegistration is Unloading"); + return; + } + std::lock_guard lockGuard(creatorMutex_); + if (!descriptor.empty()) { + auto it = creators_.find(descriptor); + if (it != creators_.end()) { + creators_.erase(it); + } + auto it1 = std::find_if(objects_.begin(), objects_.end(), [descriptor](uintptr_t id) { + const BrokerDelegatorBase *object = reinterpret_cast(id); + return object->descriptor_ == descriptor; + }); + if (it1 != objects_.end()) { + objects_.erase(it1); + } + } } sptr BrokerRegistration::NewInstance(const std::u16string &descriptor, const sptr &object) { - if (object == nullptr) { - return nullptr; - } - if (creators_.find(descriptor) == creators_.end()) { - return nullptr; + std::lock_guard lockGuard(creatorMutex_); + + sptr broker; + if (object != nullptr) { + auto it = creators_.find(descriptor); + if (it != creators_.end()) { + broker = it->second(object); + } +// if (object->IsProxyObject()) { +// +// } else { +// broker = object->AsInterface().GetRefPtr(); +// } } - return creators_[descriptor](object); + return broker; } -BrokerRegistration::~BrokerRegistration() {} PeerHolder::PeerHolder(const sptr &object) : remoteObject_(object) {}; sptr PeerHolder::Remote() { return remoteObject_; } diff --git a/mock/src/mock_ipc_object_stub.cpp b/mock/src/mock_ipc_object_stub.cpp index 96152970017a315ccfdc1a0c3f070a8409e5d8bd..99cd67e1ca5e1beb4ef5ce40bbcaadf9076ff8a8 100644 --- a/mock/src/mock_ipc_object_stub.cpp +++ b/mock/src/mock_ipc_object_stub.cpp @@ -83,30 +83,10 @@ int32_t IPCObjectStub::InvokerDataBusThread(MessageParcel &data, MessageParcel & { return 0; } -int32_t IPCObjectStub::IncStubRefs(MessageParcel &data, MessageParcel &reply) -{ - return 0; -} -int32_t IPCObjectStub::DecStubRefs(MessageParcel &data, MessageParcel &reply) -{ - return 0; -} int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code) { return 0; } -int32_t IPCObjectStub::GrantDataBusName(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) -{ - return 0; -} -std::string IPCObjectStub::CreateDatabusName(int uid, int pid) -{ - return std::string(); -} -std::string IPCObjectStub::GetDataBusName() -{ - return std::string(); -} bool IPCObjectStub::IsDeviceIdIllegal(const std::string &deviceID) { return false; diff --git a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp index 5918a8826378b5b770d2a9cd8bf71766b13069d9..fe2d082b05e9592169c320a86f09c17082fac749 100644 --- a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp +++ b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp @@ -127,7 +127,11 @@ napi_value PreferencesProxy::New(napi_env env, napi_callback_info info) LOG_WARN("get this failed"); return nullptr; } - PreferencesProxy *obj = new PreferencesProxy(); + PreferencesProxy *obj = new (std::nothrow) PreferencesProxy(); + if (obj == nullptr) { + LOG_ERROR("PreferencesProxy::New new failed, obj is nullptr"); + return nullptr; + } obj->env_ = env; obj->uvQueue_ = std::make_shared(env); napi_status status = napi_wrap(env, thiz, obj, PreferencesProxy::Destructor, nullptr, nullptr); diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp index e0dffd71ce7f141909bec55279a11b319a9f5a4b..b7f082b79ffcc390596cd75a04eced6076a4af5d 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp @@ -131,7 +131,11 @@ napi_value StorageProxy::New(napi_env env, napi_callback_info info) napi_valuetype valueType = napi_undefined; NAPI_CALL(env, napi_typeof(env, args[0], &valueType)); NAPI_ASSERT(env, valueType == napi_string, "input type not string"); - char *path = new char[PATH_MAX]; + char *path = new (std::nothrow) char[PATH_MAX]; + if (path == nullptr) { + LOG_ERROR("StorageProxy::New new failed, path is nullptr"); + return nullptr; + } size_t pathLen = 0; napi_status status = napi_get_value_string_utf8(env, args[0], path, PATH_MAX, &pathLen); if (status != napi_ok) { @@ -145,7 +149,11 @@ napi_value StorageProxy::New(napi_env env, napi_callback_info info) OHOS::NativePreferences::PreferencesHelper::GetPreferences(path, errCode); delete[] path; NAPI_ASSERT(env, preference != nullptr, "failed to call native"); - StorageProxy *obj = new StorageProxy(preference); + StorageProxy *obj = new (std::nothrow) StorageProxy(preference); + if (obj == nullptr) { + LOG_ERROR("StorageProxy::New new failed, obj is nullptr"); + return nullptr; + } obj->env_ = env; obj->value_ = std::move(preference); obj->uvQueue_ = std::make_shared(env); @@ -221,7 +229,11 @@ napi_value StorageProxy::GetValueSync(napi_env env, napi_callback_info info) double result = obj->value_->GetDouble(key, value); NAPI_CALL(env, napi_create_double(env, result, &output)); // double } else if (valueType == napi_string) { - char *value = new char[MAX_VALUE_LENGTH]; + char *value = new (std::nothrow) char[MAX_VALUE_LENGTH]; + if (value == nullptr) { + LOG_ERROR("StorageProxy::GetValueSync new failed, value is nullptr"); + return nullptr; + } size_t valueSize = 0; napi_get_value_string_utf8(env, args[1], value, MAX_VALUE_LENGTH, &valueSize); // get value diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp index fbc613fec4a8a98c7fed02878355fff85a3cdb8e..d7b85f29cc8306d8f240b91015587680e5d8f87f 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp @@ -57,7 +57,11 @@ int ParseString(const napi_env &env, const napi_value &value, std::shared_ptrpath = path; @@ -108,7 +112,11 @@ napi_status GetInputPath(napi_env env, napi_callback_info info, std::string &pat return napi_invalid_arg; } - char *path = new char[PATH_MAX]; + char *path = new (std::nothrow) char[PATH_MAX]; + if (path == nullptr) { + LOG_ERROR("GetInputPath new failed, path is nullptr"); + return napi_arraybuffer_expected; + } size_t pathLen = 0; ret = napi_get_value_string_utf8(env, args[0], path, PATH_MAX, &pathLen); pathString = path; diff --git a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp index e1f0f06c575d650e87799f2b2b9edc444d59d04a..1c11411d15696cca053d5bca2b61933c18421066 100644 --- a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp +++ b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp @@ -157,7 +157,11 @@ napi_value Operate(napi_env env, napi_callback_info info, const char *resource, NAPI_CALL(env, napi_typeof(env, argv[0], &valueType)); NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object expected."); - AsyncContext *context = new AsyncContext(); + AsyncContext *context = new (std::nothrow) AsyncContext(); + if (context == nullptr) { + LOG_ERROR("Operate new failed, context is nullptr"); + return nullptr; + } context->prefName = GetPrefName(env); ParseString(env, argv[0], "key", parseStrFlag, context->key); diff --git a/preferences/frameworks/native/include/preferences_impl.h b/preferences/frameworks/native/include/preferences_impl.h index ead876e6b05e472db5b451770ca9f81f98822206..c286308c8ab5a119ab2f736c5ad288f3dc8c6a75 100644 --- a/preferences/frameworks/native/include/preferences_impl.h +++ b/preferences/frameworks/native/include/preferences_impl.h @@ -29,7 +29,6 @@ #include "preferences.h" #include "preferences_observer.h" #include "preferences_value.h" -#include "task_pool.h" namespace OHOS { namespace NativePreferences { @@ -168,12 +167,11 @@ private: int writeToDiskResult_; bool wasWritten_; - bool handled_; }; std::shared_ptr commitToMemory(); void notifyPreferencesObserver(const MemoryToDiskRequest &request); - void StartLoadFromDisk(); + bool StartLoadFromDisk(); int CheckKey(const std::string &key); int CheckStringValue(const std::string &value); @@ -203,12 +201,6 @@ private: const std::string filePath_; const std::string backupPath_; const std::string brokenPath_; - // Task pool - /* max threads of the task pool. */ - static constexpr int MAX_TP_THREADS = 10; - /* min threads of the task pool. */ - static constexpr int MIN_TP_THREADS = 1; - TaskPool taskPool_; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/include/task_executor.h b/preferences/frameworks/native/include/task_executor.h new file mode 100644 index 0000000000000000000000000000000000000000..38b44a65884e4e569de68725c11fec6651426f0f --- /dev/null +++ b/preferences/frameworks/native/include/task_executor.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 PREFERENCES_TASK_EXECUTOR_H +#define PREFERENCES_TASK_EXECUTOR_H +#include + +#include "task_scheduler.h" +namespace OHOS { +namespace NativePreferences { +class TaskExecutor { +public: + API_LOCAL static TaskExecutor &GetInstance(); + API_LOCAL bool Execute(TaskScheduler::Task &&task); + +private: + TaskExecutor(); + ~TaskExecutor(); + + std::shared_ptr pool_; +}; +} // namespace NativePreferences +} // namespace OHOS +#endif // PREFERENCES_TASK_EXECUTOR_H diff --git a/preferences/frameworks/native/include/task_scheduler.h b/preferences/frameworks/native/include/task_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..b8692fc85a7eebf9a4abc99eb9e7587be061bec0 --- /dev/null +++ b/preferences/frameworks/native/include/task_scheduler.h @@ -0,0 +1,123 @@ +/* + * 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 OHOS_PREFERENCES_FRAMEWORKS_COMMON_TASK_SCHEDULER_H +#define OHOS_PREFERENCES_FRAMEWORKS_COMMON_TASK_SCHEDULER_H +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "visibility.h" +namespace OHOS { +class API_LOCAL TaskScheduler { +public: + using TaskId = uint64_t; + using Time = std::chrono::steady_clock::time_point; + using Task = std::function; + inline static constexpr TaskId INVALID_TASK_ID = static_cast(0ULL); + TaskScheduler(const std::string &name) + { + capacity_ = std::numeric_limits::max(); + isRunning_ = true; + taskId_ = INVALID_TASK_ID; + thread_ = std::make_unique([this, name]() { + auto realName = std::string("task_queue_") + name; + pthread_setname_np(pthread_self(), realName.c_str()); + Loop(); + }); + } + + ~TaskScheduler() + { + isRunning_ = false; + { + std::unique_lock lock(mutex_); + indexes_.clear(); + tasks_.clear(); + } + At(std::chrono::steady_clock::now(), []() {}); + thread_->join(); + } + + // execute task at specific time + TaskId At(const Time &time, Task task) + { + std::unique_lock lock(mutex_); + if (tasks_.size() >= capacity_) { + return INVALID_TASK_ID; + } + auto taskId = GenTaskId(); + auto it = tasks_.insert({ time, std::pair{ task, taskId } }); + if (it == tasks_.begin()) { + condition_.notify_one(); + } + indexes_[taskId] = it; + return taskId; + } + + TaskId Execute(Task task) + { + return At(std::chrono::steady_clock::now(), std::move(task)); + } + +private: + using InnerTask = std::pair, uint64_t>; + void Loop() + { + while (isRunning_) { + std::function exec; + { + std::unique_lock lock(mutex_); + condition_.wait(lock, [this] { return !tasks_.empty(); }); + auto it = tasks_.begin(); + exec = it->second.first; + indexes_.erase(it->second.second); + tasks_.erase(it); + } + + if (exec) { + exec(); + } + } + } + + TaskId GenTaskId() + { + auto taskId = ++taskId_; + if (taskId == INVALID_TASK_ID) { + return ++taskId_; + } + return taskId; + } + + volatile bool isRunning_; + size_t capacity_; + std::multimap tasks_; + std::map indexes_; + std::mutex mutex_; + std::unique_ptr thread_; + std::condition_variable condition_; + std::atomic taskId_; +}; +} // namespace OHOS +#endif // OHOS_PREFERENCES_FRAMEWORKS_COMMON_TASK_SCHEDULER_H diff --git a/mock/innerkits/ipc/ipc_single/include/jni_help.h b/preferences/frameworks/native/include/visibility.h similarity index 59% rename from mock/innerkits/ipc/ipc_single/include/jni_help.h rename to preferences/frameworks/native/include/visibility.h index fb286bfd33459fd462bd5053121e1e0eed67d16f..7c7726f4aae34aec74462562be9762c31fea7e43 100644 --- a/mock/innerkits/ipc/ipc_single/include/jni_help.h +++ b/preferences/frameworks/native/include/visibility.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,14 +13,14 @@ * limitations under the License. */ -#ifndef OHOS_IPC_JNI_HELP_H -#define OHOS_IPC_JNI_HELP_H +#ifndef OHOS_PREFERENCES_FRAMEWORKS_COMMON_VISIBILITY_H +#define OHOS_PREFERENCES_FRAMEWORKS_COMMON_VISIBILITY_H -#include -#include -#include +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif +#ifndef API_LOCAL +#define API_LOCAL __attribute__((visibility("hidden"))) +#endif -namespace OHOS { -jobject JNIHelperGetJavaRemoteObject(JNIEnv *env, const sptr &target); -} // namespace OHOS -#endif // OHOS_IPC_JNI_HELP_H +#endif // OHOS_PREFERENCES_FRAMEWORKS_COMMON_VISIBILITY_H diff --git a/preferences/frameworks/native/src/preferences_helper.cpp b/preferences/frameworks/native/src/preferences_helper.cpp index 3c8e09923d7f8fee1eaa5f67338fc80276ee367a..a6624c5efd8446e491b2d418e2c3a74b7f62d297 100644 --- a/preferences/frameworks/native/src/preferences_helper.cpp +++ b/preferences/frameworks/native/src/preferences_helper.cpp @@ -108,6 +108,7 @@ std::shared_ptr PreferencesHelper::GetPreferences(const std::string std::shared_ptr pref = std::make_shared(filePath); errCode = pref->Init(); if (errCode != E_OK) { + LOG_ERROR("Preferences Init failed."); return nullptr; } prefsCache_.insert(make_pair(realPath, pref)); diff --git a/preferences/frameworks/native/src/preferences_impl.cpp b/preferences/frameworks/native/src/preferences_impl.cpp index 031669677f504da1b84b3f1fa12a8cedffb79bf4..77d81457a766db4b1359026e6a080887f3a356c2 100644 --- a/preferences/frameworks/native/src/preferences_impl.cpp +++ b/preferences/frameworks/native/src/preferences_impl.cpp @@ -20,13 +20,15 @@ #include #include #include +#include +#include "adaptor.h" #include "logger.h" #include "preferences_errno.h" #include "preferences_xml_utils.h" #include "securec.h" - -#include "adaptor.h" +#include "task_executor.h" +#include "task_scheduler.h" namespace OHOS { namespace NativePreferences { @@ -48,7 +50,7 @@ static bool IsFileExist(const std::string &inputPath) PreferencesImpl::PreferencesImpl(const std::string &filePath) : loaded_(false), filePath_(filePath), backupPath_(MakeBackupPath(filePath_)), - brokenPath_(MakeBrokenPath(filePath_)), taskPool_(TaskPool(MAX_TP_THREADS, MIN_TP_THREADS)) + brokenPath_(MakeBrokenPath(filePath_)) { currentMemoryStateGeneration_ = 0; diskStateGeneration_ = 0; @@ -70,26 +72,24 @@ std::string PreferencesImpl::MakeBrokenPath(const std::string &prefPath) PreferencesImpl::~PreferencesImpl() { - taskPool_.Stop(); } int PreferencesImpl::Init() { - int errCode = taskPool_.Start(); - if (errCode != E_OK) { - return errCode; + if (!StartLoadFromDisk()) { + return E_ERROR; } - StartLoadFromDisk(); return E_OK; } -void PreferencesImpl::StartLoadFromDisk() +bool PreferencesImpl::StartLoadFromDisk() { { std::lock_guard lock(mutex_); loaded_ = false; } - taskPool_.Schedule(std::string("PreferencesImpl"), std::bind(&PreferencesImpl::LoadFromDisk, std::ref(*this))); + TaskScheduler::Task task = std::bind(PreferencesImpl::LoadFromDisk, std::ref(*this)); + return TaskExecutor::GetInstance().Execute(std::move(task)); } int PreferencesImpl::CheckKey(const std::string &key) @@ -144,12 +144,7 @@ void PreferencesImpl::AwaitLoadFile() void PreferencesImpl::WriteToDiskFile(std::shared_ptr mcr) { - bool fileExists = false; if (IsFileExist(filePath_)) { - fileExists = true; - } - - if (fileExists) { bool needWrite = CheckRequestValidForStateGeneration(*mcr); if (!needWrite) { mcr->SetDiskWriteResult(false, E_OK); @@ -227,7 +222,7 @@ std::map PreferencesImpl::GetAll() return map_; } -void ReadXmlArrayElement(Element element, std::map &prefMap) +void ReadXmlArrayElement(const Element &element, std::map &prefMap) { if (element.tag_.compare("doubleArray") == 0) { std::vector values; @@ -259,7 +254,7 @@ void ReadXmlArrayElement(Element element, std::map &prefMap, const std::string &prefPath) + const Element &element, std::map &prefMap, const std::string &prefPath) { if (element.tag_.compare("int") == 0) { std::stringstream ss; @@ -306,15 +301,14 @@ bool PreferencesImpl::ReadSettingXml( LOG_ERROR("ReadSettingXml:%{private}s failed!", filePath_.c_str()); return false; } - - for (auto it = settings.begin(); it != settings.end(); it++) { - Element element = *it; + + for (auto &element : settings) { ReadXmlElement(element, prefMap, prefPath); } return true; } -void WriteXmlElement(Element &elem, PreferencesValue value, const std::string filePath) +void WriteXmlElement(Element &elem, const PreferencesValue &value, const std::string &filePath) { if (value.IsDoubleArray()) { elem.tag_ = std::string("doubleArray"); @@ -492,9 +486,9 @@ void PreferencesImpl::Flush() DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::shared_ptr request = commitToMemory(); request->isSyncRequest_ = false; - - taskPool_.Schedule( - std::string("PreferencesImpl"), std::bind(&PreferencesImpl::WriteToDiskFile, std::ref(*this), request)); + TaskScheduler::Task task = std::bind(&PreferencesImpl::WriteToDiskFile, std::ref(*this), request); + TaskExecutor::GetInstance().Execute(std::move(task)); + notifyPreferencesObserver(*request); } @@ -502,15 +496,11 @@ int PreferencesImpl::FlushSync() { std::shared_ptr request = commitToMemory(); request->isSyncRequest_ = true; - - taskPool_.Schedule( - std::string("PreferencesImpl"), std::bind(&PreferencesImpl::WriteToDiskFile, std::ref(*this), request)); std::unique_lock lock(request->reqMutex_); - request->reqCond_.wait(lock, [request] { return request->handled_; }); + WriteToDiskFile(request); if (request->wasWritten_) { LOG_DEBUG("%{private}s:%{public}" PRId64 " written", filePath_.c_str(), request->memoryStateGeneration_); } - notifyPreferencesObserver(*request); return request->writeToDiskResult_; } @@ -559,7 +549,6 @@ PreferencesImpl::MemoryToDiskRequest::MemoryToDiskRequest( preferencesObservers_ = preferencesObservers; memoryStateGeneration_ = memStataGeneration; isSyncRequest_ = false; - handled_ = false; wasWritten_ = false; writeToDiskResult_ = E_ERROR; } @@ -568,7 +557,6 @@ void PreferencesImpl::MemoryToDiskRequest::SetDiskWriteResult(bool wasWritten, i { writeToDiskResult_ = result; wasWritten_ = wasWritten; - handled_ = true; reqCond_.notify_one(); } } // End of namespace NativePreferences diff --git a/preferences/frameworks/native/src/task_executor.cpp b/preferences/frameworks/native/src/task_executor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8d4c6f553f37b59dc27ab639250699d8c6be543a --- /dev/null +++ b/preferences/frameworks/native/src/task_executor.cpp @@ -0,0 +1,46 @@ +/* +* 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 "task_executor.h" + +namespace OHOS { +namespace NativePreferences { +TaskExecutor &TaskExecutor::GetInstance() +{ + static TaskExecutor instance; + return instance; +} + +bool TaskExecutor::Execute(TaskScheduler::Task &&task) +{ + if (pool_ == nullptr) { + return false; + } + pool_->Execute(std::move(task)); + return true; +} + +TaskExecutor::TaskExecutor() +{ + pool_ = std::make_shared("preferences"); +} + +TaskExecutor::~TaskExecutor() +{ + if (pool_ != nullptr) { + pool_ = nullptr; + } +} +} // namespace NativePreferences +} // namespace OHOS diff --git a/preferences/interfaces/inner_api/BUILD.gn b/preferences/interfaces/inner_api/BUILD.gn index 7ee913a53a1b3db9ceb97adf8e3ea6839e9ce293..e0210d6b7ef3f5bf519cce611df8255b48cf3ecd 100644 --- a/preferences/interfaces/inner_api/BUILD.gn +++ b/preferences/interfaces/inner_api/BUILD.gn @@ -35,8 +35,7 @@ base_sources = [ "${preferences_native_path}/src/preferences_observer.cpp", "${preferences_native_path}/src/preferences_value.cpp", "${preferences_native_path}/src/preferences_xml_utils.cpp", - "${preferences_native_path}/src/task_pool.cpp", - "${preferences_native_path}/src/task_queue.cpp", + "${preferences_native_path}/src/task_executor.cpp", ] ohos_shared_library("native_preferences") { diff --git a/relational_store/frameworks/js/napi/common/src/js_utils.cpp b/relational_store/frameworks/js/napi/common/src/js_utils.cpp index baf7b22579e352e9a5ef6b2ed5695004f4cb0cd2..b87b3deed6a9acc884994678ec716e5494763285 100644 --- a/relational_store/frameworks/js/napi/common/src/js_utils.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_utils.cpp @@ -26,7 +26,11 @@ std::string JSUtils::Convert2String(napi_env env, napi_value jsStr, bool useDefa str_buffer_size = (useDefaultBufSize && (str_buffer_size > DEFAULT_BUF_SIZE)) ? (DEFAULT_BUF_SIZE + BUF_CACHE_MARGIN) : (str_buffer_size + BUF_CACHE_MARGIN); - char *buf = new char[str_buffer_size]; + char *buf = new (std::nothrow) char[str_buffer_size]; + if (buf == nullptr) { + LOG_ERROR("JSUtils::Convert2String new failed, buf is nullptr"); + return ""; + } size_t len = 0; napi_get_value_string_utf8(env, jsStr, buf, str_buffer_size, &len); buf[len] = 0; @@ -37,7 +41,11 @@ std::string JSUtils::Convert2String(napi_env env, napi_value jsStr, bool useDefa int32_t JSUtils::Convert2String(napi_env env, napi_value jsStr, std::string &output) { - char *str = new char[MAX_VALUE_LENGTH + 1]; + char *str = new (std::nothrow) char[MAX_VALUE_LENGTH + 1]; + if (str == nullptr) { + LOG_ERROR("JSUtils::Convert2String new failed, str is nullptr"); + return ERR; + } size_t valueSize = 0; napi_status status = napi_get_value_string_utf8(env, jsStr, str, MAX_VALUE_LENGTH, &valueSize); if (status != napi_ok) { diff --git a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp index 848825b0314992261c0819bec3c5d7c04764bc84..1089e67ddf3961faab05a5697a0b2c14cb8308fd 100644 --- a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp +++ b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp @@ -91,7 +91,11 @@ napi_value DataAbilityPredicatesProxy::New(napi_env env, napi_callback_info info NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); if (is_constructor) { - auto *proxy = new DataAbilityPredicatesProxy(); + auto *proxy = new (std::nothrow) DataAbilityPredicatesProxy(); + if (proxy == nullptr) { + LOG_ERROR("DataAbilityPredicatesProxy::New new failed, proxy is nullptr"); + return nullptr; + } napi_status status = napi_wrap(env, thiz, proxy, DataAbilityPredicatesProxy::Destructor, nullptr, nullptr); if (status != napi_ok) { LOG_ERROR("DataAbilityPredicatesProxy::New napi_wrap failed! napi_status:%{public}d!", status); diff --git a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h index f4dda5a29d4fc8c38454458651c0b9cf71b4b0a8..35430275a6f10c54cd478ad64b71a9add3b06e2f 100644 --- a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h +++ b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h @@ -26,7 +26,6 @@ constexpr int APIVERSION_V9 = 9; constexpr int APIVERSION_8 = 8; constexpr int E_PARAM_ERROR = 401; - constexpr int E_INNER_ERROR = 14800000; constexpr int E_DB_INVALID = 14800010; @@ -42,7 +41,7 @@ constexpr int E_RESULT_GOTO_ERROR = 14800012; napi_throw_error((env), nullptr, "error message is empty"); \ return retVal; \ } \ - if (((version) > (APIVERSION_8)) || ((error->GetCode()) == (401))) { \ + if (((version) > (APIVERSION_8)) || ((error->GetCode()) == (401))) { \ LOG_ERROR("throw error: code = %{public}d , message = %{public}s, version= %{public}d", \ error->GetCode(), error->GetMessage().c_str(), version); \ napi_throw_error((env), std::to_string(error->GetCode()).c_str(), error->GetMessage().c_str()); \ diff --git a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_store.h index 9302486ee8d53448f38d78fb7b79abf77012dece..7cfcc6fbcdd9a4cf8e6188b85be5cb389e81ba8c 100644 --- a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_store.h @@ -49,10 +49,8 @@ private: static napi_value Insert(napi_env env, napi_callback_info info); static napi_value BatchInsert(napi_env env, napi_callback_info info); static napi_value Query(napi_env env, napi_callback_info info); - static napi_value RemoteQuery(napi_env env, napi_callback_info info); static napi_value QuerySql(napi_env env, napi_callback_info info); static napi_value ExecuteSql(napi_env env, napi_callback_info info); - static napi_value Backup(napi_env env, napi_callback_info info); static napi_value Count(napi_env env, napi_callback_info info); static napi_value Replace(napi_env env, napi_callback_info info); static napi_value Attach(napi_env env, napi_callback_info info); @@ -68,7 +66,6 @@ private: static napi_value IsOpen(napi_env env, napi_callback_info info); static napi_value GetVersion(napi_env env, napi_callback_info info); static napi_value SetVersion(napi_env env, napi_callback_info info); - static napi_value Restore(napi_env env, napi_callback_info info); static napi_value SetDistributedTables(napi_env env, napi_callback_info info); static napi_value ObtainDistributedTableName(napi_env env, napi_callback_info info); static napi_value Sync(napi_env env, napi_callback_info info); diff --git a/relational_store/frameworks/js/napi/rdb/mock/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/rdb/mock/include/napi_rdb_store.h index b0bad0952276bedf5a590b51edfa3e6a9cc0c772..f0f862bb076dbf812ad70ea81275f444326450f1 100644 --- a/relational_store/frameworks/js/napi/rdb/mock/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/rdb/mock/include/napi_rdb_store.h @@ -49,7 +49,6 @@ private: static napi_value Query(napi_env env, napi_callback_info info); static napi_value QuerySql(napi_env env, napi_callback_info info); static napi_value ExecuteSql(napi_env env, napi_callback_info info); - static napi_value Backup(napi_env env, napi_callback_info info); static napi_value Count(napi_env env, napi_callback_info info); static napi_value Replace(napi_env env, napi_callback_info info); static napi_value Attach(napi_env env, napi_callback_info info); @@ -65,7 +64,6 @@ private: static napi_value IsOpen(napi_env env, napi_callback_info info); static napi_value GetVersion(napi_env env, napi_callback_info info); static napi_value SetVersion(napi_env env, napi_callback_info info); - static napi_value Restore(napi_env env, napi_callback_info info); std::mutex mutex_; std::shared_ptr rdbStore_; }; diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp index aa59249b448313f358599ac3bc12da9775fc0af9..541607578f28687aac2b44834491be433453a245 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp @@ -128,7 +128,11 @@ napi_value RdbPredicatesProxy::InnerNew(napi_env env, napi_callback_info info, i std::string tableName = JSUtils::Convert2String(env, args[0]); RDB_NAPI_ASSERT_FROMV9( env, !tableName.empty(), std::make_shared("name", "a non empty string."), version); - auto *proxy = new RdbPredicatesProxy(tableName); + auto *proxy = new (std::nothrow) RdbPredicatesProxy(tableName); + if (proxy == nullptr) { + LOG_ERROR("RdbPredicatesProxy::InnerNew new failed, proxy is nullptr"); + return nullptr; + } napi_status status = napi_wrap(env, thiz, proxy, RdbPredicatesProxy::Destructor, nullptr, nullptr); if (status != napi_ok) { LOG_ERROR("RdbPredicatesProxy::InnerNew napi_wrap failed! napi_status:%{public}d!", status); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp index e96585c44b49b57eac8afdedb6924f92ad585ff8..80bb044cbb6889de8967c45b35a8515001211506 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp @@ -157,12 +157,8 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("batchInsert", BatchInsert), DECLARE_NAPI_FUNCTION("querySql", QuerySql), DECLARE_NAPI_FUNCTION("query", Query), -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) - DECLARE_NAPI_FUNCTION("remoteQuery", RemoteQuery), -#endif DECLARE_NAPI_FUNCTION("executeSql", ExecuteSql), DECLARE_NAPI_FUNCTION("replace", Replace), - DECLARE_NAPI_FUNCTION("backup", Backup), DECLARE_NAPI_FUNCTION("count", Count), DECLARE_NAPI_FUNCTION("addAttach", Attach), DECLARE_NAPI_FUNCTION("beginTransaction", BeginTransaction), @@ -171,7 +167,6 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("queryByStep", QueryByStep), DECLARE_NAPI_FUNCTION("getVersion", GetVersion), DECLARE_NAPI_FUNCTION("setVersion", SetVersion), - DECLARE_NAPI_FUNCTION("restore", Restore), DECLARE_NAPI_GETTER("isInTransaction", IsInTransaction), DECLARE_NAPI_GETTER("isOpen", IsOpen), DECLARE_NAPI_GETTER("path", GetPath), @@ -757,45 +752,6 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) -napi_value RdbStoreProxy::RemoteQuery(napi_env env, napi_callback_info info) -{ - LOG_DEBUG("RdbStoreProxy::RemoteQuery start"); - auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - std::shared_ptr paramNumError = std::make_shared("4 or 5"); - RDB_CHECK_RETURN_CALL_RESULT(argc == 4 || argc == 5, context->SetError(paramNumError)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDevice(env, argv[0], context)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[1], context)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[2], context)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseColumns(env, argv[3], context)); - ParserThis(env, self, context); - return OK; - }; - auto exec = [context]() { - LOG_DEBUG("RdbStoreProxy::RemoteQuery Async"); - RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - context->newResultSet = - obj->rdbStore_->RemoteQuery(context->device, *(context->rdbPredicates), context->columns); - LOG_DEBUG("RdbStoreProxy::RemoteQuery result is nullptr ? %{public}d", (context->newResultSet == nullptr)); - return (context->newResultSet != nullptr) ? OK : ERR; - }; - auto output = [context](napi_env env, napi_value &result) -> int { - if (context->newResultSet == nullptr) { - LOG_DEBUG("RdbStoreProxy::RemoteQuery result is nullptr"); - return ERR; - } - result = ResultSetProxy::NewInstance(env, context->newResultSet, context->apiversion); - LOG_DEBUG("RdbStoreProxy::RemoteQuery end"); - return (result != nullptr) ? OK : ERR; - }; - context->SetAction(env, info, input, exec, output); - - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); -} -#endif - napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); @@ -947,35 +903,6 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) -{ - LOG_DEBUG("RdbStoreProxy::Backup start"); - auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - std::shared_ptr paramNumError = std::make_shared("1 or 2"); - RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context)); - ParserThis(env, self, context); - return OK; - }; - auto exec = [context]() { - LOG_DEBUG("RdbStoreProxy::Backup Async"); - RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - int errCode = obj->rdbStore_->Backup(context->tableName, context->newKey); - LOG_DEBUG("RdbStoreProxy::Backup errCode is: %{public}d", errCode); - return (errCode == E_OK) ? OK : ERR; - }; - auto output = [context](napi_env env, napi_value &result) -> int { - napi_status status = napi_get_undefined(env, &result); - LOG_DEBUG("RdbStoreProxy::Backup end"); - return (status == napi_ok) ? OK : ERR; - }; - context->SetAction(env, info, input, exec, output); - - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); -} - napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) { LOG_DEBUG("RdbStoreProxy::Attach start"); @@ -1171,36 +1098,6 @@ napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info) return nullptr; } -napi_value RdbStoreProxy::Restore(napi_env env, napi_callback_info info) -{ - LOG_DEBUG("RdbStoreProxy::Restore start"); - auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - std::shared_ptr paramNumError = std::make_shared("1 or 2"); - RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError)); - RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSrcName(env, argv[0], context)); - ParserThis(env, self, context); - return OK; - }; - auto exec = [context]() { - LOG_DEBUG("RdbStoreProxy::Restore Async"); - RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - int errCode = 0; - errCode = obj->rdbStore_->Restore(context->srcName, context->newKey); - LOG_DEBUG("RdbStoreProxy::Restore errCode is : %{public}d", errCode); - return (errCode == E_OK) ? OK : ERR; - }; - auto output = [context](napi_env env, napi_value &result) -> int { - napi_status status = napi_get_undefined(env, &result); - LOG_DEBUG("RdbStoreProxy::Restore end"); - return (status == napi_ok) ? OK : ERR; - }; - context->SetAction(env, info, input, exec, output); - - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); -} - #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info info) { @@ -1216,9 +1113,9 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - bool res = obj->rdbStore_->SetDistributedTables(context->tablesName); + int res = obj->rdbStore_->SetDistributedTables(context->tablesName); LOG_DEBUG("RdbStoreProxy::SetDistributedTables res is : %{public}d", res); - return res ? OK : ERR; + return res == E_OK ? OK : ERR; }; auto output = [context](napi_env env, napi_value &result) -> int { napi_status status = napi_get_undefined(env, &result); @@ -1246,8 +1143,10 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - auto name = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName); - LOG_INFO("RdbStoreProxy::ObtainDistributedTableName name is empty ? : %{public}d", name.empty()); + int errCode = E_ERROR; + auto name = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName, errCode); + LOG_INFO("RdbStoreProxy::ObtainDistributedTableName name is empty ? : %{public}d, errCode is %{public}d", + name.empty(), errCode); context->tableName = name; return name.empty() ? ERR : OK; }; @@ -1281,10 +1180,10 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) SyncOption option; option.mode = static_cast(context->enumArg); option.isBlock = true; - bool res = obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), + int res = obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), [context](const SyncResult &result) { context->syncResult = result; }); LOG_INFO("RdbStoreProxy::Sync res is : %{public}d", res); - return res ? OK : ERR; + return res == E_OK ? OK : ERR; }; auto output = [context](napi_env env, napi_value &result) -> int { result = JSUtils::Convert2JSValue(env, context->syncResult); @@ -1329,7 +1228,8 @@ void RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *arg SubscribeOption option; option.mode = static_cast(mode); auto observer = std::make_shared(env, argv[1]); - if (!rdbStore_->Subscribe(option, observer.get())) { + int errCode = rdbStore_->Subscribe(option, observer.get()); + if (errCode != E_OK) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: subscribe failed"); return; } diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp index 5ed14e1ecca2025e70f6a45f2adcf59f9f22dbaf..87dd8a47b3f0e7d6d6e9a2867c65f9832b931568 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp @@ -163,7 +163,11 @@ napi_value ResultSetProxy::InnerInitialize(napi_env env, napi_callback_info info { napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr)); - auto *proxy = new ResultSetProxy(); + auto *proxy = new (std::nothrow) ResultSetProxy(); + if (proxy == nullptr) { + LOG_ERROR("ResultSetProxy::InnerInitialize new failed, proxy is nullptr"); + return nullptr; + } proxy->apiversion = version; auto finalize = [](napi_env env, void *data, void *hint) { ResultSetProxy *proxy = reinterpret_cast(data); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp index 327ad774680935223185ea97b8a93a31caa57792..647faeb090ffa490e07024518d63a235b94c1344 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp @@ -73,7 +73,11 @@ __attribute__((visibility("default"))) napi_value NAPI_OHOS_Data_RdbJsKit_Values __attribute__((visibility("default"))) ValuesBucket *NAPI_OHOS_Data_RdbJsKit_ValuesBucketProxy_GetNativeObject( napi_env env, napi_value &arg) { - ValuesBucket *valuesBucket = new ValuesBucket; + ValuesBucket *valuesBucket = new (std::nothrow) ValuesBucket; + if (valuesBucket == nullptr) { + LOG_ERROR("ValuesBucket new failed, valuesBucket is nullptr"); + return nullptr; + } napi_value keys = 0; napi_get_property_names(env, arg, &keys); uint32_t arrLen = 0; diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h index f0ef6f7d2ca532ccc86778032d55bf7f6db59741..37ba8fd3180c2ca52494a25bb08aebe0a31e6372 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h @@ -36,6 +36,7 @@ const static std::map ERROR_MAPS = { { NativeRdb::E_WAL_SIZE_OVER_LIMIT, "The WAL file size over default limit." }, { NativeRdb::E_EMPTY_FILE_NAME, "Failed to open database by database corrupted." }, { NativeRdb::E_INVALID_FILE_PATH, "Failed to open database by database corrupted" }, + { NativeRdb::E_NOT_SUPPORTED, "Capability not supported" }, { E_RESULT_GOTO_ERROR, "The result set is empty or the specified location is invalid." }, { E_RESULT_GET_ERROR, "The column value is null or the column type is incompatible." }, }; diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h index 7ee322775dc43d58f438a33c8cade5f0520d76b2..7be65cf472eda424b0f48e5f1674e9dd0b81e9dc 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h @@ -75,8 +75,8 @@ private: static constexpr int MIN_ON_EVENT_ARG_NUM = 2; static constexpr int MAX_ON_EVENT_ARG_NUM = 5; - void OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv); - void OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv); + int OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv); + int OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv); std::mutex mutex_; bool isSystemAppCalled_ = false; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp index 4d30a1c5682574e9b1503994ba6d83188199553a..2eb54a2a39fbc6f5b64e0621d79a6be91cb6f070 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp @@ -101,7 +101,11 @@ napi_value RdbPredicatesProxy::New(napi_env env, napi_callback_info info) RDB_NAPI_ASSERT(env, valueType == napi_string, std::make_shared("name", "not empty")); std::string tableName = JSUtils::Convert2String(env, args[0]); RDB_NAPI_ASSERT(env, !tableName.empty(), std::make_shared("name", "not empty")); - auto *proxy = new RdbPredicatesProxy(tableName); + auto *proxy = new (std::nothrow) RdbPredicatesProxy(tableName); + if (proxy == nullptr) { + LOG_ERROR("RdbPredicatesProxy::New new failed, proxy is nullptr"); + return nullptr; + } napi_status status = napi_wrap(env, thiz, proxy, RdbPredicatesProxy::Destructor, nullptr, nullptr); if (status != napi_ok) { LOG_ERROR("RdbPredicatesProxy::New napi_wrap failed! napi_status:%{public}d!", status); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp index c10e46ba782e89171a015f2d4b7322179d006e37..09c0d1e86c50e063f06b25862d5dd56edc548064 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp @@ -81,7 +81,7 @@ struct RdbStoreContext : public Context { std::shared_ptr rdbPredicates = nullptr; RdbStoreContext() - : predicatesProxy(nullptr), int64Output(0), intOutput(0), enumArg(0), + : predicatesProxy(nullptr), int64Output(0), intOutput(0), enumArg(-1), conflictResolution(NativeRdb::ConflictResolution::ON_CONFLICT_NONE) { } @@ -276,7 +276,11 @@ int ParseTablesName(const napi_env &env, const napi_value &arg, std::shared_ptr< int ParseSyncModeArg(const napi_env &env, const napi_value &arg, std::shared_ptr context) { - napi_get_value_int32(env, arg, &context->enumArg); + napi_valuetype type = napi_undefined; + napi_typeof(env, arg, &type); + CHECK_RETURN_SET(type == napi_number, std::make_shared("mode", "a SyncMode Type.")); + napi_status status = napi_get_value_int32(env, arg, &context->enumArg); + CHECK_RETURN_SET(status == napi_ok, std::make_shared("mode", "a SyncMode Type.")); bool checked = context->enumArg == 0 || context->enumArg == 1; CHECK_RETURN_SET(checked, std::make_shared("mode", "a SyncMode.")); @@ -622,10 +626,11 @@ napi_value RdbStoreProxy::RemoteQuery(napi_env env, napi_callback_info info) auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::RemoteQuery Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + int errCode = E_ERROR; context->newResultSet = - obj->rdbStore_->RemoteQuery(context->device, *(context->rdbPredicates), context->columns); - LOG_DEBUG("RdbStoreProxy::RemoteQuery result is nullptr ? %{public}d", (context->newResultSet == nullptr)); - return (context->newResultSet != nullptr) ? E_OK : E_ERROR; + obj->rdbStore_->RemoteQuery(context->device, *(context->rdbPredicates), context->columns, errCode); + LOG_DEBUG("RemoteQuerry ret is %{public}d.", errCode); + return errCode; }; auto output = [context](napi_env env, napi_value &result) { result = ResultSetProxy::NewInstance(env, context->newResultSet); @@ -1061,7 +1066,7 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - return obj->rdbStore_->SetDistributedTables(context->tablesNames) ? E_OK : E_ERROR; + return obj->rdbStore_->SetDistributedTables(context->tablesNames); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); @@ -1087,8 +1092,9 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - context->tableName = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName); - return context->tableName.empty() ? E_OK : E_ERROR; + int errCode = E_ERROR; + context->tableName = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName, errCode); + return errCode; }; auto output = [context](napi_env env, napi_value &result) { std::string table = context->tableName; @@ -1118,10 +1124,8 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) SyncOption option; option.mode = static_cast(context->enumArg); option.isBlock = true; - bool res = obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), + return obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), [context](const SyncResult &result) { context->syncResult = result; }); - LOG_INFO("RdbStoreProxy::Sync res is : %{public}d", res); - return res ? E_OK : E_ERROR; }; auto output = [context](napi_env env, napi_value &result) { result = JSUtils::Convert2JSValue(env, context->syncResult); @@ -1134,26 +1138,26 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -void RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv) +int RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv) { napi_valuetype type; napi_typeof(env, argv[0], &type); if (type != napi_number) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: first argument is not number"); - return; + return ERR; } int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX; napi_get_value_int32(env, argv[0], &mode); if (mode < 0 || mode >= SubscribeMode::SUBSCRIBE_MODE_MAX) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: first argument value is invalid"); - return; + return ERR; } LOG_INFO("RdbStoreProxy::OnDataChangeEvent: mode=%{public}d", mode); napi_typeof(env, argv[1], &type); if (type != napi_function) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: second argument is not function"); - return; + return ERR; } std::lock_guard lockGuard(mutex_); @@ -1162,39 +1166,38 @@ void RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *arg }); if (result) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: duplicate subscribe"); - return; + return ERR; } SubscribeOption option; option.mode = static_cast(mode); auto observer = std::make_shared(env, argv[1]); - if (!rdbStore_->Subscribe(option, observer.get())) { - LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: subscribe failed"); - return; - } + int errCode = rdbStore_->Subscribe(option, observer.get()); + LOG_DEBUG("Subscribe ret is %{public}d.", errCode); + RDB_NAPI_ASSERT_BASE(env, errCode == E_OK, std::make_shared(errCode), ERR); observers_[mode].push_back(observer); - LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: subscribe success"); + return OK; } -void RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv) +int RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv) { napi_valuetype type; napi_typeof(env, argv[0], &type); if (type != napi_number) { LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: first argument is not number"); - return; + return ERR; } int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX; napi_get_value_int32(env, argv[0], &mode); if (mode < 0 || mode >= SubscribeMode::SUBSCRIBE_MODE_MAX) { LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: first argument value is invalid"); - return; + return ERR; } LOG_INFO("RdbStoreProxy::OffDataChangeEvent: mode=%{public}d", mode); napi_typeof(env, argv[1], &type); if (type != napi_function) { LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: second argument is not function"); - return; + return ERR; } SubscribeOption option; @@ -1202,13 +1205,15 @@ void RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *ar std::lock_guard lockGuard(mutex_); for (auto it = observers_[mode].begin(); it != observers_[mode].end(); it++) { if (**it == argv[1]) { - rdbStore_->UnSubscribe(option, it->get()); + int errCode = rdbStore_->UnSubscribe(option, it->get()); observers_[mode].erase(it); - LOG_INFO("RdbStoreProxy::OffDataChangeEvent: unsubscribe success"); - return; + LOG_INFO("unsubscribe err is %{public}d.", errCode); + RDB_NAPI_ASSERT_BASE(env, errCode == E_OK, std::make_shared(errCode), ERR); + return OK; } } LOG_INFO("RdbStoreProxy::OffDataChangeEvent: not found"); + return ERR; } napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) @@ -1228,7 +1233,9 @@ napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) std::string event = JSUtils::Convert2String(env, argv[0]); if (event == "dataChange") { - proxy->OnDataChangeEvent(env, argc - 1, argv + 1); + if (proxy->OnDataChangeEvent(env, argc - 1, argv + 1) != OK) { + return nullptr; + } } LOG_INFO("RdbStoreProxy::OnEvent end"); @@ -1252,7 +1259,9 @@ napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) std::string event = JSUtils::Convert2String(env, argv[0]); if (event == "dataChange") { - proxy->OffDataChangeEvent(env, argc - 1, argv + 1); + if (proxy->OffDataChangeEvent(env, argc - 1, argv + 1) != OK) { + return nullptr; + } } LOG_INFO("RdbStoreProxy::OffEvent end"); @@ -1260,4 +1269,4 @@ napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) } #endif } // namespace RelationalStoreJsKit -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp index ed36e5ad235f7d1522026b92fc277cbbf332af4b..de7a07ebb27a8b6bc982ef91a755547366c303d3 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp @@ -115,7 +115,11 @@ napi_value ResultSetProxy::Initialize(napi_env env, napi_callback_info info) { napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr)); - auto *proxy = new ResultSetProxy(); + auto *proxy = new (std::nothrow) ResultSetProxy(); + if (proxy == nullptr) { + LOG_ERROR("ResultSetProxy::Initialize new failed, proxy is nullptr"); + return nullptr; + } auto finalize = [](napi_env env, void *data, void *hint) { ResultSetProxy *proxy = reinterpret_cast(data); delete proxy; diff --git a/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp b/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp index 7ca0ce4e449c92f53b36e762f36691794afeb269..7a3baad307fd9ae85140897e1247f9379dadc7c3 100644 --- a/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp +++ b/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp @@ -33,9 +33,7 @@ std::shared_ptr ISharedResultSetProxy::CreateProxy(MessagePa return nullptr; } sptr result = iface_cast(remoter); - if (result->sharedBlock_ == nullptr) { - AppDataFwk::SharedBlock::ReadMessageParcel(parcel, result->sharedBlock_); - } + result->Unmarshalling(parcel); return std::shared_ptr(result.GetRefPtr(), [keep = result] (AbsSharedResultSet *) {}); } diff --git a/relational_store/frameworks/native/dataability/src/ishared_result_set_stub.cpp b/relational_store/frameworks/native/dataability/src/ishared_result_set_stub.cpp index 5b16227ac9653831ca3702f26ee5527e657e332f..357271a75a035b10077c52568ebccfc796f8a1dd 100644 --- a/relational_store/frameworks/native/dataability/src/ishared_result_set_stub.cpp +++ b/relational_store/frameworks/native/dataability/src/ishared_result_set_stub.cpp @@ -36,9 +36,7 @@ sptr ISharedResultSetStub::CreateStub(std::shared_ptrAsObject()); - if (result->sharedBlock_ != nullptr) { - result->sharedBlock_->WriteMessageParcel(parcel); - } + result->Marshalling(parcel); return stub; } diff --git a/relational_store/frameworks/native/rdb/include/rdb_manager.h b/relational_store/frameworks/native/rdb/include/rdb_manager.h index 07185fbb52ee75efe3abda6fa5944fb61f36f9c3..5167069ad2c899dd85c8ac2e4de684be63147b0a 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_manager.h +++ b/relational_store/frameworks/native/rdb/include/rdb_manager.h @@ -26,7 +26,7 @@ namespace OHOS::DistributedRdb { class RdbManager { public: - static std::shared_ptr GetRdbService(const RdbSyncerParam& param); + static int GetRdbService(const RdbSyncerParam& param, std::shared_ptr &service); }; } // namespace OHOS::DistributedRdb #endif diff --git a/relational_store/frameworks/native/rdb/include/rdb_manager_impl.h b/relational_store/frameworks/native/rdb/include/rdb_manager_impl.h index f2c20f3eade0c35c0b1211b6140364b0fe6f1668..13e5ea0be3880aafbdf7a64f9953d32f8d166043 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_manager_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_manager_impl.h @@ -39,7 +39,7 @@ public: static RdbManagerImpl &GetInstance(); - std::shared_ptr GetRdbService(const RdbSyncerParam& param); + int GetRdbService(const RdbSyncerParam& param, std::shared_ptr &service); void OnRemoteDied(); @@ -61,8 +61,6 @@ private: ~RdbManagerImpl(); - sptr GetRdbService(); - void ResetServiceHandle(); static std::shared_ptr GetDistributedDataManager(); diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h index df19a713c2abf9fde9b88a2ab497ca874029f68b..149ac934ad703d63b5390d992b10a12cceb0732e 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -26,7 +26,6 @@ #include "rdb_store_config.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" -#include "store_session.h" #include "transaction_observer.h" namespace OHOS::NativeRdb { @@ -98,17 +97,17 @@ public: int Delete(int &deletedRows, const AbsRdbPredicates &predicates) override; std::shared_ptr RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, - const std::vector &columns) override; + const std::vector &columns, int &errCode) override; - bool SetDistributedTables(const std::vector& tables) override; + int SetDistributedTables(const std::vector& tables) override; - std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; + std::string ObtainDistributedTableName(const std::string& device, const std::string& table, int &errCode) override; - bool Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const SyncCallback& callback) override; + int Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const SyncCallback& callback) override; - bool Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; + int Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; - bool UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; + int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; // user must use UDID bool DropDeviceData(const std::vector& devices, const DropOption& option) override; @@ -124,8 +123,6 @@ private: SqliteConnectionPool *connectionPool; static const int MAX_IDLE_SESSION_SIZE = 5; std::mutex sessionMutex; - std::map, int>> threadMap; - std::list> idleSessions; bool isOpen; std::string path; std::string orgPath; diff --git a/relational_store/frameworks/native/rdb/include/rdb_types_util.h b/relational_store/frameworks/native/rdb/include/rdb_types_util.h index 018a78f270c0022f0c4678c809779aa84b718e1a..b437327f79d682552c5e4b50f814f690a937988e 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_types_util.h +++ b/relational_store/frameworks/native/rdb/include/rdb_types_util.h @@ -17,15 +17,12 @@ #define DISTRIBUTED_RDB_RDB_TYPES_UTIL_H #include "itypes_util.h" #include "rdb_types.h" -#include "value_object.h" -#include "values_bucket.h" +#include "rdb_visibility.h" namespace OHOS::ITypesUtil { using SyncerParam = DistributedRdb::RdbSyncerParam; using SyncOption = DistributedRdb::SyncOption; using RdbPredicates = DistributedRdb::RdbPredicates; using RdbOperation = DistributedRdb::RdbPredicateOperation; -using ValueObject = NativeRdb::ValueObject; -using ValuesBucket = NativeRdb::ValuesBucket; template<> RDB_API_EXPORT bool Marshalling(const SyncerParam &input, MessageParcel &data); template<> @@ -42,13 +39,5 @@ template<> RDB_API_EXPORT bool Marshalling(const RdbOperation &input, MessageParcel &data); template<> RDB_API_EXPORT bool Unmarshalling(RdbOperation &output, MessageParcel &data); -template<> -bool Marshalling(const ValueObject &input, MessageParcel &data); -template<> -bool Unmarshalling(ValueObject &output, MessageParcel &data); -template<> -bool Marshalling(const ValuesBucket &input, MessageParcel &data); -template<> -bool Unmarshalling(ValuesBucket &output, MessageParcel &data); } #endif // DISTRIBUTED_RDB_RDB_TYPES_UTIL_H diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h index 6a283a6101143ff974ac78c7fb9e02a1d2552b00..f3dbc0a81c3b5e7f1a7c6bcf13cecc5de7e0fc6d 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h @@ -44,7 +44,7 @@ public: int ChangeDbFileForRestore(const std::string newPath, const std::string backupPath, const std::vector &newKey); std::stack &getTransactionStack(); - void AcquireTransaction(); + int AcquireTransaction(); void ReleaseTransaction(); private: diff --git a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h index 199653da6190697cc64c3f84a9fc5269b559de04..7928de31297c434d877ed53aa9086872e68b98e1 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h @@ -52,7 +52,6 @@ protected: private: int PrepareStep(); - int CheckSession(); void FillSharedBlock(int requiredPos); private: diff --git a/relational_store/frameworks/native/rdb/include/step_result_set.h b/relational_store/frameworks/native/rdb/include/step_result_set.h index 9a7c1fd8208958362a0f2c8a52e33c5615d07381..721405a2090e10acf52e6191d09af70813824d2f 100644 --- a/relational_store/frameworks/native/rdb/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/include/step_result_set.h @@ -54,7 +54,6 @@ public: int PrepareStep(); private: - int CheckSession(); void Reset(); std::shared_ptr rdb; std::string sql; diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h index efd7f3dddd33cc607856108542e8eeae51649953..765306a8ba1d9240b1be66d612a7d5b64f447d89 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h @@ -26,7 +26,6 @@ #include "rdb_store_config.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" -#include "store_session.h" #include "transaction_observer.h" namespace OHOS::NativeRdb { @@ -104,8 +103,6 @@ private: SqliteConnectionPool *connectionPool; static const int MAX_IDLE_SESSION_SIZE = 5; std::mutex sessionMutex; - std::map, int>> threadMap; - std::list> idleSessions; bool isOpen; std::string path; std::string orgPath; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h index 7d02e6846db44fec58d888862cf6055767b5901e..73101e55cd5efefcbf4acb9eec9198329b2734f3 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h @@ -44,7 +44,7 @@ public: int ChangeDbFileForRestore(const std::string newPath, const std::string backupPath, const std::vector &newKey); std::stack &getTransactionStack(); - void AcquireTransaction(); + int AcquireTransaction(); void ReleaseTransaction(); private: diff --git a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h index 209669bcc63a8a702abf6f8205948b045317bb89..85d52516fe20e7dec807597ed8efface1d17c570 100644 --- a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h @@ -54,7 +54,6 @@ public: int PrepareStep(); private: - int CheckSession(); void Reset(); std::shared_ptr rdb; std::string sql; diff --git a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp index b4d3c029b8c9321b888d6d97623b8c4a070107d8..bc13c07960df1c6de663549163cf2926a699f935 100644 --- a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp @@ -407,5 +407,27 @@ int AbsSharedResultSet::CheckState(int columnIndex) return E_OK; } + +bool AbsSharedResultSet::Marshalling(MessageParcel &parcel) +{ + if (sharedBlock_ == nullptr) { + LOG_ERROR("AbsSharedResultSet::Marshalling sharedBlock is null."); + return false; + } + LOG_DEBUG("AbsSharedResultSet::Marshalling sharedBlock."); + return sharedBlock_->WriteMessageParcel(parcel); +} + +bool AbsSharedResultSet::Unmarshalling(MessageParcel &parcel) +{ + if (sharedBlock_ != nullptr) { + return false; + } + int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock_); + if (result < 0) { + LOG_ERROR("AbsSharedResultSet: create from parcel error is %{public}d.", result); + } + return true; +} } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp index 9bcd1fc488a208f73589029570e7a9eaa60d7592..669e0f97810cd9fbbf84dc2dc2700c2d7a367aca 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp @@ -19,10 +19,10 @@ #include "rdb_common.h" #include "rdb_errno.h" #include "rdb_store_impl.h" +#include "rdb_store_manager.h" #include "rdb_trace.h" #include "sqlite_global_config.h" #include "unistd.h" -#include "rdb_store_manager.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) #include "rdb_security_manager.h" @@ -54,7 +54,6 @@ static void DeleteRdbKeyFiles(const std::string &dbFileName) #endif } - int RdbHelper::DeleteRdbStore(const std::string &dbFileName) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); diff --git a/relational_store/frameworks/native/rdb/src/rdb_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_manager.cpp index 76bddfc3e5ad5be2be08b70fd5494be98d97f2e4..261e420f6c9357bdeddff25a7c297708a63a266a 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_manager.cpp @@ -17,8 +17,8 @@ #include "rdb_manager_impl.h" namespace OHOS::DistributedRdb { -std::shared_ptr RdbManager::GetRdbService(const RdbSyncerParam& param) +int RdbManager::GetRdbService(const RdbSyncerParam& param, std::shared_ptr &service) { - return RdbManagerImpl::GetInstance().GetRdbService(param); + return RdbManagerImpl::GetInstance().GetRdbService(param, service); } } // namespace OHOS::DistributedRdb diff --git a/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp index f7f934881257ac265357e32cdaf610aa663f5f21..208c8c2170fefef72145562f25cb59ddd6943db9 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp @@ -26,8 +26,10 @@ #include "irdb_service.h" #include "itypes_util.h" #include "rdb_service_proxy.h" +#include "rdb_errno.h" namespace OHOS::DistributedRdb { +using namespace OHOS::NativeRdb; std::shared_ptr RdbManagerImpl::GetDistributedDataManager() { auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); @@ -78,46 +80,40 @@ RdbManagerImpl& RdbManagerImpl::GetInstance() return manager; } -sptr RdbManagerImpl::GetRdbService() +int RdbManagerImpl::GetRdbService(const RdbSyncerParam& param, std::shared_ptr &service) { + std::lock_guard lock(mutex_); + if (rdbService_ != nullptr) { + service = rdbService_; + return E_OK; + } if (distributedDataMgr_ == nullptr) { distributedDataMgr_ = GetDistributedDataManager(); } if (distributedDataMgr_ == nullptr) { ZLOGE("get distributed data manager failed"); - return nullptr; + return E_ERROR; } auto remote = distributedDataMgr_->GetFeatureInterface("relational_store"); if (remote == nullptr) { ZLOGE("get rdb service failed"); - return nullptr; + return E_NOT_SUPPORTED; } - return iface_cast(remote); -} - -std::shared_ptr RdbManagerImpl::GetRdbService(const RdbSyncerParam& param) -{ - std::lock_guard lock(mutex_); - if (rdbService_ != nullptr) { - return rdbService_; - } - auto service = GetRdbService(); - if (service == nullptr) { - return nullptr; - } - if (service->InitNotifier(param) != RDB_OK) { + sptr serviceProxy = iface_cast(remote); + if (serviceProxy->InitNotifier(param) != RDB_OK) { ZLOGE("init notifier failed"); - return nullptr; + return E_ERROR; } - sptr serviceBase = service; + sptr serviceBase = serviceProxy; LinkToDeath(serviceBase->AsObject().GetRefPtr()); - rdbService_ = std::shared_ptr(service.GetRefPtr(), [holder = service] (const auto*) {}); + rdbService_ = std::shared_ptr(serviceProxy.GetRefPtr(), [holder = serviceProxy] (const auto*) {}); if (rdbService_ == nullptr) { - return nullptr; + return E_ERROR; } bundleName_ = param.bundleName_; - return rdbService_; + service = rdbService_; + return E_OK; } void RdbManagerImpl::OnRemoteDied() @@ -134,8 +130,9 @@ void RdbManagerImpl::OnRemoteDied() std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME)); RdbSyncerParam param; param.bundleName_ = bundleName_; - auto service = GetRdbService(param); - if (service == nullptr) { + std::shared_ptr service = nullptr; + int errCode = GetRdbService(param, service); + if (errCode != E_OK) { return; } proxy = std::static_pointer_cast(service); diff --git a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp index e060c932329051939c89877d082e82a0631935ec..52f9b05c9137c022f6de0a048c206b3b64fdf75b 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp @@ -1,17 +1,17 @@ /* -* Copyright (c) 2022 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "rdb_security_manager.h" @@ -33,71 +33,71 @@ RdbPassword::RdbPassword() = default; RdbPassword::~RdbPassword() { - (void)Clear(); + (void)Clear(); } bool RdbPassword::operator==(const RdbPassword &input) const { - if (size_ != input.GetSize()) { - return false; - } - return memcmp(data_, input.GetData(), size_) == 0; + if (size_ != input.GetSize()) { + return false; + } + return memcmp(data_, input.GetData(), size_) == 0; } bool RdbPassword::operator!=(const RdbPassword &input) const { - return !(*this == input); + return !(*this == input); } size_t RdbPassword::GetSize() const { - return size_; + return size_; } const uint8_t *RdbPassword::GetData() const { - return data_; + return data_; } int RdbPassword::SetValue(const uint8_t *inputData, size_t inputSize) { - if (inputSize > MAX_PASSWORD_SIZE) { - return E_ERROR; - } - if (inputSize != 0 && inputData == nullptr) { - return E_ERROR; - } - - if (inputSize != 0) { - std::copy(inputData, inputData + inputSize, data_); - } - - size_t filledSize = std::min(size_, MAX_PASSWORD_SIZE); - if (inputSize < filledSize) { - std::fill(data_ + inputSize, data_ + filledSize, UCHAR_MAX); - } - - size_ = inputSize; - return E_OK; + if (inputSize > MAX_PASSWORD_SIZE) { + return E_ERROR; + } + if (inputSize != 0 && inputData == nullptr) { + return E_ERROR; + } + + if (inputSize != 0) { + std::copy(inputData, inputData + inputSize, data_); + } + + size_t filledSize = std::min(size_, MAX_PASSWORD_SIZE); + if (inputSize < filledSize) { + std::fill(data_ + inputSize, data_ + filledSize, UCHAR_MAX); + } + + size_ = inputSize; + return E_OK; } int RdbPassword::Clear() { - return SetValue(nullptr, 0); + return SetValue(nullptr, 0); } int32_t RdbSecurityManager::MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize) { - blob->data = (uint8_t *)malloc(blobSize); - if (blob->data == NULL) { - LOG_ERROR("Blob data is NULL."); - return HKS_FAILURE; - } - return HKS_SUCCESS; + blob->data = (uint8_t *)malloc(blobSize); + if (blob->data == NULL) { + LOG_ERROR("Blob data is NULL."); + return HKS_FAILURE; + } + return HKS_SUCCESS; } int32_t RdbSecurityManager::HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, - const struct HksBlob *inData, struct HksBlob *outData) + const struct HksBlob *inData, struct HksBlob *outData) { struct HksBlob inDataSeg = *inData; uint8_t *lastPtr = inData->data + inData->size - 1; @@ -135,7 +135,7 @@ int32_t RdbSecurityManager::HksLoopUpdate(const struct HksBlob *handle, const st } int32_t RdbSecurityManager::HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, - const struct HksBlob *plainText, struct HksBlob *cipherText) + const struct HksBlob *plainText, struct HksBlob *cipherText) { uint8_t handle[sizeof(uint64_t)] = { 0 }; struct HksBlob handleBlob = { sizeof(uint64_t), handle }; @@ -148,7 +148,7 @@ int32_t RdbSecurityManager::HksEncryptThreeStage(const struct HksBlob *keyAlias, } int32_t RdbSecurityManager::HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, - const struct HksBlob *cipherText, struct HksBlob *plainText) + const struct HksBlob *cipherText, struct HksBlob *plainText) { uint8_t handle[sizeof(uint64_t)] = { 0 }; struct HksBlob handleBlob = { sizeof(uint64_t), handle }; @@ -509,106 +509,106 @@ RdbPassword RdbSecurityManager::GetRdbPassword(KeyFileType keyFile) std::vector RdbSecurityManager::GenerateRootKeyAlias(const std::string &bundleName) { - bundleName_ = bundleName; - if (bundleName_.empty()) { - LOG_ERROR("BundleName is empty!"); - return {}; - } - std::vector rootKeyAlias = - std::vector(RDB_ROOT_KEY_ALIAS_PREFIX, RDB_ROOT_KEY_ALIAS_PREFIX + strlen(RDB_ROOT_KEY_ALIAS_PREFIX)); - rootKeyAlias.insert(rootKeyAlias.end(), bundleName.begin(), bundleName.end()); - return rootKeyAlias; + bundleName_ = bundleName; + if (bundleName_.empty()) { + LOG_ERROR("BundleName is empty!"); + return {}; + } + std::vector rootKeyAlias = + std::vector(RDB_ROOT_KEY_ALIAS_PREFIX, RDB_ROOT_KEY_ALIAS_PREFIX + strlen(RDB_ROOT_KEY_ALIAS_PREFIX)); + rootKeyAlias.insert(rootKeyAlias.end(), bundleName.begin(), bundleName.end()); + return rootKeyAlias; } void RdbSecurityManager::DelRdbSecretDataFile(const std::string &path) { - LOG_INFO("Delete all key files begin."); - std::lock_guard lock(mutex_); - ParsePath(path); - SqliteDatabaseUtils::DeleteFile(keyPath_); - SqliteDatabaseUtils::DeleteFile(keyBakPath_); + LOG_INFO("Delete all key files begin."); + std::lock_guard lock(mutex_); + ParsePath(path); + SqliteDatabaseUtils::DeleteFile(keyPath_); + SqliteDatabaseUtils::DeleteFile(keyBakPath_); } bool RdbSecurityManager::IsKeyOutOfdate(const time_t &createTime) const { - std::chrono::system_clock::time_point createTimeChrono = std::chrono::system_clock::from_time_t(createTime); - return ((createTimeChrono + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now()); + std::chrono::system_clock::time_point createTimeChrono = std::chrono::system_clock::from_time_t(createTime); + return ((createTimeChrono + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now()); } RdbSecurityManager &RdbSecurityManager::GetInstance() { - static RdbSecurityManager instance; - return instance; + static RdbSecurityManager instance; + return instance; } static std::string RemoveSuffix(const std::string &name) { - std::string suffix(".db"); - auto pos = name.rfind(suffix); - if (pos == std::string::npos || pos < name.length() - suffix.length()) { - return name; - } - return { name, 0, pos }; + std::string suffix(".db"); + auto pos = name.rfind(suffix); + if (pos == std::string::npos || pos < name.length() - suffix.length()) { + return name; + } + return { name, 0, pos }; } void RdbSecurityManager::ParsePath(const std::string &path) { - dbDir_ = ExtractFilePath(path); - const std::string dbName = ExtractFileName(path); - dbName_ = RemoveSuffix(dbName); - dbKeyDir_ = dbDir_ + std::string("key/"); - keyPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY); - keyBakPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY_BAK); + dbDir_ = ExtractFilePath(path); + const std::string dbName = ExtractFileName(path); + dbName_ = RemoveSuffix(dbName); + dbKeyDir_ = dbDir_ + std::string("key/"); + keyPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY); + keyBakPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY_BAK); } bool RdbSecurityManager::CheckKeyDataFileExists(RdbSecurityManager::KeyFileType fileType) { - if (fileType == KeyFileType::PUB_KEY_FILE) { - return FileExists(keyPath_); - } else { - return FileExists(keyBakPath_); - } + if (fileType == KeyFileType::PUB_KEY_FILE) { + return FileExists(keyPath_); + } else { + return FileExists(keyBakPath_); + } } int RdbSecurityManager::GetKeyDistributedStatus(KeyFileType keyFile, bool &status) { - LOG_INFO("GetKeyDistributedStatus start."); - std::string keyPath; - if (keyFile == KeyFileType::PUB_KEY_FILE) { - keyPath = keyPath_; - } else { - keyPath = keyBakPath_; - } - - RdbSecretKeyData keyData; - if (!LoadSecretKeyFromDisk(keyPath, keyData)) { - return E_ERROR; - } - - status = (keyData.distributed == DISTRIBUTED); - return E_OK; + LOG_INFO("GetKeyDistributedStatus start."); + std::string keyPath; + if (keyFile == KeyFileType::PUB_KEY_FILE) { + keyPath = keyPath_; + } else { + keyPath = keyBakPath_; + } + + RdbSecretKeyData keyData; + if (!LoadSecretKeyFromDisk(keyPath, keyData)) { + return E_ERROR; + } + + status = (keyData.distributed == DISTRIBUTED); + return E_OK; } int RdbSecurityManager::SetKeyDistributedStatus(KeyFileType keyFile, bool status) { - LOG_INFO("SetKeyDistributedStatus start."); - std::string keyPath; - if (keyFile == KeyFileType::PUB_KEY_FILE) { - keyPath = keyPath_; - } else { - keyPath = keyBakPath_; - } - RdbSecretKeyData keyData; - if (!LoadSecretKeyFromDisk(keyPath, keyData)) { - return E_ERROR; - } - - keyData.distributed = (status ? DISTRIBUTED : UNDISTRIBUTED); - if (!SaveSecretKeyToDisk(keyPath, keyData)) { - return E_ERROR; - } - - return E_OK; + LOG_INFO("SetKeyDistributedStatus start."); + std::string keyPath; + if (keyFile == KeyFileType::PUB_KEY_FILE) { + keyPath = keyPath_; + } else { + keyPath = keyBakPath_; + } + RdbSecretKeyData keyData; + if (!LoadSecretKeyFromDisk(keyPath, keyData)) { + return E_ERROR; + } + + keyData.distributed = (status ? DISTRIBUTED : UNDISTRIBUTED); + if (!SaveSecretKeyToDisk(keyPath, keyData)) { + return E_ERROR; + } + + return E_OK; } } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp index 44664c97023f1e20904cfa70885d92ab04a75634..19c41f83649f7a1bc2807c3cc46057aa413d9c36 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -86,14 +86,16 @@ int RdbStoreImpl::InnerOpen(const RdbStoreConfig &config) syncerParam_.password_ = {}; // open uri share if (!config.GetUri().empty()) { - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { - LOG_ERROR("RdbStoreImpl::InnerOpen get service failed"); - return -1; + std::shared_ptr service = nullptr; + errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { + LOG_ERROR("RdbStoreImpl::InnerOpen get service failed, err is %{public}d.", errCode); + return E_OK; } - if (service->CreateRDBTable(syncerParam_, config.GetWritePermission(), config.GetReadPermission()) != E_OK) { + errCode = service->CreateRDBTable(syncerParam_, config.GetWritePermission(), config.GetReadPermission()); + if (errCode != E_OK) { LOG_ERROR("RdbStoreImpl::InnerOpen service CreateRDBTable failed"); - return -1; + return E_OK; } isShared_ = true; } @@ -110,12 +112,11 @@ RdbStoreImpl::RdbStoreImpl() RdbStoreImpl::~RdbStoreImpl() { delete connectionPool; - threadMap.clear(); - idleSessions.clear(); #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) if (isShared_) { - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { + std::shared_ptr service = nullptr; + int errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { LOG_ERROR("RdbStoreImpl::~RdbStoreImpl get service failed"); return; } @@ -156,8 +157,16 @@ int RdbStoreImpl::BatchInsert(int64_t &outInsertNum, const std::string &table, } // prepare BeginTransaction - connectionPool->AcquireTransaction(); + int errCode = connectionPool->AcquireTransaction(); + if (errCode != E_OK) { + return errCode; + } + SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + if (connection->IsInTransaction()) { connectionPool->ReleaseTransaction(); connectionPool->ReleaseConnection(connection); @@ -166,7 +175,7 @@ int RdbStoreImpl::BatchInsert(int64_t &outInsertNum, const std::string &table, } BaseTransaction transaction(0); connection->SetInTransaction(true); - int errCode = connection->ExecuteSql(transaction.GetTransactionStr()); + errCode = connection->ExecuteSql(transaction.GetTransactionStr()); if (errCode != E_OK) { LOG_ERROR("BeginTransaction with error code %{public}d.", errCode); connection->SetInTransaction(false); @@ -253,6 +262,10 @@ int RdbStoreImpl::InsertWithConflictResolution(int64_t &outRowId, const std::str sql << ')'; SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + errCode = connection->ExecuteForLastInsertedRowId(outRowId, sql.str(), bindArgs); connectionPool->ReleaseConnection(connection); @@ -311,6 +324,10 @@ int RdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::stri } SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + errCode = connection->ExecuteForChangedRowCount(changedRows, sql.str(), bindArgs); connectionPool->ReleaseConnection(connection); @@ -342,6 +359,10 @@ int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std:: } SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteForChangedRowCount(deletedRows, sql.str(), bindArgs); connectionPool->ReleaseConnection(connection); @@ -370,14 +391,15 @@ std::unique_ptr RdbStoreImpl::QueryByStep( } std::shared_ptr RdbStoreImpl::RemoteQuery(const std::string &device, - const AbsRdbPredicates &predicates, const std::vector &columns) + const AbsRdbPredicates &predicates, const std::vector &columns, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); LOG_DEBUG("RdbStoreImpl::RemoteQuery on called."); std::vector selectionArgs = predicates.GetWhereArgs(); std::string sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { + std::shared_ptr service = nullptr; + errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { LOG_ERROR("RdbStoreImpl::RemoteQuery get service failed"); return nullptr; } @@ -500,6 +522,10 @@ int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::stri const std::vector &bindArgs) { SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteForLastInsertedRowId(outValue, sql, bindArgs); connectionPool->ReleaseConnection(connection); return errCode; @@ -510,6 +536,10 @@ int RdbStoreImpl::ExecuteForChangedRowCount(int64_t &outValue, const std::string { int changeRow = 0; SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteForChangedRowCount(changeRow, sql, bindArgs); connectionPool->ReleaseConnection(connection); outValue = changeRow; @@ -598,6 +628,10 @@ int RdbStoreImpl::BeginExecuteSql(const std::string &sql, SqliteConnection **con bool assumeReadOnly = SqliteUtils::IsSqlReadOnly(type); bool isReadOnly = false; *connection = connectionPool->AcquireConnection(assumeReadOnly); + if (*connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = (*connection)->Prepare(sql, isReadOnly); if (errCode != 0) { connectionPool->ReleaseConnection(*connection); @@ -607,6 +641,10 @@ int RdbStoreImpl::BeginExecuteSql(const std::string &sql, SqliteConnection **con if (isReadOnly == (*connection)->IsWriteConnection()) { connectionPool->ReleaseConnection(*connection); *connection = connectionPool->AcquireConnection(isReadOnly); + if (*connection == nullptr) { + return E_CON_OVER_LIMIT; + } + if (!isReadOnly && !(*connection)->IsWriteConnection()) { LOG_ERROR("StoreSession BeginExecutea : read connection can not execute write operation"); connectionPool->ReleaseConnection(*connection); @@ -625,6 +663,10 @@ bool RdbStoreImpl::IsHoldingConnection() int RdbStoreImpl::GiveConnectionTemporarily(int64_t milliseconds) { SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + if (connection->IsInTransaction()) { return E_STORE_SESSION_NOT_GIVE_CONNECTION_TEMPORARILY; } @@ -713,6 +755,10 @@ int RdbStoreImpl::BeginTransaction() DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); BaseTransaction transaction(connectionPool->getTransactionStack().size()); SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteSql(transaction.GetTransactionStr()); connectionPool->ReleaseConnection(connection); if (errCode != E_OK) { @@ -740,6 +786,10 @@ int RdbStoreImpl::RollBack() connectionPool->getTransactionStack().top().SetChildFailure(true); } SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteSql(transaction.GetRollbackStr()); connectionPool->ReleaseConnection(connection); if (connectionPool->getTransactionStack().empty()) { @@ -770,6 +820,10 @@ int RdbStoreImpl::Commit() } SqliteConnection *connection = connectionPool->AcquireConnection(false); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteSql(sqlStr); connectionPool->ReleaseConnection(connection); connection->SetInTransaction(false); @@ -795,7 +849,11 @@ int RdbStoreImpl::FreeTransaction(SqliteConnection *connection, const std::strin bool RdbStoreImpl::IsInTransaction() { - return connectionPool->AcquireConnection(false)->IsInTransaction(); + auto connection = connectionPool->AcquireConnection(false); + if (connection != nullptr) { + return connection->IsInTransaction(); + } + return true; } int RdbStoreImpl::CheckAttach(const std::string &sql) @@ -815,6 +873,10 @@ int RdbStoreImpl::CheckAttach(const std::string &sql) bool isRead = SqliteDatabaseUtils::BeginExecuteSql(GlobalExpr::PRAGMA_JOUR_MODE_EXP); SqliteConnection *connection = connectionPool->AcquireConnection(isRead); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = connection->ExecuteGetString(journalMode, GlobalExpr::PRAGMA_JOUR_MODE_EXP, std::vector()); connectionPool->ReleaseConnection(connection); @@ -1001,12 +1063,12 @@ std::unique_ptr RdbStoreImpl::QueryByStep(const std::string &sql, } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) -bool RdbStoreImpl::SetDistributedTables(const std::vector &tables) +int RdbStoreImpl::SetDistributedTables(const std::vector &tables) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (tables.empty()) { LOG_WARN("The distributed tables to be set is empty."); - return true; + return E_OK; } if (isEncrypt_) { bool status = false; @@ -1019,16 +1081,17 @@ bool RdbStoreImpl::SetDistributedTables(const std::vector &tables) } } - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { - return false; + std::shared_ptr service = nullptr; + int errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { + return errCode; } int32_t errorCode = service->SetDistributedTables(syncerParam_, tables); if (errorCode != E_OK) { LOG_ERROR("Fail to set distributed tables, error=%{public}d", errorCode); syncerParam_.password_.assign(syncerParam_.password_.size(), 0); syncerParam_.password_.clear(); - return false; + return errorCode; } if (isEncrypt_) { @@ -1037,53 +1100,57 @@ bool RdbStoreImpl::SetDistributedTables(const std::vector &tables) RdbSecurityManager::GetInstance().SetKeyDistributedStatus( RdbSecurityManager::KeyFileType::PUB_KEY_FILE, true); } - return true; + return E_OK; } -std::string RdbStoreImpl::ObtainDistributedTableName(const std::string &device, const std::string &table) +std::string RdbStoreImpl::ObtainDistributedTableName(const std::string &device, const std::string &table, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { + std::shared_ptr service = nullptr; + errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { return ""; } auto distTable = service->ObtainDistributedTableName(device, table); return distTable; } -bool RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const SyncCallback &callback) +int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const SyncCallback &callback) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { - return false; + std::shared_ptr service = nullptr; + int errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { + LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); + return errCode; } - if (service->Sync(syncerParam_, option, predicate.GetDistributedPredicates(), callback) != 0) { - LOG_ERROR("failed"); - return false; + errCode = service->Sync(syncerParam_, option, predicate.GetDistributedPredicates(), callback); + if (errCode != E_OK) { + LOG_ERROR("Sync is failed, err is %{public}d.", errCode); + return errCode; } - LOG_INFO("success"); - return true; + return E_OK; } -bool RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) +int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) { - LOG_INFO("enter"); - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { - return false; + std::shared_ptr service = nullptr; + int errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { + return errCode; } - return service->Subscribe(syncerParam_, option, observer) == 0; + return service->Subscribe(syncerParam_, option, observer); } -bool RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) +int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) { LOG_INFO("enter"); - auto service = DistributedRdb::RdbManager::GetRdbService(syncerParam_); - if (service == nullptr) { - return false; + std::shared_ptr service = nullptr; + int errCode = DistributedRdb::RdbManager::GetRdbService(syncerParam_, service); + if (errCode != E_OK) { + return errCode; } - return service->UnSubscribe(syncerParam_, option, observer) == 0; + return service->UnSubscribe(syncerParam_, option, observer); } bool RdbStoreImpl::DropDeviceData(const std::vector &devices, const DropOption &option) diff --git a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp index 2521f2739548b3d3ba402d006b173bc739a2f9cf..1666628e687fd3597177664b5a2c7f503c1e7263 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp @@ -68,24 +68,4 @@ bool Unmarshalling(RdbOperation &output, MessageParcel &data) output.operator_ = static_cast(option); return ret; } - -template<> bool ITypesUtil::Marshalling(const ValueObject &input, MessageParcel &data) -{ - return ITypesUtil::Marshal(data, input.value); -} - -template<> bool ITypesUtil::Unmarshalling(ValueObject &output, MessageParcel &data) -{ - return ITypesUtil::Unmarshal(data, output.value); -} - -template<> bool ITypesUtil::Marshalling(const ValuesBucket &input, MessageParcel &data) -{ - return ITypesUtil::Marshal(data, input.valuesMap); -} - -template<> bool ITypesUtil::Unmarshalling(ValuesBucket &output, MessageParcel &data) -{ - return ITypesUtil::Marshal(data, output.valuesMap); -} } \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index 06724dc3255a54ff4640d3b3f58b964858c446fa..cbc65eac622d6d228ded3fb32019a724dfaf5342 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -49,7 +49,11 @@ const int ERROR_STATUS = -1; SqliteConnection *SqliteConnection::Open(const SqliteConfig &config, bool isWriteConnection, int &errCode) { - auto connection = new SqliteConnection(isWriteConnection); + auto connection = new (std::nothrow) SqliteConnection(isWriteConnection); + if (connection == nullptr) { + LOG_ERROR("SqliteConnection::Open new failed, connection is nullptr"); + return nullptr; + } errCode = connection->InnerOpen(config); if (errCode != E_OK) { delete connection; @@ -123,9 +127,11 @@ int SqliteConnection::InnerOpen(const SqliteConfig &config) return errCode; } - errCode = sqlite3_wal_checkpoint_v2(dbHandle, nullptr, SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr); - if (errCode != SQLITE_OK) { - LOG_WARN("sqlite checkpoint errCode is %{public}d", errCode); + if (isWriteConnection) { + errCode = sqlite3_wal_checkpoint_v2(dbHandle, nullptr, SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr); + if (errCode != SQLITE_OK) { + LOG_WARN("sqlite checkpoint errCode is %{public}d", errCode); + } } filePath = dbPath; @@ -805,21 +811,13 @@ int SqliteConnection::LimitWalSize() } std::string walName = sqlite3_filename_wal(sqlite3_db_filename(dbHandle, "main")); - if (SqliteUtils::GetFileSize(walName) < GlobalExpr::DB_WAL_SIZE_LIMIT) { - return E_OK; - } - - int errCode = sqlite3_wal_checkpoint_v2(dbHandle, nullptr, SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr); - if (errCode != SQLITE_OK) { - return E_WAL_SIZE_OVER_LIMIT; - } - int fileSize = SqliteUtils::GetFileSize(walName); - if (fileSize >= GlobalExpr::DB_WAL_SIZE_LIMIT) { - LOG_ERROR("the WAL file size over default limit, size: %{public}d", fileSize); + if (fileSize > GlobalExpr::DB_WAL_SIZE_LIMIT) { + LOG_ERROR("the WAL file size over default limit, %{public}s size is %{public}d", + walName.substr(walName.find_last_of('/') + 1).c_str(), fileSize); return E_WAL_SIZE_OVER_LIMIT; } - + return E_OK; } } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp index fde0b47352fb130bf57d2bab6ecfc9fcaff9526d..37578573935d53c7e03d243868f0288b4b1153ec 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp @@ -32,9 +32,15 @@ namespace OHOS { namespace NativeRdb { +constexpr std::chrono::seconds timeout(2); + SqliteConnectionPool *SqliteConnectionPool::Create(const RdbStoreConfig &storeConfig, int &errCode) { - auto pool = new SqliteConnectionPool(storeConfig); + auto pool = new (std::nothrow) SqliteConnectionPool(storeConfig); + if (pool == nullptr) { + LOG_ERROR("SqliteConnectionPool::Create new failed, pool is nullptr"); + return nullptr; + } errCode = pool->Init(); if (errCode != E_OK) { delete pool; @@ -113,16 +119,18 @@ void SqliteConnectionPool::CloseAllConnections() SqliteConnection *SqliteConnectionPool::AcquireConnection(bool isReadOnly) { + LOG_DEBUG("readConnectionCount: %{public}d, idleReadConnectionCount: %{public}d, writeConnection: %{public}d", + readConnectionCount, idleReadConnectionCount, writeConnectionUsed); if (isReadOnly && readConnectionCount != 0) { - LOG_DEBUG("AcquireReadConnection"); return AcquireReadConnection(); } else { - LOG_DEBUG("AcquireWriteConnection"); return AcquireWriteConnection(); } } void SqliteConnectionPool::ReleaseConnection(SqliteConnection *connection) { + LOG_DEBUG("readConnectionCount: %{public}d, idleReadConnectionCount: %{public}d, writeConnection: %{public}d", + readConnectionCount, idleReadConnectionCount, writeConnectionUsed); connection->DesFinalize(); if (connection == writeConnection) { ReleaseWriteConnection(); @@ -133,21 +141,24 @@ void SqliteConnectionPool::ReleaseConnection(SqliteConnection *connection) SqliteConnection *SqliteConnectionPool::AcquireWriteConnection() { - LOG_DEBUG("begin"); std::unique_lock lock(writeMutex); - writeCondition.wait(lock, [&] { return !writeConnectionUsed; }); - writeConnectionUsed = true; - LOG_DEBUG("end"); - return writeConnection; + if (writeCondition.wait_for(lock, timeout, [this] { return !writeConnectionUsed; })) { + writeConnectionUsed = true; + return writeConnection; + } + LOG_DEBUG("Acquire writeConnection timeout."); + return nullptr; } -void SqliteConnectionPool::AcquireTransaction() +int SqliteConnectionPool::AcquireTransaction() { - LOG_DEBUG("AcquireTransaction begin"); std::unique_lock lock(transMutex); - transCondition.wait(lock, [&] { return !transactionUsed; }); - transactionUsed = true; - LOG_DEBUG("AcquireTransaction end"); + if (transCondition.wait_for(lock, timeout, [this] { return !transactionUsed; })) { + transactionUsed = true; + return E_OK; + } + LOG_DEBUG("Transaction timeout."); + return E_TRANSACTION_IN_EXECUTE; } void SqliteConnectionPool::ReleaseTransaction() @@ -175,11 +186,14 @@ void SqliteConnectionPool::ReleaseWriteConnection() SqliteConnection *SqliteConnectionPool::AcquireReadConnection() { std::unique_lock lock(readMutex); - readCondition.wait(lock, [&] { return idleReadConnectionCount > 0; }); - SqliteConnection *connection = readConnections.back(); - readConnections.pop_back(); - idleReadConnectionCount--; - return connection; + if (readCondition.wait_for(lock, timeout, [this] { return idleReadConnectionCount > 0; })) { + SqliteConnection *connection = readConnections.back(); + readConnections.pop_back(); + idleReadConnectionCount--; + return connection; + } + LOG_DEBUG("Acquire ReadConnection timeout."); + return nullptr; } /** diff --git a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp index 1db136a2db38f7046b4ac203a750855e202b4a2d..886012b04047fbd51f25b35e256d2241e4d57acc 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp @@ -68,6 +68,10 @@ int SqliteSharedResultSet::GetAllColumnNames(std::vector &columnNam } SqliteConnection *connection = connectionPool_->AcquireConnection(true); + if (connection == nullptr) { + return E_CON_OVER_LIMIT; + } + int errCode = PrepareStep(connection); if (errCode) { connectionPool_->ReleaseConnection(connection); @@ -168,6 +172,9 @@ void SqliteSharedResultSet::FillSharedBlock(int requiredPos) bool isRead = SqliteDatabaseUtils::BeginExecuteSql(qrySql); SqliteConnection* connection = connectionPool_->AcquireConnection(isRead); + if (connection == nullptr) { + return; + } if (rowNum == NO_COUNT) { connection->ExecuteForSharedBlock(rowNum, qrySql, bindArgs, GetBlock(), requiredPos, requiredPos, true); @@ -214,13 +221,5 @@ void SqliteSharedResultSet::Finalize() Close(); } } - -int SqliteSharedResultSet::CheckSession() -{ - if (std::this_thread::get_id() != tid) { - return E_STEP_RESULT_SET_CROSS_THREADS; - } - return E_OK; -} } // namespace NativeRdb } // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/step_result_set.cpp b/relational_store/frameworks/native/rdb/src/step_result_set.cpp index 88b0610aac2c104b8406bc56ae8162ffd4186c67..a97d571259f100d08c904cafce4f7c332f259bfe 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -47,8 +47,6 @@ StepResultSet::StepResultSet(SqliteConnectionPool *pool, const std::string &sql, StepResultSet::~StepResultSet() { Close(); - connectionPool_->ReleaseConnection(connection_); - connection_ = nullptr; } int StepResultSet::GetAllColumnNames(std::vector &columnNames) @@ -146,8 +144,8 @@ int StepResultSet::GetRowCount(int &count) */ int StepResultSet::GoToRow(int position) { - if (!connection_) { - return E_ERROR; + if (connection_ == nullptr) { + return E_CON_OVER_LIMIT; } // If the moved position is less than zero, reset the result and return an error if (position < 0) { @@ -220,12 +218,11 @@ int StepResultSet::Close() isClosed = true; int errCode = FinishStep(); rdb = nullptr; - return errCode; -} -int StepResultSet::CheckSession() -{ - return E_OK; + connectionPool_->ReleaseConnection(connection_); + connection_ = nullptr; + + return errCode; } /** @@ -241,6 +238,10 @@ int StepResultSet::PrepareStep() return E_OK; } + if (connection_ == nullptr) { + return E_CON_OVER_LIMIT; + } + if (!SqliteDatabaseUtils::IsReadOnlySql(sql)) { LOG_ERROR("StoreSession BeginStepQuery fail : not select sql !"); return E_EXECUTE_IN_STEP_QUERY; @@ -261,20 +262,17 @@ int StepResultSet::PrepareStep() */ int StepResultSet::FinishStep() { - int errCode = CheckSession(); - if (errCode != E_OK) { - return errCode; - } - if (sqliteStatement == nullptr) { return E_OK; } sqliteStatement = nullptr; rowPos_ = INIT_POS; - if (connection_ != nullptr) { - errCode = connection_->EndStepQuery(); + if (connection_ == nullptr) { + return E_OK; } + + int errCode = connection_->EndStepQuery(); if (errCode != E_OK) { LOG_ERROR("StepResultSet::FinishStep err = %d", errCode); } diff --git a/relational_store/frameworks/native/rdb/src/value_object.cpp b/relational_store/frameworks/native/rdb/src/value_object.cpp index 5da153205f26bf35ee28e0d457386b4c13c8ceed..d6d39579cf107caa9295c8cc18bbd898fd51ad45 100644 --- a/relational_store/frameworks/native/rdb/src/value_object.cpp +++ b/relational_store/frameworks/native/rdb/src/value_object.cpp @@ -20,12 +20,13 @@ namespace OHOS { namespace NativeRdb { -ValueObject::ValueObject() +ValueObject::ValueObject() : type(ValueObjectType::TYPE_NULL) { } ValueObject::ValueObject(ValueObject::Type valueObject) noexcept : value(std::move(valueObject)) { + type = ValueObjectType(value.index()); } ValueObject::ValueObject(ValueObject &&valueObject) noexcept @@ -33,7 +34,9 @@ ValueObject::ValueObject(ValueObject &&valueObject) noexcept if (this == &valueObject) { return; } + type = valueObject.type; value = std::move(valueObject.value); + valueObject.type = ValueObjectType::TYPE_NULL; } ValueObject::ValueObject(const ValueObject &valueObject) @@ -41,6 +44,7 @@ ValueObject::ValueObject(const ValueObject &valueObject) if (this == &valueObject) { return; } + type = valueObject.type; value = valueObject.value; } @@ -48,26 +52,28 @@ ValueObject::~ValueObject() { } -ValueObject::ValueObject(int val) : value(static_cast(val)) +ValueObject::ValueObject(int val) : type(ValueObjectType::TYPE_INT) { + value = static_cast(val); } -ValueObject::ValueObject(int64_t val) : value(val) +ValueObject::ValueObject(int64_t val) : type(ValueObjectType::TYPE_INT) { + value = val; } -ValueObject::ValueObject(double val) +ValueObject::ValueObject(double val) : type(ValueObjectType::TYPE_DOUBLE) { value = val; } -ValueObject::ValueObject(bool val) +ValueObject::ValueObject(bool val) : type(ValueObjectType::TYPE_BOOL) { value = val; } -ValueObject::ValueObject(const std::string &val) +ValueObject::ValueObject(const std::string &val) : type(ValueObjectType::TYPE_STRING) { value = val; } -ValueObject::ValueObject(const std::vector &val) +ValueObject::ValueObject(const std::vector &val) : type(ValueObjectType::TYPE_BLOB) { std::vector blob = val; value = blob; @@ -78,7 +84,9 @@ ValueObject &ValueObject::operator=(ValueObject &&valueObject) noexcept if (this == &valueObject) { return *this; } + type = valueObject.type; value = std::move(valueObject.value); + valueObject.type = ValueObjectType::TYPE_NULL; return *this; } @@ -87,56 +95,143 @@ ValueObject &ValueObject::operator=(const ValueObject &valueObject) if (this == &valueObject) { return *this; } + type = valueObject.type; value = valueObject.value; return *this; } ValueObjectType ValueObject::GetType() const { - return ValueObjectType(value.index()); + return type; } int ValueObject::GetInt(int &val) const { - int64_t value; - auto ret = Get(value); - val = value; - return ret; + if (type != ValueObjectType::TYPE_INT) { + return E_INVALID_OBJECT_TYPE; + } + + int64_t v = std::get(value); + val = static_cast(v); + return E_OK; } int ValueObject::GetLong(int64_t &val) const { - return Get(val); + if (type != ValueObjectType::TYPE_INT) { + return E_INVALID_OBJECT_TYPE; + } + + val = std::get(value); + return E_OK; } int ValueObject::GetDouble(double &val) const { - return Get(val); + if (type != ValueObjectType::TYPE_DOUBLE) { + return E_INVALID_OBJECT_TYPE; + } + + val = std::get(value); + return E_OK; } int ValueObject::GetBool(bool &val) const { - return Get(val); + if (type != ValueObjectType::TYPE_BOOL) { + return E_INVALID_OBJECT_TYPE; + } + + val = std::get(value); + return E_OK; } int ValueObject::GetString(std::string &val) const { - return Get(val); -} + if (type != ValueObjectType::TYPE_STRING) { + return E_INVALID_OBJECT_TYPE; + } -int ValueObject::GetBlob(std::vector &val) const -{ - return Get(val); + val = std::get(value); + return E_OK; } -template int ValueObject::Get(T &output) const +int ValueObject::GetBlob(std::vector &val) const { - const T *v = std::get_if(&value); - if (v == nullptr) { + if (type != ValueObjectType::TYPE_BLOB) { return E_INVALID_OBJECT_TYPE; } - output = static_cast(*v); + + val = std::get>(value); return E_OK; } + +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) +bool ValueObject::Marshalling(Parcel &parcel) const +{ + switch (this->type) { + case ValueObjectType::TYPE_NULL: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_NULL); + break; + } + case ValueObjectType::TYPE_INT: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_INT); + parcel.WriteInt64(std::get(value)); + break; + } + case ValueObjectType::TYPE_DOUBLE: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_DOUBLE); + parcel.WriteDouble(std::get(value)); + break; + } + case ValueObjectType::TYPE_STRING: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_STRING); + parcel.WriteString(std::get(value)); + break; + } + case ValueObjectType::TYPE_BLOB: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_BLOB); + parcel.WriteUInt8Vector(std::get>(value)); + break; + } + case ValueObjectType::TYPE_BOOL: { + parcel.WriteInt16((int16_t) ValueObjectType::TYPE_BOOL); + parcel.WriteBool(std::get(value)); + break; + } + default: + break; + } + return true; +} + +ValueObject *ValueObject::Unmarshalling(Parcel &parcel) +{ + switch (parcel.ReadInt16()) { + case (int16_t)ValueObjectType::TYPE_NULL: { + return new ValueObject(); + } + case (int16_t)ValueObjectType::TYPE_INT: { + return new ValueObject(parcel.ReadInt64()); + } + case (int16_t)ValueObjectType::TYPE_DOUBLE: { + return new ValueObject(parcel.ReadDouble()); + } + case (int16_t)ValueObjectType::TYPE_STRING: { + return new ValueObject(parcel.ReadString()); + } + case (int16_t)ValueObjectType::TYPE_BLOB: { + std::vector val; + parcel.ReadUInt8Vector(&val); + return new ValueObject(val); + } + case (int16_t)ValueObjectType::TYPE_BOOL: { + return new ValueObject(parcel.ReadBool()); + } + default: + return new ValueObject(); + } +} +#endif } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/values_bucket.cpp b/relational_store/frameworks/native/rdb/src/values_bucket.cpp index e3f589ff62570b934b9ff814c2fe166027e7cf33..eee1d9626a0b0727b4e2d74f93602e8471a24f74 100644 --- a/relational_store/frameworks/native/rdb/src/values_bucket.cpp +++ b/relational_store/frameworks/native/rdb/src/values_bucket.cpp @@ -107,5 +107,32 @@ void ValuesBucket::GetAll(std::map &outValuesMap) cons { outValuesMap = valuesMap; } + +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) +bool ValuesBucket::Marshalling(Parcel &parcel) const +{ + parcel.WriteInt32(valuesMap.size()); + for (auto &it : valuesMap) { + parcel.WriteString(it.first); + parcel.WriteParcelable(&it.second); + } + return true; +} + +ValuesBucket *ValuesBucket::Unmarshalling(Parcel &parcel) +{ + int mapSize = parcel.ReadInt32(); + std::map valuesMap; + ValueObject *value = nullptr; + for (int i = 0; i < mapSize; i++) { + std::string key = parcel.ReadString(); + value = parcel.ReadParcelable(); + valuesMap.insert(std::make_pair(key, *value)); + delete value; + } + value = nullptr; + return new ValuesBucket(valuesMap); +} +#endif } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/BUILD.gn b/relational_store/interfaces/inner_api/rdb/BUILD.gn index c5a0a05b6a3ad3b2ffbf782b17cd0ffb49529baf..b00747c85014ca506d818825bc73d4e1ec85fe79 100644 --- a/relational_store/interfaces/inner_api/rdb/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb/BUILD.gn @@ -104,7 +104,6 @@ base_sources = [ "${relational_store_native_path}/rdb/src/sqlite_statement.cpp", "${relational_store_native_path}/rdb/src/sqlite_utils.cpp", "${relational_store_native_path}/rdb/src/step_result_set.cpp", - "${relational_store_native_path}/rdb/src/store_session.cpp", "${relational_store_native_path}/rdb/src/string_utils.cpp", "${relational_store_native_path}/rdb/src/value_object.cpp", "${relational_store_native_path}/rdb/src/values_bucket.cpp", diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h index c2a68ce75645f6f4f5725318ccaeae948ce70057..90a7de1660dfe4045d7098e79311be182b23a34f 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h @@ -22,6 +22,8 @@ #include #include "abs_result_set.h" +#include "message_parcel.h" +#include "parcel.h" #include "shared_block.h" #include "shared_result_set.h" @@ -188,12 +190,16 @@ protected: void ClosedBlock(); virtual void Finalize(); + friend class ISharedResultSetStub; + friend class ISharedResultSetProxy; + bool Unmarshalling(MessageParcel &parcel); + bool Marshalling(MessageParcel &parcel); + private: // The default position of the cursor static const int INIT_POS = -1; static const size_t DEFAULT_BLOCK_SIZE = 2 * 1024 * 1024; - friend class ISharedResultSetStub; - friend class ISharedResultSetProxy; + // The SharedBlock owned by this AbsSharedResultSet AppDataFwk::SharedBlock *sharedBlock_ = nullptr; }; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h index c3ca4d4c3ec0c05026d4c5287e48cbfa3c250f51..7f89c41c4144d08aa296ea250cd300e2df0bf7b2 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h @@ -29,6 +29,11 @@ constexpr int E_OK = 0; */ constexpr int E_BASE = 14800000; +/** +* @brief The error when the capability not supported. +*/ +constexpr int E_NOT_SUPPORTED = 801; + /** * @brief The error code for common exceptions. */ @@ -258,6 +263,11 @@ constexpr int E_ARGS_READ_CON_OVERLOAD = (E_BASE + 46); * @brief The error when the wal file size over default limit. */ static constexpr int E_WAL_SIZE_OVER_LIMIT = (E_BASE + 47); + +/** +* @brief The error when the connection count is used up. +*/ +static constexpr int E_CON_OVER_LIMIT = (E_BASE + 48); } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h index 72ab6599940e715f7abb9466cc1375fcf3b307c6..d20fd73633ef70fa59199740a959a3663b5d82bb 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h @@ -27,6 +27,7 @@ #include "values_bucket.h" #include "rdb_types.h" #include "rdb_common.h" +#include "rdb_errno.h" namespace OHOS::NativeRdb { class RDB_API_EXPORT RdbStore { @@ -270,8 +271,8 @@ public: * @param predicates Indicates the specified query condition by the instance object of {@link AbsRdbPredicates}. * @param columns Indicates the columns to query. If the value is empty array, the query applies to all columns. */ - virtual std::shared_ptr RemoteQuery(const std::string &device, - const AbsRdbPredicates &predicates, const std::vector &columns) = 0; + virtual std::shared_ptr RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, + const std::vector &columns, int &errCode) = 0; /** * @brief Updates data in the database based on a a specified instance object of AbsRdbPredicates. @@ -364,7 +365,7 @@ public: * * @param tables Indicates the tables name you want to set. */ - virtual bool SetDistributedTables(const std::vector& tables) = 0; + virtual int SetDistributedTables(const std::vector& tables) = 0; /** * @brief Obtain distributed table name of specified remote device according to local table name. @@ -374,7 +375,8 @@ public: * * @return Returns the distributed table name. */ - virtual std::string ObtainDistributedTableName(const std::string& device, const std::string& table) = 0; + virtual std::string ObtainDistributedTableName( + const std::string &device, const std::string &table, int &errCode) = 0; /** * @brief Sync data between devices. @@ -382,17 +384,17 @@ public: * @param device Indicates the remote device. * @param predicate Indicates the AbsRdbPredicates {@link AbsRdbPredicates} object. */ - virtual bool Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const SyncCallback& callback) = 0; + virtual int Sync(const SyncOption& option, const AbsRdbPredicates& predicate, const SyncCallback& callback) = 0; /** * @brief Subscribe to event changes. */ - virtual bool Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; + virtual int Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; /** * @brief UnSubscribe to event changes. */ - virtual bool UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; + virtual int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; /** * @brief Drop the specified devices Data. diff --git a/relational_store/interfaces/inner_api/rdb/include/value_object.h b/relational_store/interfaces/inner_api/rdb/include/value_object.h index e1ce57f4e96fec090617cc50461db20344fc692e..ce6e83d4f9d4b7d7792ab5a7ee3404d71f9ec13e 100644 --- a/relational_store/interfaces/inner_api/rdb/include/value_object.h +++ b/relational_store/interfaces/inner_api/rdb/include/value_object.h @@ -45,13 +45,12 @@ enum class ValueObjectType { /** * The ValueObject class of RDB. */ -class ValueObject { +class RDB_API_EXPORT ValueObject : public virtual OHOS::Parcelable { public: /** * @brief Use Type replace std::variant. */ using Type = std::variant>; - Type value; /** * @brief Constructor. @@ -179,6 +178,16 @@ public: */ RDB_API_EXPORT int GetBlob(std::vector &val) const; + /** + * @brief Write to message parcel. + */ + RDB_API_EXPORT bool Marshalling(Parcel &parcel) const override; + + /** + * @brief Obtains a ValueObject object from parcel. + */ + RDB_API_EXPORT static ValueObject *Unmarshalling(Parcel &parcel); + /** * @brief Type conversion function. * @@ -250,8 +259,8 @@ public: } private: - template - int Get(T &output) const; + ValueObjectType type; + Type value; }; } // namespace NativeRdb diff --git a/relational_store/interfaces/inner_api/rdb/include/values_bucket.h b/relational_store/interfaces/inner_api/rdb/include/values_bucket.h index 9d25d0def780474338b0d43a5c61203d6d0c0e92..592f9280660bd0d59a4e143bde660bbcd54c77b4 100644 --- a/relational_store/interfaces/inner_api/rdb/include/values_bucket.h +++ b/relational_store/interfaces/inner_api/rdb/include/values_bucket.h @@ -18,6 +18,8 @@ #include #include +#include + #include "value_object.h" namespace OHOS { @@ -25,7 +27,7 @@ namespace NativeRdb { /** * The ValuesBucket class of RDB. */ -class ValuesBucket { +class RDB_API_EXPORT ValuesBucket : public virtual OHOS::Parcelable { public: /** * @brief Constructor. @@ -139,7 +141,17 @@ public: * @brief Obtains the ValuesBucket object's valuesmap. */ RDB_API_EXPORT void GetAll(std::map &valuesMap) const; - + + /** + * @brief Write to message parcel. + */ + RDB_API_EXPORT bool Marshalling(Parcel &parcel) const override; + + /** + * @brief Obtains a ValuesBucket object from parcel. + */ + RDB_API_EXPORT static ValuesBucket *Unmarshalling(Parcel &parcel); +private: std::map valuesMap; }; diff --git a/relational_store/test/js/relationalstore/performance/src/RdbStoreOthersCallbackPerf.js b/relational_store/test/js/relationalstore/performance/src/RdbStoreOthersCallbackPerf.js index 6fa5cec90e1d29c653be745e998747a172c9de13..77e7cb07d46a44d6530882b8811a4f1240f4e4a9 100644 --- a/relational_store/test/js/relationalstore/performance/src/RdbStoreOthersCallbackPerf.js +++ b/relational_store/test/js/relationalstore/performance/src/RdbStoreOthersCallbackPerf.js @@ -162,48 +162,4 @@ describe('rdbStoreOthersCallbackPerf', function () { let startTime = new Date().getTime(); executeSqlCallbackPerf(0); }) - - it('SUB_DDM_PERF_RDB_backup_Callback_001', 0, async function (done) { - let averageTime = 0; - - async function backupCallbackPerf(index) { - rdbStore.backup("backup.db", function (err, data) { - if (index < BASE_COUNT) { - backupCallbackPerf(index + 1); - } else { - let endTime = new Date().getTime(); - averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; - console.info(TAG + " the backup_Callback average time is: " + averageTime + " μs"); - expect(averageTime < BASE_LINE).assertTrue(); - done(); - } - }) - } - - let startTime = new Date().getTime(); - backupCallbackPerf(0); - }) - - it('SUB_DDM_PERF_RDB_restore_Callback_001', 0, async function (done) { - let averageTime = 0; - - async function restoreCallbackPerf(index) { - rdbStore.restore("backup.db", function (err, data) { - if (index < BASE_COUNT) { - restoreCallbackPerf(index + 1); - } else { - let endTime = new Date().getTime(); - averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; - console.info(TAG + " the restore_Callback average time is: " + averageTime + " μs"); - expect(averageTime < BASE_LINE).assertTrue(); - dataRdb.deleteRdbStore(context, "backup.db", function (err, data) { - done(); - }) - } - }) - } - - let startTime = new Date().getTime(); - restoreCallbackPerf(0); - }) }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js index d4957a29839de953fa1f24f1bef93490ec097e2e..9455ea0684179326825688e2bf0956170cd35166 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js @@ -94,8 +94,13 @@ describe('rdbStoreDistributedTest', function () { console.log(TAG + "set none to be distributed table success"); expect(rdbStore).assertEqual(rdbStore) } catch (err) { - console.log(TAG + "set none to be distributed table failed"); - expect(null).assertFail(); + if (err.code == 801) { + console.log(TAG + "Capability not supported."); + expect(true).assertEqual(true); + } else { + console.log(TAG + "set none to be distributed table failed"); + expect(null).assertFail(); + } } done() console.log(TAG + "************* testRdbStoreDistributed002 end *************"); @@ -113,8 +118,13 @@ describe('rdbStoreDistributedTest', function () { console.log(TAG + "set employee to be distributed table success"); expect(rdbStore).assertEqual(rdbStore) } catch (err) { - console.log(TAG + "set employee to be distributed table failed"); - expect(null).assertFail(); + if (err.code == 801) { + console.log(TAG + "Capability not supported."); + expect(true).assertEqual(true); + } else { + console.log(TAG + "set employee to be distributed table failed"); + expect(null).assertFail(); + } } done() console.log(TAG + "************* testRdbStoreDistributed003 end *************"); @@ -132,8 +142,13 @@ describe('rdbStoreDistributedTest', function () { console.log(TAG + "set employee and product to be distributed table success"); expect(rdbStore).assertEqual(rdbStore) } catch (err) { - console.log(TAG + "set employee and product to be distributed table failed"); - expect(null).assertFail(); + if (err.code == 801) { + console.log(TAG + "Capability not supported."); + expect(true).assertEqual(true); + } else { + console.log(TAG + "set employee and product to be distributed table failed"); + expect(null).assertFail(); + } } done() console.log(TAG + "************* testRdbStoreDistributed004 end *************"); diff --git a/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/distributed_test.cpp b/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/distributed_test.cpp index 8c5204d9a9026091af71226e1b77e73570b5dcde..3482e061ff45f188cda8df1c78a525ea793add25 100644 --- a/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/distributed_test.cpp +++ b/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/distributed_test.cpp @@ -152,12 +152,14 @@ HWTEST_F(DistributedTest, RemoteQuery001, TestSize.Level1) }); std::vector tables = {"test"}; DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", deviceInfos_); - std::string test = store_->ObtainDistributedTableName(deviceInfos_[0].networkId, tables[0]); + int errCode = E_ERROR; + std::string test = store_->ObtainDistributedTableName(deviceInfos_[0].networkId, tables[0], errCode); AbsRdbPredicates predicate(tables[0]); predicate.EqualTo("name", "zhangsan"); std::vector columns; - std::shared_ptr resultSet = store_-> RemoteQuery(deviceInfos_[0].networkId, predicate, columns); - + errCode = E_ERROR; + std::shared_ptr resultSet = store_->RemoteQuery(deviceInfos_[0].networkId, predicate, columns, errCode); + EXPECT_TRUE(ret > 0); EXPECT_EQ(returvalue, "zhangsan"); } diff --git a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp index 4d055a38fd5892e66c3afb5a6abf3659337635c4..c9378919c465c6e65c2def46e084f1d59669dd3c 100644 --- a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp @@ -1600,4 +1600,22 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_InDevices_InAllDevices_026, TestSize.Le AbsRdbPredicates* absRdbPredicates1 = predicates.InAllDevices(); EXPECT_NE(absRdbPredicates1, nullptr); EXPECT_EQ(absRdbPredicates, absRdbPredicates1); +} + +/* * + * @tc.name: RdbStore_GetDistributedPredicates_027 + * @tc.desc: Normal testCase of RdbPredicates for GetDistributedPredicates method + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GetDistributedPredicates_027, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.EqualTo("stringValue", "ABCDEFGHIJKLMN")->OrderByDesc("integerValue")->Limit(2); + auto distributedRdbPredicates = predicates.GetDistributedPredicates(); + EXPECT_EQ(distributedRdbPredicates.table_, "AllDataType"); + EXPECT_EQ(distributedRdbPredicates.operations_.size(), 3UL); + EXPECT_EQ(distributedRdbPredicates.operations_[0].operator_, OHOS::DistributedRdb::EQUAL_TO); + EXPECT_EQ(distributedRdbPredicates.operations_[0].field_, "stringValue"); + EXPECT_EQ(distributedRdbPredicates.operations_[0].values_[0], "ABCDEFGHIJKLMN"); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_value_bucket_test.cpp b/relational_store/test/native/rdb/unittest/rdb_value_bucket_test.cpp index 361653cdc3c3d7174d177edb5768d6dbe0b93d28..0fa37582d8147eedd92eab56b856a298a36d47db 100644 --- a/relational_store/test/native/rdb/unittest/rdb_value_bucket_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_value_bucket_test.cpp @@ -22,7 +22,6 @@ #include "parcel.h" #include "value_object.h" #include "values_bucket.h" -#include "itypes_util.h" using namespace testing::ext; using namespace OHOS; @@ -69,42 +68,42 @@ HWTEST_F(ValuesBucketTest, Values_Bucket_001, TestSize.Level1) values.PutNull("mark"); OHOS::MessageParcel data; - ITypesUtil::Marshal(data, values); - ValuesBucket valuesBucket; + data.WriteParcelable(&values); - ITypesUtil::Unmarshal(data, valuesBucket); + auto valuesBucket = std::shared_ptr(data.ReadParcelable()); ValueObject valueObject; - valuesBucket.GetObject("id", valueObject); + + valuesBucket->GetObject("id", valueObject); EXPECT_EQ(ValueObjectType::TYPE_INT, valueObject.GetType()); int intVal; valueObject.GetInt(intVal); EXPECT_EQ(1, intVal); - valuesBucket.GetObject("name", valueObject); + valuesBucket->GetObject("name", valueObject); EXPECT_EQ(ValueObjectType::TYPE_STRING, valueObject.GetType()); std::string strVal; valueObject.GetString(strVal); EXPECT_EQ("zhangsan", strVal); - valuesBucket.GetObject("No.", valueObject); + valuesBucket->GetObject("No.", valueObject); EXPECT_EQ(ValueObjectType::TYPE_INT, valueObject.GetType()); int64_t int64Val; valueObject.GetLong(int64Val); EXPECT_EQ(9223372036854775807L, int64Val); - valuesBucket.GetObject("salary", valueObject); + valuesBucket->GetObject("salary", valueObject); EXPECT_EQ(ValueObjectType::TYPE_DOUBLE, valueObject.GetType()); double doubleVal; valueObject.GetDouble(doubleVal); EXPECT_EQ(100.5, doubleVal); - valuesBucket.GetObject("graduated", valueObject); + valuesBucket->GetObject("graduated", valueObject); EXPECT_EQ(ValueObjectType::TYPE_BOOL, valueObject.GetType()); bool boolVal = false; valueObject.GetBool(boolVal); EXPECT_EQ(true, boolVal); - valuesBucket.GetObject("codes", valueObject); + valuesBucket->GetObject("codes", valueObject); EXPECT_EQ(ValueObjectType::TYPE_BLOB, valueObject.GetType()); std::vector blobVal; valueObject.GetBlob(blobVal); @@ -113,7 +112,7 @@ HWTEST_F(ValuesBucketTest, Values_Bucket_001, TestSize.Level1) EXPECT_EQ(2, blobVal.at(1)); EXPECT_EQ(3, blobVal.at(2)); - valuesBucket.GetObject("mark", valueObject); + valuesBucket->GetObject("mark", valueObject); EXPECT_EQ(ValueObjectType::TYPE_NULL, valueObject.GetType()); } @@ -192,7 +191,7 @@ HWTEST_F(ValuesBucketTest, Values_Bucket_003, TestSize.Level1) */ HWTEST_F(ValuesBucketTest, Values_Bucket_004, TestSize.Level1) { - MessageParcel parcel; + Parcel parcel; ValuesBucket values; values.PutInt("id", 1); values.PutString("name", std::string("zhangsan")); @@ -202,13 +201,12 @@ HWTEST_F(ValuesBucketTest, Values_Bucket_004, TestSize.Level1) values.PutBlob("codes", std::vector{ 1, 2, 3 }); values.PutNull("mark"); - EXPECT_EQ(true, ITypesUtil::Marshal(parcel, values)); - ValuesBucket valuesBucket; - ITypesUtil::Unmarshal(parcel, valuesBucket); - EXPECT_EQ(7, valuesBucket.Size()); - valuesBucket.Clear(); - ITypesUtil::Unmarshal(parcel, valuesBucket); - EXPECT_EQ(true, valuesBucket.IsEmpty()); + EXPECT_EQ(true, values.Marshalling(parcel)); + auto valuesBucket = std::shared_ptr(ValuesBucket::Unmarshalling(parcel)); + EXPECT_EQ(7, valuesBucket->Size()); + valuesBucket->Clear(); + valuesBucket = std::shared_ptr(ValuesBucket::Unmarshalling(parcel)); + EXPECT_EQ(true, valuesBucket->IsEmpty()); } /** diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe0e055dffe54c61c02d3904ee6725c7df3b05fb..dc4b1394af5cb69bedd870704fa2747855804620 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,7 +34,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/dis #aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/app/test/moduletest remoteTestSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/test/mock remoteTestSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/test remoteTestSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/test/native/unittest localTestSrc) +#aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/test/native/unittest localTestSrc)//TODO:加上preferences,全量运行有crash! aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/test/native/dataability/unittest localTestSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/test/native/rdb/unittest localTestSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/test/native/rdb_data_share_adapter/unittest localTestSrc)