From bf763f261cd2bf09fde461c58721fccf2ebaed29 Mon Sep 17 00:00:00 2001 From: htt1997 Date: Sat, 21 Sep 2024 15:54:09 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- .../adaptor/flat_object_storage_engine.h | 1 + .../include/adaptor/flat_object_store.h | 2 + ...uteddata_object_store_ipc_interface_code.h | 1 + .../innerkitsimpl/include/object_service.h | 1 + .../include/object_service_proxy.h | 1 + .../adaptor/flat_object_storage_engine.cpp | 4 + .../src/adaptor/flat_object_store.cpp | 24 + .../src/object_service_proxy.cpp | 30 + .../test/unittest/src/object_store_test.cpp | 12 + .../src/adaptor/js_distributedobjectstore.cpp | 1 + .../interfaces/innerkits/objectstore_errors.h | 5 + datamgr_service/bundle.json | 3 +- .../src/account_delegate_normal_impl.cpp | 1 + .../adapter/screenlock/src/screen_lock.cpp | 2 + .../app/src/installer/installer_impl.cpp | 6 +- .../app/src/kvstore_data_service.cpp | 13 +- .../app/src/kvstore_meta_manager.cpp | 8 +- .../distributeddataservice/framework/BUILD.gn | 1 + .../framework/cloud/asset_loader.cpp | 4 + .../framework/include/cloud/asset_loader.h | 1 + .../include/metadata/meta_data_manager.h | 1 + .../include/metadata/store_debug_info.h | 41 + .../include/metadata/store_meta_data.h | 1 + .../framework/metadata/meta_data_manager.cpp | 46 + .../framework/metadata/store_debug_info.cpp | 56 + .../framework/metadata/store_meta_data.cpp | 6 + .../framework/test/asset_loader_test.cpp | 12 + .../framework/test/cloud_test.cpp | 29 +- .../distributeddataservice/service/BUILD.gn | 2 + .../sync_strategies/network_sync_strategy.cpp | 2 +- .../service/common/value_proxy.cpp | 41 +- .../service/kvdb/kvdb_service_impl.cpp | 10 +- .../service/object/object_dms_handler.cpp | 87 + .../service/object/object_dms_handler.h | 59 + .../service/object/object_manager.cpp | 6 - .../service/object/object_service_impl.cpp | 20 + .../service/object/object_service_impl.h | 1 + .../service/object/object_service_stub.cpp | 11 + .../service/object/object_service_stub.h | 2 + .../service/rdb/rdb_general_store.cpp | 3 + .../service/rdb/rdb_service_impl.cpp | 81 +- .../service/rdb/rdb_service_impl.h | 4 + .../service/rdb/rdb_service_stub.cpp | 18 +- .../service/rdb/rdb_service_stub.h | 5 +- .../service/test/BUILD.gn | 31 + .../service/test/directory_manager_test.cpp | 30 + .../objectservicestub_fuzzer/BUILD.gn | 2 + .../service/test/kvdb_general_store_test.cpp | 4 +- .../service/test/object_dms_handler_test.cpp | 81 + .../cloud/device_manger_adapter_mock.cpp | 30 +- .../service/test/value_proxy_test.cpp | 19 +- .../service/udmf/store/runtime_store.cpp | 15 +- .../service/udmf/udmf_service_impl.cpp | 13 +- .../service/udmf/udmf_service_stub.cpp | 6 + .../distributed_event/include/dms_handler.h | 42 +- .../include/dms_listener_stub.h | 2 +- .../distributed_event/src/dms_client.cpp | 110 -- .../src/dms_listener_stub.cpp | 89 - .../distributed_event/src/dms_sa_client.cpp | 141 -- .../image_native/include/pixel_map.h | 3 + mock/src/mock_dms.cpp | 19 +- mock/src/mock_notification.cpp | 51 +- .../napi/common/src/js_common_type_init.cpp | 2 +- .../js/napi/common/src/js_utils.cpp | 11 +- .../src/napi_data_ability_predicates.cpp | 3 + .../js/napi/rdb/src/napi_rdb_predicates.cpp | 24 + .../relationalstore/src/napi_rdb_store.cpp | 2 +- .../native/appdatafwk/src/shared_block.cpp | 3 + .../dfx/include/rdb_fault_hiview_reporter.h | 31 +- .../dfx/src/rdb_fault_hiview_reporter.cpp | 182 +- .../native/rdb/include/connection.h | 4 + .../native/rdb/include/connection_pool.h | 2 + .../native/rdb/include/grd_api_manager.h | 3 + .../native/rdb/include/rd_statement.h | 1 - .../native/rdb/include/rdb_service_proxy.h | 4 +- .../native/rdb/include/rdb_store_impl.h | 60 +- .../native/rdb/include/rdb_store_manager.h | 8 +- .../native/rdb/include/rdb_types_util.h | 5 + .../native/rdb/include/sqlite_connection.h | 25 +- .../native/rdb/include/sqlite_global_config.h | 2 +- .../native/rdb/include/sqlite_sql_builder.h | 6 - .../native/rdb/include/sqlite_statement.h | 1 - .../native/rdb/include/sqlite_utils.h | 3 + .../native/rdb/include/step_result_set.h | 1 - .../native/rdb/mock/include/connection.h | 4 + .../native/rdb/mock/include/connection_pool.h | 2 + .../native/rdb/mock/include/rdb_store_impl.h | 60 +- .../rdb/mock/include/rdb_store_manager.h | 10 +- .../rdb/mock/include/sqlite_connection.h | 28 +- .../native/rdb/mock/include/step_result_set.h | 1 - .../mock/src/rdb_fault_hiview_reporter.cpp | 53 +- .../native/rdb/src/abs_result_set.cpp | 4 +- .../frameworks/native/rdb/src/connection.cpp | 33 +- .../native/rdb/src/connection_pool.cpp | 41 +- .../native/rdb/src/grd_api_manager.cpp | 12 + .../native/rdb/src/rd_connection.cpp | 1 + .../native/rdb/src/rd_statement.cpp | 37 +- .../frameworks/native/rdb/src/rd_utils.cpp | 65 +- .../frameworks/native/rdb/src/rdb_helper.cpp | 59 +- .../native/rdb/src/rdb_security_manager.cpp | 23 +- .../native/rdb/src/rdb_service_proxy.cpp | 25 +- .../native/rdb/src/rdb_sql_utils.cpp | 13 +- .../native/rdb/src/rdb_store_impl.cpp | 367 ++-- .../native/rdb/src/rdb_store_manager.cpp | 44 +- .../native/rdb/src/rdb_types_util.cpp | 18 +- .../frameworks/native/rdb/src/share_block.cpp | 21 - .../native/rdb/src/sqlite_connection.cpp | 256 ++- .../native/rdb/src/sqlite_global_config.cpp | 11 +- .../native/rdb/src/sqlite_sql_builder.cpp | 44 - .../native/rdb/src/sqlite_statement.cpp | 45 +- .../native/rdb/src/sqlite_utils.cpp | 107 +- .../native/rdb/src/step_result_set.cpp | 26 - ...data_relational_store_ipc_interface_code.h | 1 + .../inner_api/rdb/include/rdb_service.h | 4 +- .../inner_api/rdb/include/rdb_store_config.h | 12 +- .../inner_api/rdb/include/rdb_types.h | 18 + .../rdb/mock/include/rdb_store_config.h | 12 +- .../interfaces/ndk/src/relational_store.cpp | 312 ++- .../ndk/src/relational_store_inner.h | 54 + relational_store/test/native/rdb/BUILD.gn | 2 + .../test/native/rdb/unittest/common.h | 2 + .../rdb/unittest/rdb_double_write_test.cpp | 220 ++- .../native/rdb/unittest/rdb_helper_test.cpp | 93 +- .../unittest/rdb_security_manager_test.cpp | 21 + .../rdb_store_backup_restore_test.cpp | 321 ++++ .../rdb/unittest/rdb_store_impl_test.cpp | 71 + .../rdb/unittest/rdb_store_subscribe_test.cpp | 70 +- .../native/rdb/unittest/rdb_update_test.cpp | 167 +- .../native/rdb/unittest/rdb_utils_test.cpp | 20 - .../native/rdb/unittest/sqlite_utils_test.cpp | 132 ++ test/CMakeLists.txt | 2 +- udmf/CMakeLists.txt | 4 +- udmf/bundle.json | 4 +- udmf/framework/common/graph.cpp | 2 +- udmf/framework/common/tlv_object.cpp | 1094 ++--------- udmf/framework/common/tlv_object.h | 153 +- udmf/framework/common/tlv_tag.h | 78 + udmf/framework/common/tlv_util.cpp | 1711 ++++------------- udmf/framework/common/tlv_util.h | 562 ++++-- udmf/framework/common/udmf_types_util.cpp | 15 +- udmf/framework/common/udmf_utils.cpp | 21 + udmf/framework/common/udmf_utils.h | 4 + udmf/framework/common/unittest/BUILD.gn | 82 + .../common/unittest/mock/tlv_util_mock.cpp | 232 +++ .../common/unittest/tlv_util_test.cpp | 654 +++++++ .../udmf_types_util_abnormal_test.cpp | 138 ++ .../common/unittest/udmf_types_util_test.cpp | 119 +- .../innerkitsimpl/client/utd_client.cpp | 65 +- .../innerkitsimpl/common/unified_meta.cpp | 24 +- .../innerkitsimpl/convert/udmf_conversion.cpp | 154 ++ .../data/application_defined_record.cpp | 27 + udmf/framework/innerkitsimpl/data/file.cpp | 36 + udmf/framework/innerkitsimpl/data/html.cpp | 22 +- udmf/framework/innerkitsimpl/data/link.cpp | 21 +- .../innerkitsimpl/data/plain_text.cpp | 23 +- .../data/preset_type_descriptors.cpp | 14 + .../data/system_defined_appitem.cpp | 40 +- .../data/system_defined_form.cpp | 46 + .../data/system_defined_pixelmap.cpp | 41 +- .../data/system_defined_record.cpp | 21 +- udmf/framework/innerkitsimpl/data/text.cpp | 17 +- .../data/unified_data_helper.cpp | 11 +- .../innerkitsimpl/data/unified_record.cpp | 21 +- .../service/udmf_service_proxy.cpp | 3 + .../innerkitsimpl/test/unittest/BUILD.gn | 7 +- .../innerkitsimpl/test/unittest/html_test.cpp | 22 - .../innerkitsimpl/test/unittest/link_test.cpp | 22 - .../mock/system_defined_pixelmap_mock.cpp | 6 - .../test/unittest/mock/tlv_object_mock.cpp | 171 +- .../unittest/ndk_data_conversion_test.cpp | 145 ++ .../test/unittest/plain_text_test.cpp | 22 - .../unittest/system_defined_appitem_test.cpp | 4 +- .../unittest/system_defined_record_test.cpp | 2 +- .../test/unittest/udmf_client_test.cpp | 121 +- .../jskitsimpl/common/napi_error_utils.cpp | 4 +- udmf/framework/ndkimpl/data/udmf.cpp | 72 +- .../framework/ndkimpl/data/udmf_capi_common.h | 4 +- udmf/framework/ndkimpl/unittest/udmf_test.cpp | 58 +- udmf/framework/ndkimpl/unittest/uds_test.cpp | 2 +- udmf/interfaces/cj/BUILD.gn | 128 ++ .../cj/include/type_descriptor_ffi.h | 43 + .../cj/include/type_descriptor_impl.h | 56 + udmf/interfaces/cj/include/udmf_log.h | 41 + udmf/interfaces/cj/include/unified_data_ffi.h | 38 + .../interfaces/cj/include/unified_data_impl.h | 50 + .../cj/include/unified_record_ffi.h | 37 + .../cj/include/unified_record_impl.h | 68 + .../cj/include/uniform_type_descriptor_ffi.h | 37 + .../cj/include/uniform_type_descriptor_impl.h | 35 + udmf/interfaces/cj/include/utils.h | 32 + .../interfaces/cj/src/type_descriptor_ffi.cpp | 144 ++ .../cj/src/type_descriptor_impl.cpp | 114 ++ udmf/interfaces/cj/src/unified_data_ffi.cpp | 98 + udmf/interfaces/cj/src/unified_data_impl.cpp | 138 ++ udmf/interfaces/cj/src/unified_record_ffi.cpp | 64 + .../interfaces/cj/src/unified_record_impl.cpp | 208 ++ .../cj/src/uniform_type_descriptor_ffi.cpp | 44 + .../cj/src/uniform_type_descriptor_impl.cpp | 98 + udmf/interfaces/cj/src/utils.cpp | 45 + udmf/interfaces/innerkits/BUILD.gn | 1 + .../innerkits/common/unified_meta.h | 29 +- .../innerkits/convert/udmf_conversion.h | 37 + .../data/application_defined_record.h | 2 + udmf/interfaces/innerkits/data/file.h | 1 + udmf/interfaces/innerkits/data/html.h | 3 +- udmf/interfaces/innerkits/data/link.h | 3 +- udmf/interfaces/innerkits/data/plain_text.h | 3 +- .../innerkits/data/system_defined_appitem.h | 3 +- .../innerkits/data/system_defined_form.h | 7 +- .../innerkits/data/system_defined_pixelmap.h | 4 +- .../innerkits/data/system_defined_record.h | 4 +- udmf/interfaces/innerkits/data/text.h | 4 +- .../innerkits/data/unified_record.h | 8 +- 213 files changed, 8194 insertions(+), 4234 deletions(-) create mode 100644 datamgr_service/services/distributeddataservice/framework/include/metadata/store_debug_info.h create mode 100644 datamgr_service/services/distributeddataservice/framework/metadata/store_debug_info.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/object/object_dms_handler.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/object/object_dms_handler.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/object_dms_handler_test.cpp delete mode 100644 mock/innerkits/dmsfwk_standard/distributed_event/src/dms_client.cpp delete mode 100644 mock/innerkits/dmsfwk_standard/distributed_event/src/dms_listener_stub.cpp delete mode 100644 mock/innerkits/dmsfwk_standard/distributed_event/src/dms_sa_client.cpp create mode 100644 relational_store/interfaces/ndk/src/relational_store_inner.h create mode 100644 relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp create mode 100644 udmf/framework/common/tlv_tag.h create mode 100644 udmf/framework/common/unittest/mock/tlv_util_mock.cpp create mode 100644 udmf/framework/common/unittest/tlv_util_test.cpp create mode 100644 udmf/framework/common/unittest/udmf_types_util_abnormal_test.cpp create mode 100644 udmf/framework/innerkitsimpl/convert/udmf_conversion.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/ndk_data_conversion_test.cpp create mode 100644 udmf/interfaces/cj/BUILD.gn create mode 100644 udmf/interfaces/cj/include/type_descriptor_ffi.h create mode 100644 udmf/interfaces/cj/include/type_descriptor_impl.h create mode 100644 udmf/interfaces/cj/include/udmf_log.h create mode 100644 udmf/interfaces/cj/include/unified_data_ffi.h create mode 100644 udmf/interfaces/cj/include/unified_data_impl.h create mode 100644 udmf/interfaces/cj/include/unified_record_ffi.h create mode 100644 udmf/interfaces/cj/include/unified_record_impl.h create mode 100644 udmf/interfaces/cj/include/uniform_type_descriptor_ffi.h create mode 100644 udmf/interfaces/cj/include/uniform_type_descriptor_impl.h create mode 100644 udmf/interfaces/cj/include/utils.h create mode 100644 udmf/interfaces/cj/src/type_descriptor_ffi.cpp create mode 100644 udmf/interfaces/cj/src/type_descriptor_impl.cpp create mode 100644 udmf/interfaces/cj/src/unified_data_ffi.cpp create mode 100644 udmf/interfaces/cj/src/unified_data_impl.cpp create mode 100644 udmf/interfaces/cj/src/unified_record_ffi.cpp create mode 100644 udmf/interfaces/cj/src/unified_record_impl.cpp create mode 100644 udmf/interfaces/cj/src/uniform_type_descriptor_ffi.cpp create mode 100644 udmf/interfaces/cj/src/uniform_type_descriptor_impl.cpp create mode 100644 udmf/interfaces/cj/src/utils.cpp create mode 100644 udmf/interfaces/innerkits/convert/udmf_conversion.h diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h index d94ee1f1..83afb625 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h @@ -51,6 +51,7 @@ public: private: constexpr static const char *DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; std::mutex operationMutex_{}; + std::mutex watcherMutex_{}; std::shared_ptr storeManager_; std::map delegates_; std::map> observerMap_; diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h index 8ab380d2..56d26aa0 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h @@ -46,6 +46,7 @@ public: std::function> &data, bool allReady)> &callback); int32_t UnregisterDataChange(const std::string &bundleName, const std::string &sessionId); int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId); + bool IsContinue(); private: int32_t SaveObject(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const std::map> &objectData, @@ -87,6 +88,7 @@ private: uint32_t Put(const std::string &sessionId, const std::string &key, std::vector value); uint32_t Get(const std::string &sessionId, const std::string &key, Bytes &value); + static constexpr const char* DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; std::shared_ptr storageEngine_; CacheManager *cacheManager_; std::mutex mutex_; diff --git a/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h b/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h index d1728569..1de2eb22 100644 --- a/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h +++ b/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h @@ -29,6 +29,7 @@ enum class ObjectServiceInterfaceCode { OBJECTSTORE_ON_ASSET_CHANGED, OBJECTSTORE_BIND_ASSET_STORE, OBJECTSTORE_DELETE_SNAPSHOT, + OBJECTSTORE_IS_CONTINUE, OBJECTSTORE_SERVICE_CMD_MAX }; diff --git a/data_object/frameworks/innerkitsimpl/include/object_service.h b/data_object/frameworks/innerkitsimpl/include/object_service.h index 37ea3754..0c5c8d57 100644 --- a/data_object/frameworks/innerkitsimpl/include/object_service.h +++ b/data_object/frameworks/innerkitsimpl/include/object_service.h @@ -40,6 +40,7 @@ public: virtual int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) = 0; virtual int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) = 0; + virtual int32_t IsContinue(bool &result) = 0; }; } // namespace OHOS::DistributedObject #endif diff --git a/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h b/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h index a6b2c271..366207fc 100644 --- a/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h +++ b/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h @@ -42,6 +42,7 @@ public: int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) override; int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) override; + int32_t IsContinue(bool &result) override; private: static inline BrokerDelegator delegator_; }; diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp index 8f51a161..1e43feb4 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp @@ -79,6 +79,7 @@ uint32_t FlatObjectStorageEngine::Close() void FlatObjectStorageEngine::OnComplete(const std::string &key, const std::map &devices, std::shared_ptr statusWatcher) { + std::lock_guard lock(watcherMutex_); LOG_INFO("complete"); if (statusWatcher != nullptr) { for (auto item : devices) { @@ -351,6 +352,7 @@ uint32_t FlatObjectStorageEngine::SetStatusNotifier(std::shared_ptr void { + std::lock_guard lock(watcherMutex_); LOG_INFO("complete"); if (statusWatcher_ == nullptr) { LOG_INFO("FlatObjectStorageEngine::statusWatcher_ null"); @@ -377,6 +379,7 @@ uint32_t FlatObjectStorageEngine::SetStatusNotifier(std::shared_ptrSetStoreStatusNotifier(databaseStatusNotifyCallback); LOG_INFO("FlatObjectStorageEngine::SetStatusNotifier success"); + std::lock_guard lock(watcherMutex_); statusWatcher_ = watcher; return SUCCESS; } @@ -433,6 +436,7 @@ uint32_t FlatObjectStorageEngine::GetItems(const std::string &key, std::map lock(watcherMutex_); if (statusWatcher_ == nullptr) { return; } 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 c7b109a3..a7b8f549 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -15,10 +15,12 @@ #include "flat_object_store.h" +#include "accesstoken_kit.h" #include "block_data.h" #include "bytes_utils.h" #include "client_adaptor.h" #include "distributed_objectstore_impl.h" +#include "ipc_skeleton.h" #include "logger.h" #include "object_callback_impl.h" #include "object_radar_reporter.h" @@ -51,6 +53,13 @@ FlatObjectStore::~FlatObjectStore() uint32_t FlatObjectStore::CreateObject(const std::string &sessionId) { + if (!cacheManager_->IsContinue()) { // NOT IN CONTINUE, CHECK PERMISSION + auto tokenId = IPCSkeleton::GetSelfTokenID(); + int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, DISTRIBUTED_DATASYNC); + if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + return ERR_NO_PERMISSION; + } + } if (!storageEngine_->isOpened_ && storageEngine_->Open(bundleName_) != SUCCESS) { LOG_ERROR("FlatObjectStore::DB has not inited"); return ERR_DB_NOT_INIT; @@ -544,4 +553,19 @@ int32_t CacheManager::DeleteSnapshot(const std::string &bundleName, const std::s LOG_INFO("object delete snapshot successful"); return status; } + +bool CacheManager::IsContinue() +{ + sptr proxy = ClientAdaptor::GetObjectService(); + if (proxy == nullptr) { + LOG_ERROR("Object service proxy is nullptr"); + return false; + } + bool isContinue = false; + int32_t status = proxy->IsContinue(isContinue); + if (status != SUCCESS) { + LOG_ERROR("Get continue state failed, status: %{public}d, isContinue: %{public}d", status, isContinue); + } + return isContinue; +} } // namespace OHOS::ObjectStore diff --git a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp index eedef6e9..715315cc 100644 --- a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp +++ b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp @@ -268,4 +268,34 @@ int32_t ObjectServiceProxy::DeleteSnapshot(const std::string &bundleName, const } return reply.ReadInt32(); } + +int32_t ObjectServiceProxy::IsContinue(bool &result) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERROR("Remote object is nullptr."); + return ERR_IPC; + } + MessageParcel data; + MessageParcel reply; + MessageOption mo { MessageOption::TF_SYNC }; + if (!data.WriteInterfaceToken(ObjectServiceProxy::GetDescriptor())) { + ZLOGE("Write descriptor failed"); + return ERR_IPC; + } + if (!ITypesUtil::Marshal(data, result)) { + ZLOGE("Marshall result failed, result: %{public}d", result); + return ERR_IPC; + } + int32_t status = remote->SendRequest(static_cast(ObjectCode::OBJECTSTORE_IS_CONTINUE), data, reply, mo); + if (status != SUCCESS) { + ZLOGE("Send request failed, status: %{public}d", status); + return status; + } + if (!ITypesUtil::Unmarshal(reply, result)) { + ZLOGE("Unmarshal result failed, result: %{public}d", result); + return ERR_IPC; + } + return SUCCESS; +} } // namespace OHOS::DistributedObject 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 61cd98e1..7e764e70 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 @@ -1286,6 +1286,18 @@ HWTEST_F(NativeObjectStoreTest, CacheManager_UnregisterDataChange_001, TestSize. EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); } +/** + * @tc.name: CacheManager_IsContinue_001 + * @tc.desc: test CacheManager IsContinue. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_IsContinue_001, TestSize.Level1) +{ + auto cacheManager = std::make_shared(); + auto result = cacheManager->IsContinue(); + EXPECT_FALSE(result); +} + /** * @tc.name: DistributedObject_NotifyCachedStatus_001 * @tc.desc: test DistributedObjectStore NotifyCachedStatus. diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp index f18d2787..49d167a3 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp @@ -188,6 +188,7 @@ napi_value JSDistributedObjectStore::JSCreateObjectSync(napi_env env, napi_callb uint32_t result = 0; DistributedObject *object = objectInfo->CreateObject(sessionId, result); NAPI_ASSERT_ERRCODE_V9(env, result != ERR_EXIST, version, std::make_shared()); + NAPI_ASSERT_ERRCODE_V9(env, result != ERR_NO_PERMISSION, version, std::make_shared()); NAPI_ASSERT_ERRCODE_V9(env, result == SUCCESS && object != nullptr, version, innerError); return NewDistributedObject(env, objectInfo, object, objectId); } diff --git a/data_object/interfaces/innerkits/objectstore_errors.h b/data_object/interfaces/innerkits/objectstore_errors.h index 2b59296f..8794d5eb 100644 --- a/data_object/interfaces/innerkits/objectstore_errors.h +++ b/data_object/interfaces/innerkits/objectstore_errors.h @@ -135,6 +135,11 @@ constexpr uint32_t ERR_INVALID_ARGS = BASE_ERR_OFFSET + 21; * @brief Ipc error. */ constexpr uint32_t ERR_IPC = BASE_ERR_OFFSET + 22; + +/** + * @brief No DATA_SYNC permission. + */ +constexpr uint32_t ERR_NO_PERMISSION = BASE_ERR_OFFSET + 23; } // namespace OHOS::ObjectStore #endif diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index 3d202f77..059721cd 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -86,7 +86,8 @@ "app_file_service", "file_api", "openssl", - "json" + "json", + "dmsfwk" ], "third_party": [ "libuv", diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp index e59d08a2..c99e49d9 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp @@ -17,6 +17,7 @@ #include "account_delegate_normal_impl.h" #include #include +#include #include #include #include diff --git a/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp b/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp index 92e9118e..a83e2bb4 100644 --- a/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp @@ -13,7 +13,9 @@ * limitations under the License. */ +#define LOG_TAG "screen_lock" #include "screen_lock.h" + #include "screenlock_manager.h" namespace OHOS::DistributedData { diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp index 62832996..98de6baf 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp @@ -80,12 +80,14 @@ void InstallEventSubscriber::OnUninstall(const std::string &bundleName, int32_t bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), userId, appIndex); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); - PermitDelegate::GetInstance().DelCache(meta.GetKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); + PermitDelegate::GetInstance().DelCache(meta.GetKey()); } } } diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp index ecc50daa..5606a61a 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -549,6 +549,7 @@ Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vec dbOption.createIfNecessary = options.createIfMissing; dbOption.isMemoryDb = (!options.persistent); dbOption.isEncryptedDb = options.encrypt; + dbOption.isNeedCompressOnSync = options.isNeedCompress; if (options.encrypt) { dbOption.cipher = DistributedDB::CipherType::AES_256_GCM; dbOption.passwd = password; @@ -688,10 +689,13 @@ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) ZLOGI("bundleName:%{public}s, user:%{public}s", meta.bundleName.c_str(), meta.user.c_str()); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); - MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); PermitDelegate::GetInstance().DelCache(meta.GetKey()); } g_kvStoreAccountEventStatus = 0; @@ -858,10 +862,13 @@ int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32 Anonymous::Change(meta.storeId).c_str(), appIndex); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetBackupSecretKey(), true); MetaDataManager::GetInstance().DelMeta(meta.appId, true); - MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetDebugInfoKey(), true); + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); PermitDelegate::GetInstance().DelCache(meta.GetKey()); } } diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 31a5fd76..8cf32c40 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -285,17 +285,11 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() if (dbStatusTmp == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { ZLOGE("meta data corrupted!"); option.isNeedRmCorruptedDb = true; - auto fullName = GetBackupPath(); delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, - [&delegate, &dbStatusTmp, &fullName](DistributedDB::DBStatus dbStatus, + [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) { delegate = nbDelegate; dbStatusTmp = dbStatus; - if (dbStatusTmp == DistributedDB::DBStatus::OK && delegate != nullptr) { - ZLOGI("start to recover meta data"); - DistributedDB::CipherPassword password; - delegate->Import(fullName, password); - } }); } diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index ca78af92..0c0c1348 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -85,6 +85,7 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/meta_data.cpp", "metadata/meta_data_manager.cpp", "metadata/secret_key_meta_data.cpp", + "metadata/store_debug_info.cpp", "metadata/store_meta_data.cpp", "metadata/store_meta_data_local.cpp", "metadata/strategy_meta_data.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/asset_loader.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/asset_loader.cpp index 70c1b677..711879f7 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/asset_loader.cpp @@ -25,4 +25,8 @@ int32_t AssetLoader::RemoveLocalAssets(const std::string &tableName, const std:: { return E_NOT_SUPPORT; } +int32_t AssetLoader::Cancel() +{ + return E_NOT_SUPPORT; +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/asset_loader.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/asset_loader.h index 6ea12fff..fc9dcdcc 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/asset_loader.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/asset_loader.h @@ -26,6 +26,7 @@ public: VBucket &assets); virtual int32_t RemoveLocalAssets(const std::string &tableName, const std::string &gid, const Value &prefix, VBucket &assets); + virtual int32_t Cancel(); }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h index 4c5fb869..433af7b7 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h @@ -85,6 +85,7 @@ private: ~MetaDataManager(); API_EXPORT bool GetEntries(const std::string &prefix, std::vector &entries, bool isLocal); + void StopSA(); bool inited_ = false; std::mutex mutex_; diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_debug_info.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_debug_info.h new file mode 100644 index 00000000..8d9ff948 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_debug_info.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H +#include "serializable/serializable.h" +#include +namespace OHOS::DistributedData { +struct API_EXPORT StoreDebugInfo final : public Serializable { + struct FileInfo final : public Serializable { + uint64_t inode = 0; + uint64_t size = 0; + uint32_t dev = 0; + uint32_t mode = 0; + uint32_t uid = 0; + uint32_t gid = 0; + bool Marshal(Serializable::json &node) const override; + bool Unmarshal(const Serializable::json &node) override; + + }; + std::map fileInfos; + API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); + bool Marshal(Serializable::json &node) const override; + bool Unmarshal(const Serializable::json &node) override; +private: + static constexpr const char *KEY_PREFIX = "StoreDebugInfo"; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_DEBUG_INFO_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index ff5e203a..007fd6ab 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -84,6 +84,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT std::string GetStrategyKey() const; API_EXPORT std::string GetBackupSecretKey() const; API_EXPORT std::string GetAutoLaunchKey() const; + API_EXPORT std::string GetDebugInfoKey() const; API_EXPORT std::string GetStoreAlias() const; API_EXPORT StoreInfo GetStoreInfo() const; API_EXPORT static std::string GetKey(const std::initializer_list &fields); diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index 777a8d93..61ea1076 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -14,6 +14,7 @@ */ #include "metadata/meta_data_manager.h" +#include #define LOG_TAG "MetaDataManager" #include "kv_store_nb_delegate.h" @@ -85,6 +86,10 @@ MetaDataManager::Filter::Filter(const std::string &pattern) : pattern_(pattern) void MetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data) { + if (filter_ == nullptr) { + ZLOGE("filter_ is nullptr!"); + return; + } auto values = { &data.GetEntriesInserted(), &data.GetEntriesUpdated(), &data.GetEntriesDeleted() }; int32_t next = MetaDataManager::INSERT; for (auto value : values) { @@ -116,6 +121,10 @@ void MetaObserver::HandleChanges(int32_t flag, std::vector> &p if (priData.empty()) { return; } + if (filter_ == nullptr) { + ZLOGE("filter_ is nullptr!"); + return; + } for (const auto &priKey : priData) { if (priKey.empty()) { continue; @@ -184,6 +193,12 @@ bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value auto data = Serializable::Marshall(value); auto status = isLocal ? metaStore_->PutLocal({ key.begin(), key.end() }, { data.begin(), data.end() }) : metaStore_->Put({ key.begin(), key.end() }, { data.begin(), data.end() }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + StopSA(); + return false; + } if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } @@ -206,6 +221,12 @@ bool MetaDataManager::LoadMeta(const std::string &key, Serializable &value, bool DistributedDB::Value data; auto status = isLocal ? metaStore_->GetLocal({ key.begin(), key.end() }, data) : metaStore_->Get({ key.begin(), key.end() }, data); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + StopSA(); + return false; + } if (status != DistributedDB::DBStatus::OK) { return false; } @@ -221,6 +242,11 @@ bool MetaDataManager::GetEntries(const std::string &prefix, std::vector & std::vector dbEntries; auto status = isLocal ? metaStore_->GetLocalEntries({ prefix.begin(), prefix.end() }, dbEntries) : metaStore_->GetEntries({ prefix.begin(), prefix.end() }, dbEntries); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d", status, isLocal); + StopSA(); + return false; + } if (status != DistributedDB::DBStatus::OK && status != DistributedDB::DBStatus::NOT_FOUND) { ZLOGE("failed! prefix:%{public}s status:%{public}d isLocal:%{public}d", Anonymous::Change(prefix).c_str(), status, isLocal); @@ -242,6 +268,12 @@ bool MetaDataManager::DelMeta(const std::string &key, bool isLocal) DistributedDB::Value data; auto status = isLocal ? metaStore_->DeleteLocal({ key.begin(), key.end() }) : metaStore_->Delete({ key.begin(), key.end() }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d isLocal:%{public}d, key:%{public}s", + status, isLocal, Anonymous::Change(key).c_str()); + StopSA(); + return false; + } if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } @@ -263,6 +295,11 @@ bool MetaDataManager::Sync(const std::vector &devices, OnComplete c } complete(results); }); + if (status == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("db corrupted! status:%{public}d", status); + StopSA(); + return false; + } if (status != DistributedDB::OK) { ZLOGW("meta data sync error %{public}d.", status); } @@ -299,4 +336,13 @@ bool MetaDataManager::Unsubscribe(std::string filter) return metaObservers_.Erase(filter); } + +void MetaDataManager::StopSA() +{ + ZLOGI("stop distributeddata"); + int err = raise(SIGKILL); + if (err < 0) { + ZLOGE("stop distributeddata failed, errCode: %{public}d", err); + } +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_debug_info.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_debug_info.cpp new file mode 100644 index 00000000..014063f0 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_debug_info.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "metadata/store_debug_info.h" +#include "utils/constant.h" +namespace OHOS::DistributedData { +bool StoreDebugInfo::FileInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(inode)], inode); + SetValue(node[GET_NAME(size)], size); + SetValue(node[GET_NAME(dev)], dev); + SetValue(node[GET_NAME(mode)], mode); + SetValue(node[GET_NAME(uid)], uid); + SetValue(node[GET_NAME(gid)], gid); + return true; +} + +bool StoreDebugInfo::FileInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(inode), inode); + GetValue(node, GET_NAME(size), size); + GetValue(node, GET_NAME(dev), dev); + GetValue(node, GET_NAME(mode), mode); + GetValue(node, GET_NAME(uid), uid); + GetValue(node, GET_NAME(gid), gid); + return true; +} + +bool StoreDebugInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(fileInfos)], fileInfos); + return true; +} + +bool StoreDebugInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(fileInfos), fileInfos); + return true; +} + +std::string StoreDebugInfo::GetPrefix(const std::initializer_list &fields) +{ + return Constant::Join(KEY_PREFIX, Constant::KEY_SEPARATOR, fields); +} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp index 2a31c380..b33b7f5e 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -17,6 +17,7 @@ #include "metadata/auto_launch_meta_data.h" #include "metadata/secret_key_meta_data.h" +#include "metadata/store_debug_info.h" #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" #include "utils/anonymous.h" @@ -187,6 +188,11 @@ std::string StoreMetaData::GetAutoLaunchKey() const return AutoLaunchMetaData::GetPrefix({ deviceId, user, "default", bundleName, storeId }); } +std::string StoreMetaData::GetDebugInfoKey() const +{ + return StoreDebugInfo::GetPrefix({ deviceId, user, "default", bundleName, storeId, std::to_string(instanceId) }); +} + std::string StoreMetaData::GetStoreAlias() const { return Anonymous::Change(storeId); diff --git a/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp index a9ff6e45..7f2f0da6 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/asset_loader_test.cpp @@ -53,3 +53,15 @@ HWTEST_F(AssetLoaderTest, RemoveLocalAssets, TestSize.Level1) auto ret = loader.RemoveLocalAssets(tableName, gid, prefix, assets); ASSERT_EQ(ret, E_NOT_SUPPORT); } + +/** +* @tc.name: Cancel +* @tc.desc: cancel. +* @tc.type: FUNC +*/ +HWTEST_F(AssetLoaderTest, Cancel, TestSize.Level1) +{ + AssetLoader loader; + auto ret = loader.Cancel(); + ASSERT_EQ(ret, E_NOT_SUPPORT); +} diff --git a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp index 90232b18..2688a1ec 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp @@ -229,34 +229,9 @@ HWTEST_F(CloudInfoTest, GetPrefix, TestSize.Level0) * @tc.desc: Marshal and Unmarshal of CloudInfo. * @tc.type: FUNC * @tc.require: -* @tc.author: Anvette -*/ -HWTEST_F(CloudInfoTest, CloudInfoTest001, TestSize.Level0) -{ - CloudInfo cloudInfo1; - cloudInfo1.user = 111; - cloudInfo1.id = "test1_id"; - cloudInfo1.totalSpace = 0; - cloudInfo1.remainSpace = 0; - cloudInfo1.enableCloud = false; - - Serializable::json node1; - cloudInfo1.Marshal(node1); - EXPECT_EQ(Serializable::Marshall(cloudInfo1), to_string(node1)); - - CloudInfo cloudInfo2; - cloudInfo2.Unmarshal(node1); - EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); -} - -/** -* @tc.name: CloudInfoTest002 -* @tc.desc: Marshal and Unmarshal of CloudInfo. -* @tc.type: FUNC -* @tc.require: * @tc.author: SQL */ -HWTEST_F(CloudInfoTest, CloudInfoTest002, TestSize.Level0) +HWTEST_F(CloudInfoTest, CloudInfoTest001, TestSize.Level0) { CloudInfo cloudInfo1; cloudInfo1.user = 111; @@ -273,7 +248,7 @@ HWTEST_F(CloudInfoTest, CloudInfoTest002, TestSize.Level0) CloudInfo cloudInfo2; cloudInfo2.Unmarshal(node1); - EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); + EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo2)); } /** diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index df0103f7..6f0b47f2 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -109,6 +109,7 @@ ohos_shared_library("distributeddatasvc") { "object/object_asset_machine.cpp", "object/object_callback_proxy.cpp", "object/object_data_listener.cpp", + "object/object_dms_handler.cpp", "object/object_manager.cpp", "object/object_service_impl.cpp", "object/object_service_stub.cpp", @@ -153,6 +154,7 @@ ohos_shared_library("distributeddatasvc") { "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp index 827bf628..d7b6f74d 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp @@ -55,7 +55,7 @@ NetworkSyncStrategy::~NetworkSyncStrategy() int32_t NetworkSyncStrategy::CheckSyncAction(const StoreInfo &storeInfo) { if (storeInfo.user == StrategyInfo::ROOT_USER) { - return E_OK; + return next_ ? next_->CheckSyncAction(storeInfo) : E_OK; } if (!DeviceManagerAdapter::GetInstance().IsNetworkAvailable()) { return E_NETWORK_ERROR; diff --git a/datamgr_service/services/distributeddataservice/service/common/value_proxy.cpp b/datamgr_service/services/distributeddataservice/service/common/value_proxy.cpp index dfec667a..a650c66f 100644 --- a/datamgr_service/services/distributeddataservice/service/common/value_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/common/value_proxy.cpp @@ -298,28 +298,27 @@ uint32_t ValueProxy::Asset::ConvertToDataStatus(const DistributedDB::Asset &asse { auto highStatus = GetHighStatus(asset.status); auto lowStatus = GetLowStatus(asset.status); - if (lowStatus == DistributedDB::AssetStatus::DOWNLOADING) { - if (asset.flag == static_cast(DistributedDB::AssetOpType::DELETE)) { - lowStatus = DistributedData::Asset::STATUS_DELETE; - } else { + switch (lowStatus) { + case static_cast(DistributedDB::AssetStatus::NORMAL): + lowStatus = DistributedData::Asset::STATUS_NORMAL; + break; + case static_cast(DistributedDB::AssetStatus::DOWNLOADING): lowStatus = DistributedData::Asset::STATUS_DOWNLOADING; - } - } else if (lowStatus == DistributedDB::AssetStatus::ABNORMAL) { - lowStatus = DistributedData::Asset::STATUS_ABNORMAL; - } else { - switch (asset.flag) { - case static_cast(DistributedDB::AssetOpType::INSERT): - lowStatus = DistributedData::Asset::STATUS_INSERT; - break; - case static_cast(DistributedDB::AssetOpType::UPDATE): - lowStatus = DistributedData::Asset::STATUS_UPDATE; - break; - case static_cast(DistributedDB::AssetOpType::DELETE): - lowStatus = DistributedData::Asset::STATUS_DELETE; - break; - default: - lowStatus = DistributedData::Asset::STATUS_NORMAL; - } + break; + case static_cast(DistributedDB::AssetStatus::ABNORMAL): + lowStatus = DistributedData::Asset::STATUS_ABNORMAL; + break; + case static_cast(DistributedDB::AssetStatus::INSERT): + lowStatus = DistributedData::Asset::STATUS_INSERT; + break; + case static_cast(DistributedDB::AssetStatus::UPDATE): + lowStatus = DistributedData::Asset::STATUS_UPDATE; + break; + case static_cast(DistributedDB::AssetStatus::DELETE): + lowStatus = DistributedData::Asset::STATUS_DELETE; + break; + default: + lowStatus = DistributedData::Asset::STATUS_NORMAL; } return lowStatus | highStatus; } diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index b225490d..8e6bb524 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -194,9 +194,12 @@ Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId) }); MetaDataManager::GetInstance().DelMeta(metaData.GetKey()); MetaDataManager::GetInstance().DelMeta(metaData.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(metaData.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(metaData.GetStrategyKey()); - MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData.GetDebugInfoKey(), true); PermitDelegate::GetInstance().DelCache(metaData.GetKey()); AutoCache::GetInstance().CloseStore(tokenId, storeId); ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), @@ -1059,8 +1062,9 @@ Status KVDBServiceImpl::DoSyncBegin(const std::vector &devices, con SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, info.syncId, DATA_TYPE, meta.dataType); auto store = AutoCache::GetInstance().GetStore(meta, watcher); if (store == nullptr) { - ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", meta.bundleName.c_str(), - Anonymous::Change(meta.storeId).c_str(), meta.dataDir.c_str()); + ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s storeId length:%{public}zu dir:%{public}s", + meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), + meta.storeId.size(), meta.dataDir.c_str()); RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_FAILED, ERROR_CODE, Status::ERROR, BIZ_STATE, END, SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.cpp b/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.cpp new file mode 100644 index 00000000..8dbfeea9 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectDmsHandler" + +#include "object_dms_handler.h" + +#include "dms_handler.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DistributedObject { +void DmsEventListener::DSchedEventNotify(DistributedSchedule::EventNotify ¬ify) +{ + ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify); +} + +void ObjectDmsHandler::ReceiveDmsEvent(DistributedSchedule::EventNotify &event) +{ + std::lock_guard lock(mutex_); + auto now = std::chrono::steady_clock::now(); + dmsEvents_.push_back(std::make_pair(event, now)); + if (dmsEvents_.size() > MAX_EVENTS) { + dmsEvents_.pop_front(); + } + ZLOGI("Received dms event, eventType: %{public}d, srcNetworkId: %{public}s, srcBundleName: %{public}s, " + "dstNetworkId: %{public}s, destBundleName: %{public}s", event.dSchedEventType_, + DistributedData::Anonymous::Change(event.srcNetworkId_).c_str(), event.srcBundleName_.c_str(), + DistributedData::Anonymous::Change(event.dstNetworkId_).c_str(), event.destBundleName_.c_str()); +} + +bool ObjectDmsHandler::IsContinue(const std::string &networkId, const std::string &bundleName) +{ + std::lock_guard lock(mutex_); + auto validityTime = std::chrono::steady_clock::now() - std::chrono::seconds(VALIDITY); + for (auto it = dmsEvents_.rbegin(); it != dmsEvents_.rend(); ++it) { + if (it->second < validityTime) { + continue; + } + if (it->first.dSchedEventType_ != DistributedSchedule::DMS_CONTINUE) { + continue; + } + if (it->first.srcNetworkId_ == networkId && it->first.srcBundleName_ == bundleName) { + ZLOGI("Continue source, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(networkId).c_str(), bundleName.c_str()); + return true; + } + if (it->first.dstNetworkId_ == networkId && it->first.destBundleName_ == bundleName) { + ZLOGI("Continue destination, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(networkId).c_str(), bundleName.c_str()); + return true; + } + } + ZLOGW("Not in continue, networkId: %{public}s, bundleName: %{public}s", + DistributedData::Anonymous::Change(networkId).c_str(), bundleName.c_str()); + return false; +} + +void ObjectDmsHandler::RegisterDmsEvent() +{ + ZLOGI("Start register dms event"); + if (dmsEventListener_ == nullptr) { + dmsEventListener_ = sptr(new DmsEventListener); + } + if (dmsEventListener_ == nullptr) { + ZLOGE("Register dms event listener failed, listener is nullptr"); + return; + } + auto status = DistributedSchedule::DmsHandler::GetInstance().RegisterDSchedEventListener( + DistributedSchedule::DSchedEventType::DMS_ALL, dmsEventListener_); + if (status != 0) { + ZLOGE("Register dms event listener failed, status: %{public}d", status); + } +} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.h b/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.h new file mode 100644 index 00000000..c1804e17 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/object/object_dms_handler.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H +#define DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H + +#include + +#include "dms_listener_stub.h" +#include "distributed_sched_types.h" + +namespace OHOS::DistributedObject { +class DmsEventListener : public DistributedSchedule::DSchedEventListenerStub { +public: + DmsEventListener() = default; + ~DmsEventListener() = default; + void DSchedEventNotify(DistributedSchedule::EventNotify ¬ify); +}; + +class ObjectDmsHandler { +public: + static ObjectDmsHandler &GetInstance() + { + static ObjectDmsHandler instance; + return instance; + } + + void ReceiveDmsEvent(DistributedSchedule::EventNotify &event); + bool IsContinue(const std::string &networkId, const std::string &bundleName); + void RegisterDmsEvent(); + +private: + ObjectDmsHandler() = default; + ~ObjectDmsHandler() = default; + ObjectDmsHandler(const ObjectDmsHandler &) = delete; + ObjectDmsHandler &operator=(const ObjectDmsHandler &) = delete; + ObjectDmsHandler(ObjectDmsHandler &&) = delete; + ObjectDmsHandler &operator=(ObjectDmsHandler &&) = delete; + + static constexpr int64_t VALIDITY = 15; + static constexpr uint32_t MAX_EVENTS = 20; + std::deque> dmsEvents_{}; + std::mutex mutex_{}; + sptr dmsEventListener_; +}; +} // namespace OHOS::DistributedObject +#endif // DISTRIBUTEDDATAMGR_OBJECT_DMS_HANDLER_H diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp index 2089491a..9be54bc8 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp @@ -57,17 +57,11 @@ ObjectStoreManager::ObjectStoreManager() ObjectStoreManager::~ObjectStoreManager() { ZLOGI("ObjectStoreManager destroy"); - if (objectAssetsSendListener_ != nullptr) { - delete objectAssetsSendListener_; - objectAssetsSendListener_ = nullptr; - } if (objectAssetsRecvListener_ != nullptr) { auto status = DistributedFileDaemonManager::GetInstance().UnRegisterAssetCallback(objectAssetsRecvListener_); if (status != DistributedDB::DBStatus::OK) { ZLOGE("UnRegister assetsRecvListener err %{public}d", status); } - delete objectAssetsRecvListener_; - objectAssetsRecvListener_ = nullptr; } } diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index 206dd106..a47b7486 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -19,6 +19,7 @@ #include +#include "accesstoken_kit.h" #include "account/account_delegate.h" #include "bootstrap.h" #include "checker/checker_manager.h" @@ -31,6 +32,7 @@ #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "object_asset_loader.h" +#include "object_dms_handler.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" #include "utils/anonymous.h" @@ -42,6 +44,7 @@ using StoreMetaData = OHOS::DistributedData::StoreMetaData; using FeatureSystem = OHOS::DistributedData::FeatureSystem; using DumpManager = OHOS::DistributedData::DumpManager; __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_; +constexpr const char *PKG_NAME = "ohos.distributeddata.service"; ObjectServiceImpl::Factory::Factory() { FeatureSystem::GetInstance().RegisterCreator( @@ -110,6 +113,22 @@ int32_t ObjectServiceImpl::BindAssetStore(const std::string &bundleName, const s return status; } +int32_t ObjectServiceImpl::IsContinue(bool &result) +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + Security::AccessToken::HapTokenInfo tokenInfo; + auto status = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (status != 0) { + ZLOGE("Get hap token info failed, tokenId: %{public}u, status: %{public}d", tokenId, status); + return status; + } + DistributedHardware::DmDeviceInfo info; + DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info); + std::string networkId = info.networkId; + result = ObjectDmsHandler::GetInstance().IsContinue(networkId, tokenInfo.bundleName); + return OBJECT_SUCCESS; +} + int32_t ObjectServiceImpl::OnInitialize() { ZLOGI("Initialize"); @@ -157,6 +176,7 @@ int32_t ObjectServiceImpl::OnInitialize() saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str()); RegisterObjectServiceInfo(); RegisterHandler(); + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); return OBJECT_SUCCESS; } diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h index 60cf85ae..437d49e9 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h @@ -51,6 +51,7 @@ public: const std::string &deviceId, const ObjectStore::Asset &assetValue) override; int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) override; + int32_t IsContinue(bool &result) override; private: using StaticActs = DistributedData::StaticActs; class ObjectStatic : public StaticActs { diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp index 3e332204..20255eab 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp @@ -181,6 +181,17 @@ int32_t ObjectServiceStub::OnDeleteSnapshot(MessageParcel &data, MessageParcel & return 0; } +int32_t ObjectServiceStub::OnIsContinue(MessageParcel &data, MessageParcel &reply) +{ + bool isContinue = false; + int32_t status = IsContinue(isContinue); + if (!ITypesUtil::Marshal(reply, isContinue)) { + ZLOGE("Marshal isContinue failed, isContinue: %{public}d, status: %{public}d", isContinue, status); + return -1; + } + return 0; +} + bool ObjectServiceStub::CheckInterfaceToken(MessageParcel& data) { auto localDescriptor = IObjectService::GetDescriptor(); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h index 8e71f952..fef5c7ec 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h @@ -36,6 +36,7 @@ private: int32_t OnAssetChangedOnRemote(MessageParcel &data, MessageParcel &reply); int32_t ObjectStoreBindAssetOnRemote(MessageParcel &data, MessageParcel &reply); int32_t OnDeleteSnapshot(MessageParcel &data, MessageParcel &reply); + int32_t OnIsContinue(MessageParcel &data, MessageParcel &reply); using RequestHandle = int (ObjectServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(ObjectCode::OBJECTSTORE_SERVICE_CMD_MAX)] = { &ObjectServiceStub::ObjectStoreSaveOnRemote, @@ -46,6 +47,7 @@ private: &ObjectServiceStub::OnAssetChangedOnRemote, &ObjectServiceStub::ObjectStoreBindAssetOnRemote, &ObjectServiceStub::OnDeleteSnapshot, + &ObjectServiceStub::OnIsContinue, }; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index b5be9c58..c4866bfe 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -231,6 +231,9 @@ int32_t RdbGeneralStore::Close(bool isForce) if (!isForce && delegate_->GetCloudSyncTaskCount() > 0) { return GeneralError::E_BUSY; } + if (isForce && bindInfo_.loader_ != nullptr) { + bindInfo_.loader_->Cancel(); + } auto status = manager_.CloseStore(delegate_); if (status != DBStatus::OK) { return status; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index e8730147..487b28b0 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -14,19 +14,22 @@ */ #define LOG_TAG "RdbServiceImpl" #include "rdb_service_impl.h" + +#include "abs_rdb_predicates.h" #include "accesstoken_kit.h" #include "account/account_delegate.h" -#include "checker/checker_manager.h" -#include "abs_rdb_predicates.h" #include "changeevent/remote_change_event.h" +#include "checker/checker_manager.h" #include "cloud/change_event.h" -#include "cloud/cloud_share_event.h" #include "cloud/cloud_lock_event.h" +#include "cloud/cloud_share_event.h" #include "cloud/make_query_event.h" +#include "cloud/schema_meta.h" #include "commonevent/data_change_event.h" #include "commonevent/set_searchable_event.h" #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" +#include "device_matrix.h" #include "directory/directory_manager.h" #include "dump/dump_manager.h" #include "eventcenter/event_center.h" @@ -34,23 +37,22 @@ #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/auto_launch_meta_data.h" +#include "metadata/capability_meta_data.h" #include "metadata/meta_data_manager.h" +#include "metadata/store_debug_info.h" #include "metadata/store_meta_data.h" -#include "rdb_watcher.h" +#include "rdb_general_store.h" #include "rdb_notifier_proxy.h" #include "rdb_query.h" +#include "rdb_result_set_impl.h" +#include "rdb_watcher.h" #include "store/general_store.h" #include "tokenid_kit.h" #include "types_export.h" #include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" -#include "cloud/schema_meta.h" -#include "rdb_general_store.h" -#include "rdb_result_set_impl.h" #include "xcollie.h" -#include "device_matrix.h" -#include "metadata/capability_meta_data.h" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; @@ -676,9 +678,12 @@ int32_t RdbServiceImpl::Delete(const RdbSyncerParam ¶m) auto storeMeta = GetStoreMetaData(tmpParam); MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey()); MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true); MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true); MetaDataManager::GetInstance().DelMeta(storeMeta.GetStrategyKey()); - MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetBackupSecretKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetAutoLaunchKey(), true); + MetaDataManager::GetInstance().DelMeta(storeMeta.GetDebugInfoKey(), true); return RDB_OK; } @@ -781,6 +786,9 @@ int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) EventCenter::GetInstance().PostEvent(std::move(evt)); } } + + SaveDebugInfo(meta, param); + AppIDMetaData appIdMeta; appIdMeta.bundleName = meta.bundleName; appIdMeta.appId = meta.appId; @@ -1225,4 +1233,57 @@ int32_t RdbServiceImpl::UnlockCloudContainer(const RdbSyncerParam ¶m) EventCenter::GetInstance().PostEvent(std::move(evt)); return result; } + +int32_t RdbServiceImpl::GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) +{ + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + auto metaData = GetStoreMetaData(param); + auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true); + if (!isCreated) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta data", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_OK; + } + DistributedData::StoreDebugInfo debugMeta; + isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetDebugInfoKey(), debugMeta, true); + if (!isCreated) { + return RDB_OK; + } + + for (auto &[name, fileDebug] : debugMeta.fileInfos) { + RdbDebugInfo rdbInfo; + rdbInfo.inode_ = fileDebug.inode; + rdbInfo.size_ = fileDebug.size; + rdbInfo.dev_ = fileDebug.dev; + rdbInfo.mode_ = fileDebug.mode; + rdbInfo.uid_ = fileDebug.uid; + rdbInfo.gid_ = fileDebug.gid; + debugInfo.insert(std::pair{ name, rdbInfo }); + } + return RDB_OK; +} + +int32_t RdbServiceImpl::SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam ¶m) +{ + if (param.infos_.empty()) { + return RDB_OK; + } + DistributedData::StoreDebugInfo debugMeta; + for (auto &[name, info] : param.infos_) { + DistributedData::StoreDebugInfo::FileInfo fileInfo; + fileInfo.inode = info.inode_; + fileInfo.size = info.size_; + fileInfo.dev = info.dev_; + fileInfo.mode = info.mode_; + fileInfo.uid = info.uid_; + fileInfo.gid = info.gid_; + debugMeta.fileInfos.insert(std::pair{name, fileInfo}); + } + MetaDataManager::GetInstance().SaveMeta(metaData.GetDebugInfoKey(), debugMeta, true); + return RDB_OK; +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h index c110a4d7..5b82ac7c 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -101,6 +101,8 @@ public: int32_t UnlockCloudContainer(const RdbSyncerParam ¶m) override; + int32_t GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) override; + private: using Watchers = DistributedData::AutoCache::Watchers; using StaticActs = DistributedData::StaticActs; @@ -196,6 +198,8 @@ private: StoreInfo GetStoreInfo(const RdbSyncerParam ¶m); + int32_t SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam ¶m); + static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index a6736520..dea28b89 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -186,7 +186,7 @@ int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel { RdbSyncerParam param; SubscribeOption option; - if (!ITypesUtil::Unmarshal(data, param)) { + if (!ITypesUtil::Unmarshal(data, param, option)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; @@ -419,4 +419,20 @@ int32_t RdbServiceStub::OnUnlockCloudContainer(MessageParcel &data, MessageParce } return RDB_OK; } + +int32_t RdbServiceStub::OnGetDebugInfo(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + std::map debugInfo; + auto status = GetDebugInfo(param, debugInfo); + if (!ITypesUtil::Marshal(reply, status, debugInfo)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h index a8ac6b9b..eb506e85 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -74,6 +74,8 @@ private: int32_t OnUnlockCloudContainer(MessageParcel& data, MessageParcel& reply); + int32_t OnGetDebugInfo(MessageParcel& data, MessageParcel& reply); + using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(RdbServiceCode::RDB_SERVICE_CMD_MAX)] = { [static_cast(RdbServiceCode::RDB_SERVICE_CMD_OBTAIN_TABLE)] = @@ -105,7 +107,8 @@ private: [static_cast(RdbServiceCode::RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER)] = &RdbServiceStub::OnLockCloudContainer, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER)] = - &RdbServiceStub::OnUnlockCloudContainer + &RdbServiceStub::OnUnlockCloudContainer, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_DEBUG_INFO)] = &RdbServiceStub::OnGetDebugInfo }; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index 6e351661..0181a183 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -626,6 +626,36 @@ ohos_unittest("ObjectAssetMachineTest") { ] } +ohos_unittest("ObjectDmsHandlerTest") { + module_out_path = module_output_path + sources = [ + "../object/object_dms_handler.cpp", + "object_dms_handler_test.cpp", + ] + + include_dirs = [] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dmsfwk:distributed_sdk", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + ohos_unittest("ObjectManagerTest") { module_out_path = module_output_path sources = [ @@ -1107,6 +1137,7 @@ group("unittest") { ":MetaDataTest", ":ObjectAssetLoaderTest", ":ObjectAssetMachineTest", + ":ObjectDmsHandlerTest", ":ObjectManagerTest", ":ObjectSnapshotTest", ":RdbResultSetImplTest", diff --git a/datamgr_service/services/distributeddataservice/service/test/directory_manager_test.cpp b/datamgr_service/services/distributeddataservice/service/test/directory_manager_test.cpp index a41e1ac2..fd57b50c 100644 --- a/datamgr_service/services/distributeddataservice/service/test/directory_manager_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/directory_manager_test.cpp @@ -19,6 +19,7 @@ #include "directory/directory_manager.h" #include "nativetoken_kit.h" #include "types.h" +#include using namespace testing::ext; using namespace OHOS::DistributedData; @@ -229,4 +230,33 @@ HWTEST_F(DirectoryManagerTest, GetSecretKeyPath, TestSize.Level0) EXPECT_NE(sizeof(version), 0); auto path = DirectoryManager::GetInstance().GetSecretKeyPath(metaData); EXPECT_EQ(path, "/data/service/el1/public/database/bundle_manager_service/kvdb/secret"); +} + +/** +* @tc.name: DeleteDirectory +* @tc.desc: test delete dir +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(DirectoryManagerTest, DeleteDirectory, TestSize.Level0) +{ + std::string path = "/data/service/el1/public/database/bundle_manager_service/kvdb/100/data"; + bool ret = DirectoryManager::GetInstance().CreateDirectory(path); + EXPECT_TRUE(ret); + std::ofstream file( + "/data/service/el1/public/database/bundle_manager_service/kvdb/100/data/test.txt", std::ios::out); + if (file.is_open()) { + file << "test content" << std::endl; + file.close(); + } + std::ofstream file1("/data/service/el1/public/database/bundle_manager_service/kvdb/100/test.txt", std::ios::out); + if (file1.is_open()) { + file1 << "test content" << std::endl; + file1.close(); + } + std::string deleteDir = "/data/service/el1/public/database/bundle_manager_service/kvdb/100"; + bool ret1 = DirectoryManager::GetInstance().DeleteDirectory(deleteDir.c_str()); + EXPECT_TRUE(ret1); + EXPECT_EQ(access(deleteDir.c_str(), F_OK), -1); } \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn index d268b6b6..afb06200 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -76,6 +76,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/object/object_asset_machine.cpp", "${data_service_path}/service/object/object_callback_proxy.cpp", "${data_service_path}/service/object/object_data_listener.cpp", + "${data_service_path}/service/object/object_dms_handler.cpp", "${data_service_path}/service/object/object_manager.cpp", "${data_service_path}/service/object/object_service_impl.cpp", "${data_service_path}/service/object/object_service_stub.cpp", @@ -105,6 +106,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", "hilog:libhilog", "hisysevent:libhisysevent", "huks:libhukssdk", diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp index 557d62d5..1cc13344 100644 --- a/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp @@ -486,7 +486,7 @@ HWTEST_F(KVDBGeneralStoreTest, Sync, TestSize.Level0) mixMode = GeneralStore::MixMode(syncMode, highMode); syncParam.mode = mixMode; ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); - EXPECT_EQ(ret, GeneralError::E_ERROR); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); } /** @@ -606,7 +606,7 @@ HWTEST_F(KVDBGeneralStoreTest, ConvertStatus, TestSize.Level0) ret = store->ConvertStatus(DBStatus::CLOUD_SYNC_TASK_MERGED); EXPECT_EQ(ret, GeneralError::E_SYNC_TASK_MERGED); ret = store->ConvertStatus(DBStatus::DB_ERROR); - EXPECT_EQ(ret, GeneralError::E_ERROR); + EXPECT_EQ(ret, GeneralError::E_DB_ERROR); } /** diff --git a/datamgr_service/services/distributeddataservice/service/test/object_dms_handler_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_dms_handler_test.cpp new file mode 100644 index 00000000..37fc4e3a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/object_dms_handler_test.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObjectDmsHandlerTest" + +#include "object_dms_handler.h" + +#include + +#include "dms_listener_stub.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +namespace OHOS::Test { +class ObjectDmsHandlerTest : public testing::Test { +public: + void SetUp() {} + void TearDown() {} +}; + +/** +* @tc.name: IsContinueTest_001 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, IsContinue_001, TestSize.Level0) +{ + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); + DmsEventListener listener; + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = "srcNetworkId"; + notify.dstNetworkId_ = "dstNetworkId"; + notify.srcBundleName_ = "srcBundleName"; + notify.destBundleName_ = "destBundleName"; + listener.DSchedEventNotify(notify); + auto res = ObjectDmsHandler::GetInstance().IsContinue("srcNetworkId", "srcBundleName"); + EXPECT_TRUE(res); + res = ObjectDmsHandler::GetInstance().IsContinue("dstNetworkId", "destBundleName"); + EXPECT_TRUE(res); + res = ObjectDmsHandler::GetInstance().IsContinue("srcNetworkId", "destBundleName"); + EXPECT_FALSE(res); + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} + +/** +* @tc.name: ReceiveDmsEvent_001 +* @tc.desc: IsContinue test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectDmsHandlerTest, ReceiveDmsEvent_001, TestSize.Level0) +{ + ObjectDmsHandler::GetInstance().RegisterDmsEvent(); + DmsEventListener listener; + for (int i = 0; i <= 20; i++) { + DistributedSchedule::EventNotify notify; + notify.dSchedEventType_ = DistributedSchedule::DSchedEventType::DMS_CONTINUE; + notify.srcNetworkId_ = "srcNetworkId" + std::to_string(i); + notify.dstNetworkId_ = "dstNetworkId" + std::to_string(i); + notify.srcBundleName_ = "srcBundleName" + std::to_string(i); + notify.destBundleName_ = "destBundleName" + std::to_string(i); + ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify); + } + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.size(), 20); + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.front().first.srcNetworkId_, "srcNetworkId1"); + EXPECT_EQ(ObjectDmsHandler::GetInstance().dmsEvents_.back().first.srcNetworkId_, "srcNetworkId20"); + ObjectDmsHandler::GetInstance().dmsEvents_.clear(); +} +} // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/device_manger_adapter_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/device_manger_adapter_mock.cpp index 4764ba0d..ec2f814e 100644 --- a/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/device_manger_adapter_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/unittest/cloud/device_manger_adapter_mock.cpp @@ -33,14 +33,32 @@ void DeviceManagerAdapter::Init(std::shared_ptr executors) {} //DeviceInfo DeviceManagerAdapter::GetLocalDevice() {} //std::vector DeviceManagerAdapter::GetRemoteDevices() {} //DeviceInfo DeviceManagerAdapter::GetDeviceInfo(const std::string &id) {} -std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkId) {} -std::string DeviceManagerAdapter::GetUdidByNetworkId(const std::string &networkId) {} -std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const std::string &uuid) {} -std::string DeviceManagerAdapter::ToUUID(const std::string &id) {} -std::string DeviceManagerAdapter::ToUDID(const std::string &id) {} +std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkId) +{ + return networkId; +} +std::string DeviceManagerAdapter::GetUdidByNetworkId(const std::string &networkId) +{ + return networkId; +} +std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const std::string &uuid) +{ + return appId + uuid; +} +std::string DeviceManagerAdapter::ToUUID(const std::string &id) +{ + return id; +} +std::string DeviceManagerAdapter::ToUDID(const std::string &id) +{ + return id; +} //static std::vector DeviceManagerAdapter::ToUUID(const std::vector &devices) {} //static std::vector DeviceManagerAdapter::ToUUID(std::vector devices) {} -std::string DeviceManagerAdapter::ToNetworkID(const std::string &id) {} +std::string DeviceManagerAdapter::ToNetworkID(const std::string &id) +{ + return id; +} void DeviceManagerAdapter::NotifyReadyEvent(const std::string &uuid) {} bool DeviceManagerAdapter::IsNetworkAvailable() diff --git a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp index 327e2e49..bdedc604 100644 --- a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp @@ -256,12 +256,7 @@ HWTEST_F(ValueProxyServiceTest, AssetConvertToDataStatus, TestSize.Level0) { DistributedDB::Asset asset; asset.status = static_cast(DistributedDB::AssetStatus::DOWNLOADING); - asset.flag = static_cast(DistributedDB::AssetOpType::DELETE); auto result = ValueProxy::Asset::ConvertToDataStatus(asset); - EXPECT_EQ(result, DistributedData::Asset::STATUS_DELETE); - - asset.flag = static_cast(DistributedDB::AssetOpType::NO_CHANGE); - result = ValueProxy::Asset::ConvertToDataStatus(asset); EXPECT_EQ(result, DistributedData::Asset::STATUS_DOWNLOADING); asset.status = static_cast(DistributedDB::AssetStatus::ABNORMAL); @@ -269,19 +264,23 @@ HWTEST_F(ValueProxyServiceTest, AssetConvertToDataStatus, TestSize.Level0) EXPECT_EQ(result, DistributedData::Asset::STATUS_ABNORMAL); asset.status = static_cast(DistributedDB::AssetStatus::NORMAL); - asset.flag = static_cast(DistributedDB::AssetOpType::INSERT); result = ValueProxy::Asset::ConvertToDataStatus(asset); - EXPECT_EQ(result, DistributedData::Asset::STATUS_INSERT); + EXPECT_EQ(result, DistributedData::Asset::STATUS_NORMAL); - asset.flag = static_cast(DistributedDB::AssetOpType::UPDATE); + asset.status = static_cast(DistributedDB::AssetStatus::UPDATE); result = ValueProxy::Asset::ConvertToDataStatus(asset); EXPECT_EQ(result, DistributedData::Asset::STATUS_UPDATE); - asset.flag = static_cast(DistributedDB::AssetOpType::DELETE); + asset.status = static_cast(DistributedDB::AssetStatus::DELETE); result = ValueProxy::Asset::ConvertToDataStatus(asset); EXPECT_EQ(result, DistributedData::Asset::STATUS_DELETE); - asset.flag = static_cast(DistributedDB::AssetOpType::NO_CHANGE); + asset.status = static_cast(DistributedDB::AssetStatus::INSERT); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_INSERT); + + asset.status = static_cast(DistributedDB::AssetStatus::UPDATE) + + static_cast(DistributedDB::AssetStatus::ABNORMAL); result = ValueProxy::Asset::ConvertToDataStatus(asset); EXPECT_EQ(result, DistributedData::Asset::STATUS_NORMAL); } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp index e75733df..179b49fe 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -23,6 +23,10 @@ #include "log_print.h" #include "ipc_skeleton.h" +#include "file.h" +#include "udmf_conversion.h" +#include "udmf_radar_reporter.h" +#include "unified_meta.h" #include "tlv_util.h" #include "account/account_delegate.h" #include "metadata/store_meta_data.h" @@ -32,7 +36,7 @@ #include "bootstrap.h" #include "directory/directory_manager.h" #include "utils/anonymous.h" -#include "udmf_radar_reporter.h" + namespace OHOS { namespace UDMF { using namespace RadarReporter; @@ -107,7 +111,7 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) // add runtime info std::vector runtimeBytes; auto runtimeTlv = TLVObject(runtimeBytes); - if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv)) { + if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv, TAG::TAG_RUNTIME)) { ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str()); return E_WRITE_PARCEL_ERROR; } @@ -119,7 +123,7 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) for (const auto &record : unifiedData.GetRecords()) { std::vector recordBytes; auto recordTlv = TLVObject(recordBytes); - if (!TLVUtil::Writing(record, recordTlv)) { + if (!TLVUtil::Writing(record, recordTlv, TAG::TAG_UNIFIED_RECORD)) { ZLOGI("Marshall unified record failed."); return E_WRITE_PARCEL_ERROR; } @@ -590,7 +594,7 @@ Status RuntimeStore::UnmarshalEntries(const std::string &key, std::vector if (keyStr == key) { Runtime runtime; auto runtimeTlv = TLVObject(const_cast &>(entry.value)); - if (!TLVUtil::Reading(runtime, runtimeTlv)) { + if (!TLVUtil::ReadTlv(runtime, runtimeTlv, TAG::TAG_RUNTIME)) { ZLOGE("Unmarshall runtime info failed."); return E_READ_PARCEL_ERROR; } @@ -598,13 +602,14 @@ Status RuntimeStore::UnmarshalEntries(const std::string &key, std::vector } else if (keyStr.find(key) == 0) { std::shared_ptr record; auto recordTlv = TLVObject(const_cast &>(entry.value)); - if (!TLVUtil::Reading(record, recordTlv)) { + if (!TLVUtil::ReadTlv(record, recordTlv, TAG::TAG_UNIFIED_RECORD)) { ZLOGE("Unmarshall unified record failed."); return E_READ_PARCEL_ERROR; } unifiedData.AddRecord(record); } } + UdmfConversion::ConvertRecordToSubclass(unifiedData); return E_OK; } } // namespace UDMF diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 2a6356b7..b47e61b2 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "UdmfServiceImpl" #include "udmf_service_impl.h" @@ -32,6 +33,7 @@ #include "uri_permission_manager.h" #include "uri.h" #include "utd/custom_utd_installer.h" +#include "udmf_conversion.h" #include "udmf_radar_reporter.h" #include "securec.h" #include "unified_types.h" @@ -144,6 +146,7 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData return E_DB_ERROR; } + UdmfConversion::InitValueObject(unifiedData); if (store->Put(unifiedData) != E_OK) { ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; @@ -346,13 +349,9 @@ int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vectorSetUid(PreProcessUtils::GenerateId()); } + UdmfConversion::InitValueObject(unifiedData); if (store->Update(unifiedData) != E_OK) { ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); return E_DB_ERROR; @@ -502,6 +502,7 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi return E_DB_ERROR; } data.GetRuntime()->privileges.emplace_back(privilege); + UdmfConversion::InitValueObject(data); if (store->Update(data) != E_OK) { ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); return E_DB_ERROR; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index 2523b196..e8224c93 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "UdmfServiceStub" #include "udmf_service_stub.h" @@ -22,6 +23,7 @@ #include "accesstoken_kit.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "udmf_conversion.h" #include "udmf_types_util.h" #include "unified_data.h" #include "unified_meta.h" @@ -61,6 +63,7 @@ int32_t UdmfServiceStub::OnSetData(MessageParcel &data, MessageParcel &reply) customOption.tokenId = token; std::string key; int32_t status = SetData(customOption, unifiedData, key); + UdmfConversion::InitValueObject(unifiedData); if (!ITypesUtil::Marshal(reply, status, key)) { ZLOGE("Marshal status or key failed, status: %{public}d, key: %{public}s", status, key.c_str()); return E_WRITE_PARCEL_ERROR; @@ -80,6 +83,7 @@ int32_t UdmfServiceStub::OnGetData(MessageParcel &data, MessageParcel &reply) query.tokenId = token; UnifiedData unifiedData; int32_t status = GetData(query, unifiedData); + UdmfConversion::InitValueObject(unifiedData); if (!ITypesUtil::Marshal(reply, status, unifiedData)) { ZLOGE("Marshal status or unifiedData failed, status: %{public}d", status); return E_WRITE_PARCEL_ERROR; @@ -99,6 +103,7 @@ int32_t UdmfServiceStub::OnGetBatchData(MessageParcel &data, MessageParcel &repl query.tokenId = token; std::vector unifiedDataSet; int32_t status = GetBatchData(query, unifiedDataSet); + UdmfConversion::InitValueObject(unifiedDataSet); if (!ITypesUtil::Marshal(reply, status, unifiedDataSet)) { ZLOGE("Marshal status or unifiedDataSet failed, status: %{public}d", status); return E_WRITE_PARCEL_ERROR; @@ -137,6 +142,7 @@ int32_t UdmfServiceStub::OnDeleteData(MessageParcel &data, MessageParcel &reply) query.tokenId = token; std::vector unifiedDataSet; int32_t status = DeleteData(query, unifiedDataSet); + UdmfConversion::InitValueObject(unifiedDataSet); if (!ITypesUtil::Marshal(reply, status, unifiedDataSet)) { ZLOGE("Marshal status or unifiedDataSet failed, status: %{public}d", status); return E_WRITE_PARCEL_ERROR; diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h index bda0a1b8..90b22634 100644 --- a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h @@ -1,17 +1,17 @@ /* - * 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. - */ +* Copyright (c) 2023-2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef OHOS_DMS_HANDLER_H #define OHOS_DMS_HANDLER_H @@ -22,19 +22,23 @@ #include #include +#include "refbase.h" + #include "distributed_event_listener.h" -#include "dms_sa_client.h" #include "distributed_sched_types.h" +#include "dms_sa_client.h" +#include "single_instance.h" namespace OHOS { namespace DistributedSchedule { class DmsHandler { + DECLARE_SINGLE_INSTANCE(DmsHandler); + public: - static DmsHandler &GetInstance(); - int32_t RegisterDSchedEventListener(std::string type, sptr &listener); - int32_t UnRegisterDSchedEventListener(std::string type, sptr &listener); - int32_t GetContinueInfo(ContinueInfo &continueInfo); - int32_t GetDSchedEventInfo(const DSchedEventType &type, std::vector &events); + int32_t RegisterDSchedEventListener(const DSchedEventType& type, sptr &listener); + int32_t UnRegisterDSchedEventListener(const DSchedEventType& type, sptr &listener); + int32_t GetContinueInfo(ContinueInfo &continueInfo); + int32_t GetDSchedEventInfo(const DSchedEventType &type, std::vector &events); }; } // namespace DistributedSchedule } // namespace OHOS diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_listener_stub.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_listener_stub.h index 9adb025f..25270184 100644 --- a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_listener_stub.h +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_listener_stub.h @@ -20,7 +20,7 @@ #include #include "distributed_event_listener.h" -#include "dtbschedmgr_log.h" +//#include "dtbschedmgr_log.h" #include "iremote_stub.h" #include "message_parcel.h" #include "refbase.h" diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_client.cpp b/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_client.cpp deleted file mode 100644 index 467b208c..00000000 --- a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_client.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 "dms_client.h" - -#include "ability_manager_errors.h" -#include "distributed_parcel_helper.h" -#include "if_system_ability_manager.h" -#include "ipc_skeleton.h" -#include "iservice_registry.h" -#include "string_ex.h" -#include "system_ability_definition.h" - -namespace OHOS { -namespace DistributedSchedule { -namespace { -const std::u16string DMS_PROXY_INTERFACE_TOKEN = u"ohos.distributedschedule.accessToken"; -} -sptr DistributedClient::GetDmsProxy() -{ - auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (samgrProxy == nullptr) { - HILOG_ERROR("fail to get samgr."); - return nullptr; - } - return samgrProxy->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID); -} - -int32_t DistributedClient::RegisterDSchedEventListener(const std::string& type, - const sptr& obj) -{ - HILOG_INFO("RegisterDSchedEventListener called"); - sptr remote = GetDmsProxy(); - if (remote == nullptr) { - HILOG_ERROR("remote system ablity is nullptr"); - return AAFwk::INVALID_PARAMETERS_ERR; - } - MessageParcel data; - MessageParcel reply; - if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { - return ERR_FLATTEN_OBJECT; - } - PARCEL_WRITE_HELPER(data, String, type); - PARCEL_WRITE_HELPER(data, RemoteObject, obj->AsObject()); - PARCEL_TRANSACT_SYNC_RET_INT(remote, REGISTER_DSCHED_EVENT_LISTENER, data, reply); -} - -int32_t DistributedClient::UnRegisterDSchedEventListener(const std::string& type, - const sptr& obj) -{ - HILOG_INFO("UnRegisterDSchedEventListener called"); - sptr remote = GetDmsProxy(); - if (remote == nullptr) { - HILOG_ERROR("remote system ablity is null"); - return AAFwk::INVALID_PARAMETERS_ERR; - } - MessageParcel data; - MessageParcel reply; - if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { - HILOG_DEBUG("write interface token failed."); - return ERR_FLATTEN_OBJECT; - } - PARCEL_WRITE_HELPER(data, String, type); - PARCEL_WRITE_HELPER(data, RemoteObject, obj->AsObject()); - PARCEL_TRANSACT_SYNC_RET_INT(remote, UNREGISTER_DSCHED_EVENT_LISTENER, data, reply); -} - -int32_t DistributedClient::GetContinueInfo(ContinueInfo &continueInfo) -{ - HILOG_INFO("%{public}s called", __func__); - sptr remote = GetDmsProxy(); - if (remote == nullptr) { - HILOG_ERROR("remote system ablity is null"); - return AAFwk::INVALID_PARAMETERS_ERR; - } - MessageParcel data; - MessageParcel reply; - if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { - HILOG_DEBUG("write interface token failed."); - return ERR_FLATTEN_OBJECT; - } - - MessageOption option; - int32_t ret = remote->SendRequest(GET_CONTINUE_INFO, data, reply, option); - if (ret != ERR_NONE) { - HILOG_ERROR("sendRequest fail, error: %{public}d", ret); - return ret; - } - continueInfo.dstNetworkId_ = reply.ReadString(); - continueInfo.srcNetworkId_ = reply.ReadString(); - if (continueInfo.dstNetworkId_ == "") { - HILOG_ERROR("read type failed!"); - return ERR_FLATTEN_OBJECT; - } - return ret; -} -} // namespace DistributedSchedule -} // namespace OHOS \ No newline at end of file diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_listener_stub.cpp b/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_listener_stub.cpp deleted file mode 100644 index e641f392..00000000 --- a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_listener_stub.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "dms_listener_stub.h" - -#include -#include -#include - -#include "ipc_object_stub.h" -#include "ipc_types.h" -#include "message_option.h" -#include "message_parcel.h" -#include "securec.h" - -namespace OHOS { -namespace DistributedSchedule { -namespace { -const std::string TAG = "DmsListenerStub"; -} - -DSchedEventListenerStub::DSchedEventListenerStub() -{ - memberFuncMap_[static_cast(DSchedEventListenerStub::Message::DSCHED_EVENT_CALLBACK)] = - &DSchedEventListenerStub::DSchedEventNotifyInner; -} - -DSchedEventListenerStub::~DSchedEventListenerStub() -{} - -int32_t DSchedEventListenerStub::OnRemoteRequest(uint32_t code, - MessageParcel &data, MessageParcel &reply, MessageOption &option) -{ - HILOGI("DSchedEventListenerStub OnRemoteRequest code: %u", code); - std::u16string desc = DSchedEventListenerStub::GetDescriptor(); - std::u16string remoteDesc = data.ReadInterfaceToken(); - if (desc != remoteDesc) { - HILOGE("remoteDesc is invalid!"); - return GET_REMOTE_DMS_FAIL; - } - auto itFunc = memberFuncMap_.find(code); - if (itFunc == memberFuncMap_.end()) { - HILOGE("memberFuncMap_ not found"); - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } - - auto memberFunc = itFunc->second; - (this->*memberFunc)(data, reply); - return 0; -} - -void DSchedEventListenerStub::DSchedEventNotifyInner(MessageParcel &data, MessageParcel &reply) -{ - HILOGI("DSchedEventListenerStub DSchedEventNotifyInner"); - int32_t ret = 0; - do { - int32_t eventResult = data.ReadInt32(); - std::string srcNetworkId = data.ReadString(); - std::string dstNetworkId = data.ReadString(); - std::string bundleName = data.ReadString(); - std::string moduleName = data.ReadString(); - std::string abilityName = data.ReadString(); - EventNotify eventNotify; - eventNotify.eventResult_ = eventResult; - eventNotify.srcNetworkId_ = srcNetworkId; - eventNotify.dstNetworkId_ = dstNetworkId; - eventNotify.bundleName_ = bundleName; - eventNotify.moduleName_ = moduleName; - eventNotify.abilityName_ = abilityName; - DSchedEventNotify(eventNotify); - } while (0); - if (!reply.WriteInt32(ret)) { - HILOGE("DSchedEventNotifyInner write ret failed, ret = %d", ret); - } -} -} // namespace DistributedSchedule -} // namespace OHOS \ No newline at end of file diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_sa_client.cpp b/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_sa_client.cpp deleted file mode 100644 index 05d6300c..00000000 --- a/mock/innerkits/dmsfwk_standard/distributed_event/src/dms_sa_client.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "dms_sa_client.h" - -namespace OHOS { -namespace DistributedSchedule { -DmsSaClient &DmsSaClient::GetInstance() -{ - HILOGD("called."); - static DmsSaClient instance; - return instance; -} - -bool DmsSaClient::SubscribeDmsSA() -{ - HILOGD("called."); - sptr callback(new DmsSystemAbilityStatusChange()); - int32_t ret = saMgrProxy_->SubscribeSystemAbility(DISTRIBUTED_SCHED_SA_ID, callback); - if (ret != ERR_OK) { - HILOGE("Failed to subscribe system ability DISTRIBUTED_SCHED_SA_ID ret:%{public}d", ret); - return false; - } - return true; -} - -int32_t DmsSaClient::AddDSchedEventListener(const std::string& type, const sptr& listener) -{ - HILOGI("%{public}s called, the type is %{public}s", __func__, type.c_str()); - saMgrProxy_ = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (saMgrProxy_ == nullptr) { - HILOGE("fail to get saMgrProxy."); - return AAFwk::INNER_ERR; - } - if (saMgrProxy_->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID)) { - DistributedClient distributedClient; - distributedClient.RegisterDSchedEventListener(type, listener); - } - std::lock_guard lock(eventMutex_); - if (!hasSubscribeDmsSA_) { - if (SubscribeDmsSA()) { - hasSubscribeDmsSA_ = true; - listeners_[type] = listener; - } else { - return AAFwk::INNER_ERR; - } - } - return NO_ERROR; -} - -int32_t DmsSaClient::DelDSchedEventListener(const std::string& type, const sptr& listener) -{ - HILOGI("%{public}s called, the type is %{public}s", __func__, type.c_str()); - if (saMgrProxy_->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID)) { - DistributedClient distributedClient; - distributedClient.UnRegisterDSchedEventListener(type, listener); - } - std::lock_guard lock(eventMutex_); - listeners_.erase(type); - return NO_ERROR; -} - -int32_t DmsSaClient::GetContinueInfo(ContinueInfo &continueInfo) -{ - HILOGI("%{public}s called", __func__); - saMgrProxy_ = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (saMgrProxy_ == nullptr) { - HILOGE("fail to get saMgrProxy."); - return AAFwk::INNER_ERR; - } - if (saMgrProxy_->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID)) { - DistributedClient distributedClient; - distributedClient.GetContinueInfo(continueInfo); - } - return NO_ERROR; -} - -void DmsSaClient::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) -{ - HILOGI("%{public}s called, the systemAbilityId is %{public}d", __func__, systemAbilityId); - std::lock_guard lock(eventMutex_); - if (systemAbilityId == DISTRIBUTED_SCHED_SA_ID) { - HILOGI("%{public}s listeners size: %{public}zu .", __func__, listeners_.size()); - for (auto& listener : listeners_) { - DistributedClient distributedClient; - distributedClient.RegisterDSchedEventListener(listener.first, listener.second); - } - } else { - HILOGE("SystemAbilityId must be DISTRIBUTED_SCHED_SA_ID,but it is %{public}d", systemAbilityId); - } -} - -void DmsSaClient::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) -{ -} - -DmsSystemAbilityStatusChange::DmsSystemAbilityStatusChange() -{ - HILOGI("DmsSystemAbilityStatusChange create"); -} - -DmsSystemAbilityStatusChange::~DmsSystemAbilityStatusChange() -{ - HILOGI("DmsSystemAbilityStatusChange delete"); -} - -void DmsSystemAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) -{ - HILOGI("OnAddSystemAbility called, the systemAbilityId is %d", systemAbilityId); - if (systemAbilityId != DISTRIBUTED_SCHED_SA_ID) { - HILOGE("SystemAbilityId must be DISTRIBUTED_SCHED_SA_ID,but it is %d", systemAbilityId); - return; - } - - DmsSaClient::GetInstance().OnAddSystemAbility(systemAbilityId, deviceId); - HILOGI("OnAddSystemAbility called end, the systemAbilityId is %d", systemAbilityId); -} - -void DmsSystemAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) -{ - HILOGI("OnRemoveSystemAbility called, the systemAbilityId is %d", systemAbilityId); - if (systemAbilityId != DISTRIBUTED_SCHED_SA_ID) { - HILOGE("SystemAbilityId must be DISTRIBUTED_SCHED_SA_ID,but it is %d", systemAbilityId); - return; - } - - // notify listener -} -} // namespace DistributedSchedule -} // namespace OHOS \ No newline at end of file diff --git a/mock/innerkits/multimedia_image_standard/image_native/include/pixel_map.h b/mock/innerkits/multimedia_image_standard/image_native/include/pixel_map.h index 2e103053..d0919529 100644 --- a/mock/innerkits/multimedia_image_standard/image_native/include/pixel_map.h +++ b/mock/innerkits/multimedia_image_standard/image_native/include/pixel_map.h @@ -30,11 +30,14 @@ using CustomFreePixelMap = void (*)(void *addr, void *context, uint32_t size); struct InitializationOptions { Size size; + PixelFormat srcPixelFormat = PixelFormat::BGRA_8888; PixelFormat pixelFormat = PixelFormat::UNKNOWN; AlphaType alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN; ScaleMode scaleMode = ScaleMode::FIT_TARGET_SIZE; + int32_t srcRowStride = 0; bool editable = false; bool useSourceIfMatch = false; + bool useDMA = false; }; // Build ARGB_8888 pixel value diff --git a/mock/src/mock_dms.cpp b/mock/src/mock_dms.cpp index 2d4350c8..f69a756f 100644 --- a/mock/src/mock_dms.cpp +++ b/mock/src/mock_dms.cpp @@ -14,34 +14,43 @@ */ #include "dms_handler.h" +#include "dms_listener_stub.h" namespace OHOS { namespace DistributedSchedule { namespace { const std::string TAG = "DmsHandle"; } +int32_t DSchedEventListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ +} +DSchedEventListenerStub::DSchedEventListenerStub() {} +DSchedEventListenerStub::~DSchedEventListenerStub() {} +void DSchedEventListenerStub::DSchedEventNotifyInner(MessageParcel &data, MessageParcel &reply) {} -DmsHandler &DmsHandler::GetInstance(){ +DmsHandler &DmsHandler::GetInstance() +{ static DmsHandler instance; return instance; } -int32_t DmsHandler::RegisterDSchedEventListener(std::string type, sptr& listener) +int32_t DmsHandler::GetContinueInfo(ContinueInfo &continueInfo) { return 0; } -int32_t DmsHandler::UnRegisterDSchedEventListener(std::string type, sptr &listener) +int32_t DmsHandler::GetDSchedEventInfo(const DSchedEventType &type, std::vector &events) { return 0; } -int32_t DmsHandler::GetContinueInfo(ContinueInfo &continueInfo) +int32_t DmsHandler::RegisterDSchedEventListener(const DSchedEventType &type, sptr &listener) { return 0; } -int32_t DmsHandler::GetDSchedEventInfo(const DSchedEventType &type, std::vector &events) +int32_t DmsHandler::UnRegisterDSchedEventListener(const DSchedEventType &type, sptr &listener) { return 0; } diff --git a/mock/src/mock_notification.cpp b/mock/src/mock_notification.cpp index 30d46db0..377ff72e 100644 --- a/mock/src/mock_notification.cpp +++ b/mock/src/mock_notification.cpp @@ -226,6 +226,54 @@ Uri Want::GetLowerCaseScheme(const Uri &uri) { return Uri("");} void Want::ToUriStringInner(std::string &uriString) const{ } nlohmann::json Want::ToJson() const { return nlohmann::json();} bool Want::ReadFromJson(nlohmann::json &wantJson) { return false;} +Want &Want::operator=(const Want &input) +{ + params_ = input.params_; + return *this; +} + +Want &Want::SetFlags(unsigned int flags) +{ + return *this; +} +unsigned int Want::GetFlags() const +{ + return 0; +} +Want &Want::AddFlags(unsigned int flags) +{ + return *this; +} +void Want::RemoveFlags(unsigned int flag) {} +Want &Want::SetElementName(const std::string &bundleName, const std::string &abilityName) +{ + return *this; +} +Want &Want::SetElementName(const std::string &deviceId, const std::string &bundleName, const std::string &abilityName, + const std::string &moduleName) +{ + return *this; +} +Want &Want::SetElement(const AppExecFwk::ElementName &element) +{ + return *this; +} +Want *Want::MakeMainAbility(const AppExecFwk::ElementName &elementName) +{ + return nullptr; +} +Want *Want::WantParseUri(const char *uri) +{ + return nullptr; +} +Want *Want::ParseUri(const std::string &uri) +{ + return nullptr; +} +std::string Want::GetUriString() const +{ + return std::string(); +} UnsupportedData::~UnsupportedData() {} Operation::Operation() : uri_("") {} Operation::~Operation() {} @@ -338,7 +386,8 @@ bool CommonEventPublishInfo::IsSticky() const void CommonEventPublishInfo::SetSubscriberPermissions(const std::vector &subscriberPermissions) {} const std::vector &CommonEventPublishInfo::GetSubscriberPermissions() const { - return {}; + static std::vector TMP; + return TMP; } void CommonEventPublishInfo::SetOrdered(bool ordered) {} bool CommonEventPublishInfo::IsOrdered() const diff --git a/relational_store/frameworks/js/napi/common/src/js_common_type_init.cpp b/relational_store/frameworks/js/napi/common/src/js_common_type_init.cpp index 571da4f7..2e613030 100644 --- a/relational_store/frameworks/js/napi/common/src/js_common_type_init.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_common_type_init.cpp @@ -48,7 +48,7 @@ static napi_value ExportAssetStatus(napi_env env) static napi_value CommonTypeExport(napi_env env, napi_value exports) { napi_status status; - static napi_property_descriptor desc[] = { + const napi_property_descriptor desc[] = { DECLARE_NAPI_PROPERTY("AssetStatus", OHOS::CommonType::ExportAssetStatus(env)), }; 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 02e054b6..53ecd2d4 100644 --- a/relational_store/frameworks/js/napi/common/src/js_utils.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_utils.cpp @@ -242,19 +242,18 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::string &ou if (buffSize >= JSUtils::MAX_VALUE_LENGTH - 1) { buffSize = JSUtils::MAX_VALUE_LENGTH - 1; } - char *buffer = (char *)malloc((buffSize + 1) * sizeof(char)); - if (buffer == nullptr) { + std::unique_ptr buffer = std::make_unique(buffSize + 1); + if (!buffer) { LOG_ERROR("buffer data is nullptr."); return napi_invalid_arg; } - status = napi_get_value_string_utf8(env, jsValue, buffer, buffSize + 1, &buffSize); + status = napi_get_value_string_utf8(env, jsValue, buffer.get(), buffSize + 1, &buffSize); if (status != napi_ok) { LOG_ERROR("napi_get_value_string_utf8 failed, status = %{public}d", status); - free(buffer); return status; } - output = std::string(buffer); - free(buffer); + output = std::string(buffer.get()); + return status; } 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 ccebc319..93d528a0 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 @@ -180,6 +180,9 @@ std::shared_ptr DataAbilityPredicatesProxy::Ge napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } return predicatesProxy->predicates_; } 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 2cea7529..609e8cc9 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 @@ -206,6 +206,9 @@ std::shared_ptr RdbPredicatesProxy::GetNativePredicate napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } return predicatesProxy->predicates_; } @@ -217,6 +220,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldArrayByName(napi_env env, napi napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, argc == 1, std::make_shared("1"), version); @@ -241,6 +247,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldByName( napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, argc == 1, std::make_shared("1"), version); @@ -258,6 +267,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseInt32FieldByName( napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, argc == 1, std::make_shared("1"), version); @@ -275,6 +287,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldAndValueArray(napi_env env, na napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; // Ensure that argc contains 2 parameters RDB_NAPI_ASSERT_FROMV9(env, argc == 2, std::make_shared("2"), version); @@ -299,6 +314,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldAndValue(napi_env env, napi_ca napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; // 2 represents the number of parameters RDB_NAPI_ASSERT_FROMV9(env, argc == 2, std::make_shared("2"), version); @@ -324,6 +342,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldAndStringValue(napi_env env, n napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; // 2 represents the number of parameters RDB_NAPI_ASSERT_FROMV9(env, argc == 2, std::make_shared("2"), version); @@ -345,6 +366,9 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldLowAndHigh( napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); RdbPredicatesProxy *predicatesProxy = nullptr; napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); + if (predicatesProxy == nullptr) { + return nullptr; + } int version = predicatesProxy->apiversion; // 3 represents the number of parameters RDB_NAPI_ASSERT_FROMV9(env, argc == 3, std::make_shared("3"), version); 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 15acf6ff..62c151f2 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 @@ -545,7 +545,7 @@ int ParseValuesBucket(const napi_env env, const napi_value arg, std::shared_ptr< bool isMap = false; napi_status status = napi_is_map(env, arg, &isMap); CHECK_RETURN_SET( - status == napi_ok, std::make_shared("call napi_is_map failed " + std::to_string(status))); + status == napi_ok, std::make_shared("call napi_is_map failed" + std::to_string(status))); if (isMap) { return ParseSendableValuesBucket(env, arg, context); } diff --git a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp index 69067bdb..ab87e51e 100644 --- a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp +++ b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp @@ -250,6 +250,9 @@ uint32_t *SharedBlock::AllocRowOffset() uint32_t rowPos = mHeader->rowNums % ROW_NUM_IN_A_GROUP; RowGroupHeader *group = static_cast(OffsetToPtr(mHeader->groupOffset[groupPos])); mHeader->rowNums += 1; + if (group == nullptr) { + return nullptr; + } return group->rowOffsets + rowPos; } diff --git a/relational_store/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h b/relational_store/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h index 5263be1f..d8550d66 100644 --- a/relational_store/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h +++ b/relational_store/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h @@ -16,14 +16,17 @@ #ifndef DISTRIBUTEDDATAMGR_RDB_FAULT_HIVIEW_REPORTER_H #define DISTRIBUTEDDATAMGR_RDB_FAULT_HIVIEW_REPORTER_H -#include #include +#include #include +#include +#include +#include "connection.h" #include "rdb_store_config.h" - +#include "rdb_types.h" namespace OHOS::NativeRdb { - +using DebugInfo = OHOS::DistributedRdb::RdbDebugInfo; struct RdbCorruptedEvent { std::string bundleName; std::string moduleName; @@ -37,19 +40,27 @@ struct RdbCorruptedEvent { int32_t systemErrorNo; std::string appendix; time_t errorOccurTime; - int dbFileStatRet; - struct stat dbFileStat; - int walFileStatRet; - struct stat walFileStat; + std::string path; + std::map debugInfos; }; class RdbFaultHiViewReporter { public: - static void ReportRdbCorruptedFault(RdbCorruptedEvent &eventInfo); + static RdbCorruptedEvent Create(const RdbStoreConfig &config, int32_t errCode, const std::string &appendix = ""); + static bool RegCollector(Connection::Collector collector); + static void Report(const RdbCorruptedEvent &eventInfo); + static void ReportFault(const RdbCorruptedEvent &eventInfo); + static void ReportRestore(const RdbCorruptedEvent &eventInfo); private: - static std::string GetFileStatInfo(const struct stat &fileStat); - static std::string GetDateInfo(time_t time); + static void Update(RdbCorruptedEvent &eventInfo, const std::map &infos); + static std::string GetFileStatInfo(const DebugInfo &debugInfo); + static bool IsReportCorruptedFault(const std::string &dbPath); + static void CreateCorruptedFlag(const std::string &dbPath); + static void DeleteCorruptedFlag(const std::string &dbPath); + static std::string GetTimeWithMilliseconds(time_t sec, int64_t nsec); + + static Connection::Collector collector_; }; } // namespace OHOS::NativeRdb #endif //DISTRIBUTEDDATAMGR_RDB_FAULT_HIVIEW_REPORTER_H diff --git a/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp b/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp index f3497867..7f6e360d 100644 --- a/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp +++ b/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp @@ -19,40 +19,60 @@ #include #include +#include +#include +#include +#include "connection.h" #include "hisysevent_c.h" #include "logger.h" #include "rdb_errno.h" - +#include "sqlite_global_config.h" +#include "sqlite_utils.h" namespace OHOS::NativeRdb { - using namespace OHOS::Rdb; - static constexpr const char *EVENT_NAME = "DATABASE_CORRUPTED"; static constexpr const char *DISTRIBUTED_DATAMGR = "DISTDATAMGR"; +static constexpr const char *DB_CORRUPTED_POSTFIX = ".corruptedflg"; +static constexpr int MAX_TIME_BUF_LEN = 32; +static constexpr int MILLISECONDS_LEN = 3; +static constexpr int NANO_TO_MILLI = 1000000; +static constexpr int MILLI_PRE_SEC = 1000; +Connection::Collector RdbFaultHiViewReporter::collector_ = nullptr; -void RdbFaultHiViewReporter::ReportRdbCorruptedFault(RdbCorruptedEvent &eventInfo) +void RdbFaultHiViewReporter::ReportFault(const RdbCorruptedEvent &eventInfo) { - char *bundleName = eventInfo.bundleName.data(); - char *moduleName = eventInfo.moduleName.data(); - char *storeType = eventInfo.storeType.data(); - char *storeName = eventInfo.storeName.data(); + if (IsReportCorruptedFault(eventInfo.path)) { + Report(eventInfo); + CreateCorruptedFlag(eventInfo.path); + } +} + +void RdbFaultHiViewReporter::ReportRestore(const RdbCorruptedEvent &eventInfo) +{ + Report(eventInfo); + DeleteCorruptedFlag(eventInfo.path); +} + +void RdbFaultHiViewReporter::Report(const RdbCorruptedEvent &eventInfo) +{ + std::string bundleName = eventInfo.bundleName; + std::string moduleName = eventInfo.moduleName; + std::string storeType = eventInfo.storeType; + std::string storeName = eventInfo.storeName; uint32_t checkType = eventInfo.integrityCheck; std::string appendInfo = eventInfo.appendix; - if (eventInfo.dbFileStatRet >= 0) { - appendInfo = appendInfo + " \n DB : \n" + GetFileStatInfo(eventInfo.dbFileStat); - } - if (eventInfo.walFileStatRet >= 0) { - appendInfo = appendInfo + " \n WAL : \n" + GetFileStatInfo(eventInfo.walFileStat); + for (auto &[name, debugInfo] : eventInfo.debugInfos) { + appendInfo += "\n" + name + " :" + GetFileStatInfo(debugInfo); } - LOG_WARN("storeName: %{public}s, errorCode: %{public}d, appendInfo : %{public}s.", storeName, eventInfo.errorCode, - appendInfo.c_str()); - std::string occurTime = GetDateInfo(eventInfo.errorOccurTime); + LOG_WARN("storeName: %{public}s, errorCode: %{public}d, appendInfo : %{public}s", + SqliteUtils::Anonymous(eventInfo.storeName).c_str(), eventInfo.errorCode, appendInfo.c_str()); + std::string occurTime = GetTimeWithMilliseconds(eventInfo.errorOccurTime, 0); char *errorOccurTime = occurTime.data(); HiSysEventParam params[] = { - { .name = "BUNDLE_NAME", .t = HISYSEVENT_STRING, .v = { .s = bundleName }, .arraySize = 0 }, - { .name = "MODULE_NAME", .t = HISYSEVENT_STRING, .v = { .s = moduleName }, .arraySize = 0 }, - { .name = "STORE_TYPE", .t = HISYSEVENT_STRING, .v = { .s = storeType }, .arraySize = 0 }, - { .name = "STORE_NAME", .t = HISYSEVENT_STRING, .v = { .s = storeName }, .arraySize = 0 }, + { .name = "BUNDLE_NAME", .t = HISYSEVENT_STRING, .v = { .s = bundleName.data() }, .arraySize = 0 }, + { .name = "MODULE_NAME", .t = HISYSEVENT_STRING, .v = { .s = moduleName.data() }, .arraySize = 0 }, + { .name = "STORE_TYPE", .t = HISYSEVENT_STRING, .v = { .s = storeType.data() }, .arraySize = 0 }, + { .name = "STORE_NAME", .t = HISYSEVENT_STRING, .v = { .s = storeName.data() }, .arraySize = 0 }, { .name = "SECURITY_LEVEL", .t = HISYSEVENT_UINT32, .v = { .ui32 = eventInfo.securityLevel }, .arraySize = 0 }, { .name = "PATH_AREA", .t = HISYSEVENT_UINT32, .v = { .ui32 = eventInfo.pathArea }, .arraySize = 0 }, { .name = "ENCRYPT_STATUS", .t = HISYSEVENT_UINT32, .v = { .ui32 = eventInfo.encryptStatus }, .arraySize = 0 }, @@ -65,23 +85,125 @@ void RdbFaultHiViewReporter::ReportRdbCorruptedFault(RdbCorruptedEvent &eventInf OH_HiSysEvent_Write(DISTRIBUTED_DATAMGR, EVENT_NAME, HISYSEVENT_FAULT, params, sizeof(params) / sizeof(params[0])); } -std::string RdbFaultHiViewReporter::GetFileStatInfo(const struct stat &fileStat) +std::string RdbFaultHiViewReporter::GetFileStatInfo(const DebugInfo &debugInfo) { - const uint32_t permission = 0777; std::stringstream oss; - oss << " device: " << fileStat.st_dev << " inode: " << fileStat.st_ino - << " mode: " << (fileStat.st_mode & permission) << " size: " << fileStat.st_size - << " natime: " << ctime(&fileStat.st_atime) << " smtime: " << ctime(&fileStat.st_mtime) - << " sctime: " << ctime(&fileStat.st_ctime); + const uint32_t permission = 0777; + oss << " device: 0x" << std::hex << debugInfo.dev_ << " inode: 0x" << std::hex << debugInfo.inode_; + if (debugInfo.inode_ != debugInfo.oldInode_ && debugInfo.oldInode_ != 0) { + oss << "<>0x" << std::hex << debugInfo.oldInode_; + } + oss << " mode: 0" << std::oct << (debugInfo.mode_ & permission) << " size: " << std::dec << debugInfo.size_ + << " natime: " << GetTimeWithMilliseconds(debugInfo.atime_.sec_, debugInfo.atime_.nsec_) + << " smtime: " << GetTimeWithMilliseconds(debugInfo.mtime_.sec_, debugInfo.mtime_.nsec_) + << " sctime: " << GetTimeWithMilliseconds(debugInfo.ctime_.sec_, debugInfo.ctime_.nsec_); return oss.str(); } -std::string RdbFaultHiViewReporter::GetDateInfo(time_t time) +bool RdbFaultHiViewReporter::IsReportCorruptedFault(const std::string &dbPath) +{ + if (dbPath.empty()) { + return false; + } + + std::string flagFilename = dbPath + DB_CORRUPTED_POSTFIX; + if (access(flagFilename.c_str(), F_OK) == 0) { + return false; + } + return true; +} + +void RdbFaultHiViewReporter::CreateCorruptedFlag(const std::string &dbPath) +{ + if (dbPath.empty()) { + return; + } + std::string flagFilename = dbPath + DB_CORRUPTED_POSTFIX; + int fd = creat(flagFilename.c_str(), S_IRWXU | S_IRWXG); + if (fd == -1) { + LOG_WARN("creat corrupted flg fail, flgname=%{public}s, errno=%{public}d", + SqliteUtils::Anonymous(flagFilename).c_str(), errno); + return; + } + close(fd); +} + +void RdbFaultHiViewReporter::DeleteCorruptedFlag(const std::string &dbPath) +{ + if (dbPath.empty()) { + return; + } + std::string flagFilename = dbPath + DB_CORRUPTED_POSTFIX; + int result = remove(flagFilename.c_str()); + if (result != 0) { + LOG_WARN("remove corrupted flg fail, flgname=%{public}s, errno=%{public}d", + SqliteUtils::Anonymous(flagFilename).c_str(), errno); + } +} + +std::string RdbFaultHiViewReporter::GetTimeWithMilliseconds(time_t sec, int64_t nsec) { - std::tm tm; - localtime_r(&time, &tm); std::stringstream oss; - oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + char buffer[MAX_TIME_BUF_LEN] = { 0 }; + std::tm local_time; + localtime_r(&sec, &local_time); + std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &local_time); + oss << buffer << '.' << std::setfill('0') << std::setw(MILLISECONDS_LEN) << (nsec / NANO_TO_MILLI) % MILLI_PRE_SEC; return oss.str(); } + +RdbCorruptedEvent RdbFaultHiViewReporter::Create(const RdbStoreConfig &config, int32_t errCode, + const std::string &appendix) +{ + RdbCorruptedEvent eventInfo; + eventInfo.bundleName = config.GetBundleName(); + eventInfo.moduleName = config.GetModuleName(); + eventInfo.storeType = config.GetDBType() == DB_SQLITE ? "RDB" : "VECTOR DB"; + eventInfo.storeName = config.GetName(); + eventInfo.securityLevel = static_cast(config.GetSecurityLevel()); + eventInfo.pathArea = static_cast(config.GetArea()); + eventInfo.encryptStatus = static_cast(config.IsEncrypt()); + eventInfo.integrityCheck = static_cast(config.GetIntegrityCheck()); + eventInfo.errorCode = static_cast(errCode); + eventInfo.systemErrorNo = errCode == E_OK ? 0 : errno; + eventInfo.appendix = appendix; + eventInfo.errorOccurTime = time(nullptr); + eventInfo.debugInfos = Connection::Collect(config); + SqliteGlobalConfig::GetDbPath(config, eventInfo.path); + if (collector_ != nullptr) { + Update(eventInfo, collector_(config)); + } + return eventInfo; +} + +bool RdbFaultHiViewReporter::RegCollector(Connection::Collector collector) +{ + if (collector_ != nullptr) { + return false; + } + collector_ = collector; + return true; +} + +void RdbFaultHiViewReporter::Update(RdbCorruptedEvent &eventInfo, const std::map &infos) +{ + auto &local = eventInfo.debugInfos; + auto lIt = local.begin(); + auto rIt = infos.begin(); + for (; lIt != local.end() && rIt != infos.end();) { + if (lIt->first == rIt->first) { + if (lIt->second.inode_ != rIt->second.inode_) { + lIt->second.oldInode_ = rIt->second.inode_; + } + ++lIt; + ++rIt; + continue; + } + if (lIt->first < rIt->first) { + ++lIt; + } else { + ++rIt; + } + } +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/connection.h b/relational_store/frameworks/native/rdb/include/connection.h index 5ce759bd..fa335803 100644 --- a/relational_store/frameworks/native/rdb/include/connection.h +++ b/relational_store/frameworks/native/rdb/include/connection.h @@ -30,18 +30,22 @@ class RdbStoreConfig; class Statement; class Connection { public: + using Info = DistributedRdb::RdbDebugInfo; using SConn = std::shared_ptr; using Stmt = std::shared_ptr; using Notifier = std::function &tables)>; using Creator = std::pair (*)(const RdbStoreConfig &config, bool isWriter); using Repairer = int32_t (*)(const RdbStoreConfig &config); using Deleter = int32_t (*)(const RdbStoreConfig &config); + using Collector = std::map (*)(const RdbStoreConfig &config); static std::pair Create(const RdbStoreConfig &config, bool isWriter); static int32_t Repair(const RdbStoreConfig &config); static int32_t Delete(const RdbStoreConfig &config); + static std::map Collect(const RdbStoreConfig &config); static int32_t RegisterCreator(int32_t dbType, Creator creator); static int32_t RegisterRepairer(int32_t dbType, Repairer repairer); static int32_t RegisterDeleter(int32_t dbType, Deleter deleter); + static int32_t RegisterCollector(int32_t dbType, Collector collector); int32_t SetId(int32_t id); int32_t GetId() const; diff --git a/relational_store/frameworks/native/rdb/include/connection_pool.h b/relational_store/frameworks/native/rdb/include/connection_pool.h index 291b29a9..bef480ae 100644 --- a/relational_store/frameworks/native/rdb/include/connection_pool.h +++ b/relational_store/frameworks/native/rdb/include/connection_pool.h @@ -116,6 +116,8 @@ private: std::shared_ptr Convert2AutoConn(std::shared_ptr node); void ReleaseNode(std::shared_ptr node); int RestoreByDbSqliteType(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus); + int RestoreMasterDb(const std::string &newPath, const std::string &backupPath); + bool CheckIntegrity(const std::string &dbPath); static constexpr int LIMITATION = 1024; static constexpr uint32_t ITER_V1 = 5000; diff --git a/relational_store/frameworks/native/rdb/include/grd_api_manager.h b/relational_store/frameworks/native/rdb/include/grd_api_manager.h index 2f7b9eee..8e6fed29 100644 --- a/relational_store/frameworks/native/rdb/include/grd_api_manager.h +++ b/relational_store/frameworks/native/rdb/include/grd_api_manager.h @@ -17,6 +17,7 @@ #define RDB_GRD_API_MANAGER_H #include "grd_type_export.h" +#include "rdb_visibility.h" namespace OHOS { namespace NativeRdb { @@ -86,6 +87,8 @@ struct GRD_APIInfo { DBSetConfig DBSetConfigApi = nullptr; }; +API_EXPORT bool IsUsingArkData(); + GRD_APIInfo GetApiInfoInstance(); } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/include/rd_statement.h b/relational_store/frameworks/native/rdb/include/rd_statement.h index 7b4ff685..c570d512 100644 --- a/relational_store/frameworks/native/rdb/include/rd_statement.h +++ b/relational_store/frameworks/native/rdb/include/rd_statement.h @@ -57,7 +57,6 @@ private: int Prepare(GRD_DB *db, const std::string &sql); int InnerBindBlobTypeArgs(const ValueObject &bindArg, uint32_t index) const; int IsValid(int index) const; - void ReportDbCorruptedEvent(int errorCode); bool readOnly_ = false; bool isStepInPrepare_ = false; diff --git a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h index a2d1e966..e5bf0043 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h +++ b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h @@ -86,6 +86,8 @@ public: int32_t UnlockCloudContainer(const RdbSyncerParam& param) override; + int32_t GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) override; + private: using ChangeInfo = RdbStoreObserver::ChangeInfo; using PrimaryFields = RdbStoreObserver::PrimaryFields; @@ -104,7 +106,7 @@ private: int32_t DoSubscribe(const RdbSyncerParam& param, const SubscribeOption &option); - int32_t DoUnSubscribe(const RdbSyncerParam& param); + int32_t DoUnSubscribe(const RdbSyncerParam& param, const SubscribeOption &option); int32_t DoRegister(const RdbSyncerParam ¶m); 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 69f247ae..a0415cff 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -189,41 +189,29 @@ public: std::pair Detach(const std::string &attachName, int32_t waitTime = 2) override; int ModifyLockStatus(const AbsRdbPredicates &predicates, bool isLock) override; int32_t GetDbType() const override; - void AfterOpen(const RdbStoreConfig &config); + std::pair LockCloudContainer() override; int32_t UnlockCloudContainer() override; int InterruptBackup() override; int32_t GetBackupStatus() const override; int32_t ExchangeSlaverToMaster(); -protected: - int InnerOpen(); - void InitSyncerParam(); - const RdbStoreConfig config_; - bool isOpen_ = false; - bool isReadOnly_; - bool isMemoryRdb_; - bool isEncrypt_; - int64_t vSchema_ = 0; - std::string path_; - std::string name_; - std::string fileType_; - private: - ConcurrentMap> trxConnMap_ = {}; - std::atomic newTrxId_ = 1; + using ExecuteSqls = std::vector>>>; + using Stmt = std::shared_ptr; + using RdbParam = DistributedRdb::RdbSyncerParam; + + static void AfterOpen(const RdbParam ¶m, int32_t retry = 0); + int InnerOpen(); + void InitSyncerParam(const RdbStoreConfig &config, bool created); int ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute = false, const std::vector &bindArgs = {}); std::pair HandleDifferentSqlTypes(std::shared_ptr statement, const std::string &sql, const ValueObject &object, int sqlType); - - using ExecuteSqls = std::vector>>>; - using Stmt = std::shared_ptr; int CheckAttach(const std::string &sql); std::pair BeginExecuteSql(const std::string &sql); ExecuteSqls GenerateSql(const std::string& table, const std::vector& buckets, int limit); int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); - int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs); void SetAssetStatus(const ValueObject &val, int32_t status); void DoCloudSync(const std::string &table); int InnerSync(const DistributedRdb::RdbService::Option &option, const DistributedRdb::PredicatesMemo &predicates, @@ -236,8 +224,6 @@ private: int SubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer); int32_t SubscribeLocalDetail(const SubscribeOption& option, const std::shared_ptr &observer); int SubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer); - static void UploadSchema(const DistributedRdb::RdbSyncerParam ¶m, uint32_t retry); - int UnSubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer); int UnSubscribeLocalAll(const SubscribeOption& option); int UnSubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer); @@ -247,11 +233,11 @@ private: int RegisterDataChangeCallback(); void InitDelayNotifier(); bool ColHasSpecificField(const std::vector &columns); + std::pair CreateWriteableStmt(const std::string &sql); std::pair GetStatement(const std::string& sql, std::shared_ptr conn) const; std::pair GetStatement(const std::string& sql, bool read = false) const; int AttachInner(const std::string &attachName, const std::string &dbPath, const std::vector &key, int32_t waitTime); - void RemoveDbFiles(std::string &path); int GetHashKeyForLockRow(const AbsRdbPredicates &predicates, std::vector> &hashKeys); int InsertWithConflictResolutionEntry(int64_t &outRowId, const std::string &table, const ValuesBucket &values, ConflictResolution conflictResolution); @@ -266,7 +252,6 @@ private: bool TryGetMasterSlaveBackupPath(const std::string &srcPath, std::string &destPath, bool isRestore = false); void NotifyDataChange(); int GetDestPath(const std::string &backupPath, std::string &destPath); - void ReportDbRestoreSuccessEvent(); static constexpr char SCHEME_RDB[] = "rdb://"; static constexpr uint32_t EXPANSION = 2; @@ -275,23 +260,28 @@ private: static inline constexpr uint32_t MAX_RETRY_TIMES = 5; static constexpr const char *ROW_ID = "ROWID"; - std::shared_ptr connectionPool_ = nullptr; + bool isOpen_ = false; + bool isReadOnly_ = false; + bool isMemoryRdb_; + uint32_t rebuild_ = RebuiltType::NONE; + SlaveStatus slaveStatus_ = SlaveStatus::UNDEFINED; + int64_t vSchema_ = 0; + std::atomic newTrxId_ = 1; + const RdbStoreConfig config_; DistributedRdb::RdbSyncerParam syncerParam_; - - std::shared_ptr pool_; - std::shared_ptr delayNotifier_ = nullptr; - + std::string path_; + std::string name_; + std::string fileType_; mutable std::shared_mutex rwMutex_; - - std::set cloudTables_; - std::mutex mutex_; - std::shared_ptr> syncTables_; + std::shared_ptr connectionPool_ = nullptr; + std::shared_ptr delayNotifier_ = nullptr; + std::shared_ptr> syncTables_ = nullptr; + std::set cloudTables_; std::map>> localObservers_; std::map>> localSharedObservers_; ConcurrentMap attachedInfo_; - uint32_t rebuild_; - SlaveStatus slaveStatus_; + ConcurrentMap> trxConnMap_ = {}; }; } // namespace OHOS::NativeRdb #endif diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h index 1d42e91b..36cb3d95 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h @@ -42,13 +42,17 @@ public: int SetSecurityLabel(const RdbStoreConfig &config); private: - static constexpr uint32_t BUCKET_MAX_SIZE = 4; using Param = DistributedRdb::RdbSyncerParam; + using Info = DistributedRdb::RdbDebugInfo; int ProcessOpenCallback(RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback); bool IsConfigInvalidChanged(const std::string &path, const RdbStoreConfig &config); int32_t GetParamFromService(DistributedRdb::RdbSyncerParam ¶m); - Param GetSyncParam(const RdbStoreConfig &config); + static Param GetSyncParam(const RdbStoreConfig &config); + static std::map Collector(const RdbStoreConfig &config); + + static constexpr uint32_t BUCKET_MAX_SIZE = 4; + static const bool regCollector_; std::string bundleName_; std::mutex mutex_; std::map> storeCache_; 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 2788a592..d49df89f 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_types_util.h +++ b/relational_store/frameworks/native/rdb/include/rdb_types_util.h @@ -45,6 +45,7 @@ using RdbChangedData = DistributedRdb::RdbChangedData; using RdbProperties = DistributedRdb::RdbChangeProperties; using Reference = DistributedRdb::Reference; using BigInt = NativeRdb::BigInteger; +using DebugInfo = DistributedRdb::RdbDebugInfo;; template<> API_EXPORT bool Marshalling(const SyncerParam &input, MessageParcel &data); template<> @@ -121,5 +122,9 @@ template<> API_EXPORT bool Marshalling(const BigInt &input, MessageParcel &data); template<> API_EXPORT bool Unmarshalling(BigInt &output, MessageParcel &data); +template<> +API_EXPORT bool Marshalling(const DebugInfo &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(DebugInfo &output, MessageParcel &data); } #endif // DISTRIBUTED_RDB_RDB_TYPES_UTIL_H diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/include/sqlite_connection.h index 1aacb682..638098fe 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection.h @@ -44,6 +44,7 @@ public: static std::pair> Create(const RdbStoreConfig &config, bool isWrite); static int32_t Delete(const RdbStoreConfig &config); static int32_t Repair(const RdbStoreConfig &config); + static std::map Collect(const RdbStoreConfig &config); SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection); ~SqliteConnection(); int32_t OnInitialize() override; @@ -75,8 +76,11 @@ protected: int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); private: - static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets"; - static constexpr const char *MERGE_ASSET_FUNC = "merge_asset"; + struct Suffix { + const char *suffix_ = nullptr; + const char *debug_ = nullptr; + }; + int InnerOpen(const RdbStoreConfig &config); int Configure(const RdbStoreConfig &config, std::string &dbPath); int SetPageSize(const RdbStoreConfig &config); @@ -87,6 +91,7 @@ private: int SetJournalMode(const RdbStoreConfig &config); int SetJournalSizeLimit(const RdbStoreConfig &config); int SetAutoCheckpoint(const RdbStoreConfig &config); + int SetWalFile(const RdbStoreConfig &config); int SetWalSyncMode(const std::string &syncMode); void LimitPermission(const std::string &dbPath) const; @@ -107,15 +112,24 @@ private: int32_t UnsubscribeLocalDetailAll(const std::string &event); int32_t OpenDatabase(const std::string &dbPath, int openFileFlags); int LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHandle); - RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig rdbConfig); - void ReportDbCorruptedEvent(int errCode, const std::string &checkResultInfo); + RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig); int CreateSlaveConnection(const RdbStoreConfig &config, bool isWrite, bool checkSlaveExist = true); int ExchangeSlaverToMaster(bool isRestore, SlaveStatus &status); bool IsRepairable(); std::pair ExchangeVerify(bool isRestore); static std::pair> InnerCreate(const RdbStoreConfig &config, bool isWrite); - + static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = { + {"", "DB"}, + {"-shm", "SHM"}, + {"-wal", "WAL"}, + {"-journal", "JOURNAL"}, + {"-slaveFailure", nullptr}, + {"-syncInterrupt", nullptr}, + {".corruptedflg", nullptr} + }; + static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets"; + static constexpr const char *MERGE_ASSET_FUNC = "merge_asset"; static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m static constexpr int BACKUP_PRE_WAIT_TIME = 10; @@ -123,6 +137,7 @@ private: static const int32_t regCreator_; static const int32_t regRepairer_; static const int32_t regDeleter_; + static const int32_t regCollector_; std::atomic backupId_ = TaskExecutor::INVALID_TASK_ID; sqlite3 *dbHandle_; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_global_config.h b/relational_store/frameworks/native/rdb/include/sqlite_global_config.h index f1171d1a..8039a835 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_global_config.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_global_config.h @@ -26,7 +26,6 @@ namespace NativeRdb { class GlobalExpr { public: static constexpr bool CALLBACK_LOG_SWITCH = true; /* Sqlite callback log switch */ - static constexpr bool DB_AUTO_CHECK = false; /* Sqlite callback log switch */ static constexpr int SOFT_HEAP_LIMIT = 8 * 1024 * 1024; /* 8MB */ static constexpr int DB_PAGE_SIZE = 4096; /* default page size : 4k */ static constexpr int DB_JOURNAL_SIZE = 1024 * 1024; /* default file size : 1M */ @@ -42,6 +41,7 @@ public: static constexpr char EXPORT_SQL[] = "SELECT export_database('backup')"; static constexpr char DETACH_BACKUP_SQL[] = "detach backup"; static constexpr char PRAGMA_JOUR_MODE_EXP[] = "PRAGMA journal_mode"; + static constexpr char PRAGMA_BACKUP_JOUR_MODE_WAL[] = "PRAGMA backup.journal_mode=WAL"; static constexpr char PRAGMA_VERSION[] = "PRAGMA user_version"; static constexpr char JOURNAL_MODE_WAL[] = "WAL"; static constexpr char DEFAULE_SYNC_MODE[] = "FULL"; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h index 656dd273..537a0842 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h @@ -29,8 +29,6 @@ public: using ExecuteSqls = std::vector>>>; SqliteSqlBuilder(); ~SqliteSqlBuilder(); - static std::string BuildDeleteString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); static std::string BuildUpdateString(const ValuesBucket &values, const std::string &tableName, const std::vector &whereArgs, const std::string &index, const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset, std::vector &bindArgs, @@ -39,12 +37,8 @@ public: const std::vector &columns, const std::string &whereClause, const std::string &groupBy, const std::string &indexName, const std::string &orderBy, const int &limit, const int &offset, std::string &outSql); - static std::string BuildCountString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); static std::string BuildSqlStringFromPredicates(const std::string &index, const std::string &joinClause, const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); - static std::string BuildSqlStringFromPredicatesNoWhere(const std::string &index, const std::string &whereClause, - const std::string &group, const std::string &order, int limit, int offset); static std::string BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns); static std::string BuildCountString(const AbsRdbPredicates &predicates); static std::string BuildSqlStringFromPredicates(const AbsPredicates &predicates); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_statement.h b/relational_store/frameworks/native/rdb/include/sqlite_statement.h index e4d89883..835ddbc5 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_statement.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_statement.h @@ -86,7 +86,6 @@ private: int InnerStep(); int InnerFinalize(); ValueObject GetValueFromBlob(int32_t index, int32_t type) const; - void ReportDbCorruptedEvent(int errorCode); void ReadFile2Buffer(); void PrintInfoForDbError(int errorCode); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_utils.h b/relational_store/frameworks/native/rdb/include/sqlite_utils.h index 22b2fbc6..069e7757 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_utils.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_utils.h @@ -87,6 +87,9 @@ private: static constexpr size_t TYPE_SIZE = sizeof(SQL_TYPE_MAP) / sizeof(SqlType); static constexpr const char* ON_CONFLICT_CLAUSE[CONFLICT_CLAUSE_COUNT] = { "", " OR ROLLBACK", " OR ABORT", " OR FAIL", " OR IGNORE", " OR REPLACE" }; + + static std::string GetAnonymousName(const std::string& fileName); + static std::string AnonyDigits(const std::string& fileName); }; } // namespace NativeRdb 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 ef09497f..e2a580c5 100644 --- a/relational_store/frameworks/native/rdb/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/include/step_result_set.h @@ -50,7 +50,6 @@ private: std::pair GetValueObject(int32_t col, size_t index); std::shared_ptr GetStatement(); int Reset(); - int InitRowCount(); int PrepareStep(); // Max times of retrying step query diff --git a/relational_store/frameworks/native/rdb/mock/include/connection.h b/relational_store/frameworks/native/rdb/mock/include/connection.h index 5ce759bd..fa335803 100644 --- a/relational_store/frameworks/native/rdb/mock/include/connection.h +++ b/relational_store/frameworks/native/rdb/mock/include/connection.h @@ -30,18 +30,22 @@ class RdbStoreConfig; class Statement; class Connection { public: + using Info = DistributedRdb::RdbDebugInfo; using SConn = std::shared_ptr; using Stmt = std::shared_ptr; using Notifier = std::function &tables)>; using Creator = std::pair (*)(const RdbStoreConfig &config, bool isWriter); using Repairer = int32_t (*)(const RdbStoreConfig &config); using Deleter = int32_t (*)(const RdbStoreConfig &config); + using Collector = std::map (*)(const RdbStoreConfig &config); static std::pair Create(const RdbStoreConfig &config, bool isWriter); static int32_t Repair(const RdbStoreConfig &config); static int32_t Delete(const RdbStoreConfig &config); + static std::map Collect(const RdbStoreConfig &config); static int32_t RegisterCreator(int32_t dbType, Creator creator); static int32_t RegisterRepairer(int32_t dbType, Repairer repairer); static int32_t RegisterDeleter(int32_t dbType, Deleter deleter); + static int32_t RegisterCollector(int32_t dbType, Collector collector); int32_t SetId(int32_t id); int32_t GetId() const; diff --git a/relational_store/frameworks/native/rdb/mock/include/connection_pool.h b/relational_store/frameworks/native/rdb/mock/include/connection_pool.h index 291b29a9..bef480ae 100644 --- a/relational_store/frameworks/native/rdb/mock/include/connection_pool.h +++ b/relational_store/frameworks/native/rdb/mock/include/connection_pool.h @@ -116,6 +116,8 @@ private: std::shared_ptr Convert2AutoConn(std::shared_ptr node); void ReleaseNode(std::shared_ptr node); int RestoreByDbSqliteType(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus); + int RestoreMasterDb(const std::string &newPath, const std::string &backupPath); + bool CheckIntegrity(const std::string &dbPath); static constexpr int LIMITATION = 1024; static constexpr uint32_t ITER_V1 = 5000; 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 6c41bc5d..67056e27 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 @@ -106,45 +106,31 @@ public: int32_t GetBackupStatus() const override; int32_t ExchangeSlaverToMaster(); -protected: - int InnerOpen(); - void InitSyncerParam(); - const RdbStoreConfig config_; - bool isOpen_ = false; - bool isReadOnly_; - bool isMemoryRdb_; - bool isEncrypt_; - int64_t vSchema_ = 0; - std::string path_; - std::string name_; - std::string fileType_; - private: - ConcurrentMap> trxConnMap_ = {}; - std::atomic newTrxId_ = 1; + using ExecuteSqls = std::vector>>>; + using Stmt = std::shared_ptr; + using RdbParam = DistributedRdb::RdbSyncerParam; + + int InnerOpen(); + void InitSyncerParam(const RdbStoreConfig &config, bool created); int ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute = false, const std::vector &bindArgs = {}); std::pair HandleDifferentSqlTypes(std::shared_ptr statement, const std::string &sql, const ValueObject &object, int sqlType); - - using ExecuteSqls = std::vector>>>; - using Stmt = std::shared_ptr; int CheckAttach(const std::string &sql); std::pair BeginExecuteSql(const std::string &sql); ExecuteSqls GenerateSql(const std::string& table, const std::vector& buckets, int limit); int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); - int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs = std::vector()); - int ExecuteGetLongInner(const std::string &sql, const std::vector &bindArgs); + int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs); void SetAssetStatus(const ValueObject &val, int32_t status); void DoCloudSync(const std::string &table); - int InnerBackup(const std::string &databasePath, - const std::vector &destEncryptKey = std::vector()); - int RegisterDataChangeCallback(); + int InnerBackup(const std::string& databasePath, + const std::vector& destEncryptKey = std::vector()); + std::pair CreateWriteableStmt(const std::string &sql); std::pair GetStatement(const std::string& sql, std::shared_ptr conn) const; std::pair GetStatement(const std::string& sql, bool read = false) const; int AttachInner(const std::string &attachName, const std::string &dbPath, const std::vector &key, int32_t waitTime); - void RemoveDbFiles(std::string &path); int InsertWithConflictResolutionEntry(int64_t &outRowId, const std::string &table, const ValuesBucket &values, ConflictResolution conflictResolution); int UpdateWithConflictResolutionEntry(int &changedRows, const std::string &table, const ValuesBucket &values, @@ -156,20 +142,34 @@ private: int64_t trxId); int GetSlaveName(const std::string &dbName, std::string &backupFilePath); bool TryGetMasterSlaveBackupPath(const std::string &srcPath, std::string &destPath, bool isRestore = false); + void NotifyDataChange(); int GetDestPath(const std::string &backupPath, std::string &destPath); - void ReportDbRestoreSuccessEvent(); + static constexpr char SCHEME_RDB[] = "rdb://"; static constexpr uint32_t EXPANSION = 2; - static constexpr uint32_t AUTO_SYNC_MAX_INTERVAL = 20000; static inline constexpr uint32_t INTERVAL = 10; + static inline constexpr uint32_t RETRY_INTERVAL = 5; // s + static inline constexpr uint32_t MAX_RETRY_TIMES = 5; static constexpr const char *ROW_ID = "ROWID"; - std::set cloudTables_; - DistributedRdb::RdbSyncerParam syncerParam_; - std::shared_ptr connectionPool_; - ConcurrentMap attachedInfo_; + bool isOpen_ = false; + bool isReadOnly_ = false; + bool isMemoryRdb_; uint32_t rebuild_; SlaveStatus slaveStatus_; + int64_t vSchema_ = 0; + std::atomic newTrxId_ = 1; + const RdbStoreConfig config_; + DistributedRdb::RdbSyncerParam syncerParam_; + std::string path_; + std::string name_; + std::string fileType_; + std::mutex mutex_; + std::shared_ptr connectionPool_ = nullptr; + std::shared_ptr> syncTables_ = nullptr; + std::set cloudTables_; + ConcurrentMap attachedInfo_; + ConcurrentMap> trxConnMap_ = {}; }; } // namespace OHOS::NativeRdb #endif diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h b/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h index 6b860294..36cb3d95 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h +++ b/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h @@ -16,9 +16,11 @@ #ifndef NATIVE_RDB_STORE_MANAGER_H #define NATIVE_RDB_STORE_MANAGER_H +#include #include #include #include +#include #include "lru_bucket.h" #include "rdb_open_callback.h" @@ -40,13 +42,17 @@ public: int SetSecurityLabel(const RdbStoreConfig &config); private: - static constexpr uint32_t BUCKET_MAX_SIZE = 4; using Param = DistributedRdb::RdbSyncerParam; + using Info = DistributedRdb::RdbDebugInfo; int ProcessOpenCallback(RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback); bool IsConfigInvalidChanged(const std::string &path, const RdbStoreConfig &config); int32_t GetParamFromService(DistributedRdb::RdbSyncerParam ¶m); - Param GetSyncParam(const RdbStoreConfig &config); + static Param GetSyncParam(const RdbStoreConfig &config); + static std::map Collector(const RdbStoreConfig &config); + + static constexpr uint32_t BUCKET_MAX_SIZE = 4; + static const bool regCollector_; std::string bundleName_; std::mutex mutex_; std::map> storeCache_; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h index af549853..6ff84022 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h @@ -44,6 +44,7 @@ public: static std::pair> Create(const RdbStoreConfig &config, bool isWrite); static int32_t Delete(const RdbStoreConfig &config); static int32_t Repair(const RdbStoreConfig &config); + static std::map Collect(const RdbStoreConfig &config); SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection); ~SqliteConnection(); int32_t OnInitialize() override; @@ -75,8 +76,11 @@ protected: int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); private: - static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets"; - static constexpr const char *MERGE_ASSET_FUNC = "merge_asset"; + struct Suffix { + const char *suffix_ = nullptr; + const char *debug_ = nullptr; + }; + int InnerOpen(const RdbStoreConfig &config); int Configure(const RdbStoreConfig &config, std::string &dbPath); int SetPageSize(const RdbStoreConfig &config); @@ -87,6 +91,7 @@ private: int SetJournalMode(const RdbStoreConfig &config); int SetJournalSizeLimit(const RdbStoreConfig &config); int SetAutoCheckpoint(const RdbStoreConfig &config); + int SetWalFile(const RdbStoreConfig &config); int SetWalSyncMode(const std::string &syncMode); void LimitPermission(const std::string &dbPath) const; @@ -106,17 +111,25 @@ private: const std::shared_ptr &observer); int32_t UnsubscribeLocalDetailAll(const std::string &event); int32_t OpenDatabase(const std::string &dbPath, int openFileFlags); - void ReadFile2Buffer(); int LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHandle); - RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig rdbConfig); - void ReportDbCorruptedEvent(int errCode, const std::string &checkResultInfo); - int CreateSlaveConnection(const RdbStoreConfig &config, bool isWrite, bool checkSlaveExist = false); + RdbStoreConfig GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig); + int CreateSlaveConnection(const RdbStoreConfig &config, bool isWrite, bool checkSlaveExist = true); int ExchangeSlaverToMaster(bool isRestore, SlaveStatus &status); bool IsRepairable(); std::pair ExchangeVerify(bool isRestore); static std::pair> InnerCreate(const RdbStoreConfig &config, bool isWrite); - + static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = { + {"", "DB"}, + {"-shm", "SHM"}, + {"-wal", "WAL"}, + {"-journal", "JOURNAL"}, + {"-slaveFailure", nullptr}, + {"-syncInterrupt", nullptr}, + {".corruptedflg", nullptr} + }; + static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets"; + static constexpr const char *MERGE_ASSET_FUNC = "merge_asset"; static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m static constexpr int BACKUP_PRE_WAIT_TIME = 10; @@ -124,6 +137,7 @@ private: static const int32_t regCreator_; static const int32_t regRepairer_; static const int32_t regDeleter_; + static const int32_t regCollector_; std::atomic backupId_ = TaskExecutor::INVALID_TASK_ID; sqlite3 *dbHandle_; 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 8ba7776c..31a57a23 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 @@ -50,7 +50,6 @@ private: std::pair GetValueObject(int32_t col, size_t index); std::shared_ptr GetStatement(); int Reset(); - int InitRowCount(); int PrepareStep(); // Max times of retrying step query diff --git a/relational_store/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp b/relational_store/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp index d00deecb..701f3e63 100644 --- a/relational_store/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp +++ b/relational_store/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp @@ -14,23 +14,66 @@ */ #include "rdb_fault_hiview_reporter.h" +#include "connection.h" namespace OHOS::NativeRdb { -void RdbFaultHiViewReporter::ReportRdbCorruptedFault(RdbCorruptedEvent &eventInfo) +void RdbFaultHiViewReporter::ReportFault(const RdbCorruptedEvent &eventInfo) { (void)eventInfo; } -std::string RdbFaultHiViewReporter::GetFileStatInfo(const struct stat &fileStat) +void RdbFaultHiViewReporter::ReportRestore(const RdbCorruptedEvent &eventInfo) { - (void)fileStat; + (void)eventInfo; +} + +void RdbFaultHiViewReporter::Report(const RdbCorruptedEvent &eventInfo) +{ + (void)eventInfo; +} + +std::string RdbFaultHiViewReporter::GetFileStatInfo(const DebugInfo &debugInfo) +{ + (void)debugInfo; return ""; } -std::string RdbFaultHiViewReporter::GetDateInfo(time_t time) +bool RdbFaultHiViewReporter::IsReportCorruptedFault(const std::string &dbPath) +{ + return false; +} + +void RdbFaultHiViewReporter::CreateCorruptedFlag(const std::string &dbPath) +{ + (void)dbPath; +} + +void RdbFaultHiViewReporter::DeleteCorruptedFlag(const std::string &dbPath) +{ + (void)dbPath; +} + +std::string RdbFaultHiViewReporter::GetTimeWithMilliseconds(time_t sec, int64_t nsec) { - (void)time; + (void)sec; + (void)nsec; return ""; } +RdbCorruptedEvent RdbFaultHiViewReporter::Create(const RdbStoreConfig &config, int32_t errCode, + const std::string &appendix) +{ + RdbCorruptedEvent eventInfo; + return eventInfo; +} +bool RdbFaultHiViewReporter::RegCollector(Connection::Collector collector) +{ + (void)collector; + return true; +} +void RdbFaultHiViewReporter::Update(RdbCorruptedEvent &eventInfo, const std::map &infos) +{ + (void)eventInfo; + (void)infos; +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp index f2af3b70..fcb3bc24 100644 --- a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp @@ -257,7 +257,7 @@ int AbsResultSet::GetRow(RowEntity &rowEntity) ValueObject value; auto ret = Get(index, value); if (ret != E_OK) { - LOG_ERROR("Get(%{public}d, %{public}s)->ret %{public}d", index, name.c_str(), ret); + LOG_ERROR("Get(%{public}d, %{public}s)->ret %{public}d", index, SqliteUtils::Anonymous(name).c_str(), ret); return ret; } rowEntity.Put(name, index, std::move(value)); @@ -404,7 +404,7 @@ int AbsResultSet::GetColumnIndex(const std::string &columnName, int &columnIndex return E_OK; } } - LOG_ERROR("failed, columnName is: %{public}s", columnName.c_str()); + LOG_ERROR("failed, columnName is: %{public}s", SqliteUtils::Anonymous(columnName).c_str()); return E_ERROR; } diff --git a/relational_store/frameworks/native/rdb/src/connection.cpp b/relational_store/frameworks/native/rdb/src/connection.cpp index 1e851370..2df3ba07 100644 --- a/relational_store/frameworks/native/rdb/src/connection.cpp +++ b/relational_store/frameworks/native/rdb/src/connection.cpp @@ -21,6 +21,7 @@ namespace OHOS::NativeRdb { static Connection::Creator g_creators[DB_BUTT] = { nullptr, nullptr }; static Connection::Repairer g_repairers[DB_BUTT] = { nullptr, nullptr }; static Connection::Deleter g_fileDeleter[DB_BUTT] = { nullptr, nullptr }; +static Connection::Collector g_collectors[DB_BUTT] = { nullptr, nullptr }; std::pair> Connection::Create(const RdbStoreConfig &config, bool isWriter) { auto dbType = config.GetDBType(); @@ -57,15 +58,29 @@ int32_t Connection::Delete(const RdbStoreConfig &config) if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { return E_INVALID_ARGS; } - auto deleter = g_fileDeleter[dbType]; if (deleter == nullptr) { return E_NOT_SUPPORT; } - + return deleter(config); } +std::map Connection::Collect(const RdbStoreConfig &config) +{ + auto dbType = config.GetDBType(); + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return {}; + } + + auto collector = g_collectors[dbType]; + if (collector == nullptr) { + return {}; + } + + return collector(config); +} + int32_t Connection::RegisterCreator(int32_t dbType, Creator creator) { if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { @@ -108,6 +123,20 @@ int32_t Connection::RegisterDeleter(int32_t dbType, Deleter deleter) return E_OK; } +int32_t Connection::RegisterCollector(int32_t dbType, Collector collector) +{ + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + + if (g_collectors[dbType] != nullptr) { + return E_OK; + } + + g_collectors[dbType] = collector; + return E_OK; +} + int Connection::SetId(int id) { id_ = id; diff --git a/relational_store/frameworks/native/rdb/src/connection_pool.cpp b/relational_store/frameworks/native/rdb/src/connection_pool.cpp index 1e07a7ac..806062b4 100644 --- a/relational_store/frameworks/native/rdb/src/connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/connection_pool.cpp @@ -52,7 +52,7 @@ std::shared_ptr ConnPool::Create(const RdbStoreConfig &storeConfig, in std::shared_ptr conn; for (uint32_t retry = 0; retry < ITERS_COUNT; ++retry) { std::tie(errCode, conn) = pool->Init(); - if (errCode == E_OK || errCode != E_SQLITE_CORRUPT) { + if (errCode != E_SQLITE_CORRUPT) { break; } storeConfig.SetIter(ITER_V1); @@ -76,7 +76,8 @@ std::pair> ConnPool::HandleDataCorr pool = Create(storeConfig, errCode); if (errCode != E_OK) { LOG_WARN("failed, type %{public}d db %{public}s encrypt %{public}d error %{public}d, errno", - static_cast(rebuiltType), storeConfig.GetName().c_str(), storeConfig.IsEncrypt(), errCode, errno); + static_cast(rebuiltType), SqliteUtils::Anonymous(storeConfig.GetName()).c_str(), + storeConfig.IsEncrypt(), errCode, errno); } return result; @@ -364,7 +365,7 @@ int ConnPool::RestoreByDbSqliteType(const std::string &newPath, const std::strin return E_DATABASE_BUSY; } ret = connection->Restore(backupPath, {}, slaveStatus); - if (ret == E_SQLITE_CORRUPT && config_.GetAllowRebuild()) { + if (ret == E_DB_NOT_EXIST || ret == E_SQLITE_CORRUPT) { LOG_WARN("corrupt, rebuild:%{public}s", SqliteUtils::Anonymous(backupPath).c_str()); CloseAllConnections(); Connection::Delete(config_); @@ -384,6 +385,19 @@ int ConnPool::RestoreByDbSqliteType(const std::string &newPath, const std::strin } return ret; } + + return RestoreMasterDb(newPath, backupPath); +} + +int ConnPool::RestoreMasterDb(const std::string &newPath, const std::string &backupPath) +{ + if (!CheckIntegrity(backupPath)) { + LOG_ERROR("backup file is corrupted, %{public}s", SqliteUtils::Anonymous(backupPath).c_str()); + return E_SQLITE_CORRUPT; + } + SqliteUtils::DeleteFile(backupPath + "-shm"); + SqliteUtils::DeleteFile(backupPath + "-wal"); + CloseAllConnections(); Connection::Delete(config_); @@ -393,11 +407,17 @@ int ConnPool::RestoreByDbSqliteType(const std::string &newPath, const std::strin Connection::Delete(config); } + int ret = E_OK; if (!SqliteUtils::CopyFile(backupPath, newPath)) { ret = E_ERROR; } - auto [errCode, node] = Init(); - return ret == E_OK ? errCode : ret; + auto result = Init(); + if (result.first != E_OK) { + CloseAllConnections(); + Connection::Delete(config_); + result = Init(); + } + return ret == E_OK ? result.first : ret; } std::stack &ConnPool::GetTransactionStack() @@ -644,6 +664,15 @@ int32_t ConnectionPool::Container::RelDetails(std::shared_ptr node) return E_OK; } +bool ConnectionPool::CheckIntegrity(const std::string &dbPath) +{ + RdbStoreConfig config(config_); + config.SetPath(dbPath); + config.SetIntegrityCheck(IntegrityCheck::FULL); + auto [ret, connection] = Connection::Create(config, true); + return ret == E_OK; +} + int32_t ConnPool::Container::Clear() { std::list> nodes; @@ -676,7 +705,7 @@ int32_t ConnPool::Container::Dump(const char *header) { std::string info; std::vector> details; - std::string title = " M_T_C[" + std::to_string(max_) + ","+ std::to_string(total_) +"," + std::string title = " M_T_C[" + std::to_string(max_) + ","+ std::to_string(total_) +"," + std::to_string(count_) + "]"; { std::unique_lock lock(mutex_); diff --git a/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp b/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp index ed1af348..bf7b70be 100644 --- a/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp @@ -63,6 +63,18 @@ void GRD_DBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) #endif } +bool IsUsingArkData() +{ +#ifndef _WIN32 + if (g_library == nullptr) { + GetApiInfoInstance(); + } + return g_library != nullptr; +#else + return false; +#endif +} + GRD_APIInfo GetApiInfoInstance() { GRD_APIInfo GRD_TempApiStruct; diff --git a/relational_store/frameworks/native/rdb/src/rd_connection.cpp b/relational_store/frameworks/native/rdb/src/rd_connection.cpp index 35502a78..08994d7a 100644 --- a/relational_store/frameworks/native/rdb/src/rd_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_connection.cpp @@ -71,6 +71,7 @@ static constexpr const char *RD_POST_FIXES[] = { ".ctrl.dwr", ".safe", ".map", + ".corruptedflg", }; int32_t RdConnection::Delete(const RdbStoreConfig &config) diff --git a/relational_store/frameworks/native/rdb/src/rd_statement.cpp b/relational_store/frameworks/native/rdb/src/rd_statement.cpp index 5be71f5f..f15baba6 100644 --- a/relational_store/frameworks/native/rdb/src/rd_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_statement.cpp @@ -127,8 +127,8 @@ int RdStatement::Prepare(GRD_DB *db, const std::string &newSql) GRD_SqlStmt *tmpStmt = nullptr; int ret = RdUtils::RdSqlPrepare(db, newSql.c_str(), newSql.length(), &tmpStmt, nullptr); if (ret != E_OK) { - if (ret == E_SQLITE_CORRUPT) { - ReportDbCorruptedEvent(ret); + if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } if (tmpStmt != nullptr) { (void)RdUtils::RdSqlFinalize(tmpStmt); @@ -295,8 +295,8 @@ int32_t RdStatement::Step() return E_OK; } int ret = RdUtils::RdSqlStep(stmtHandle_); - if (ret == E_SQLITE_CORRUPT) { - ReportDbCorruptedEvent(ret); + if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } stepCnt_++; return ret; @@ -491,34 +491,5 @@ void RdStatement::GetProperties() { columnCount_ = RdUtils::RdSqlColCnt(stmtHandle_); } - -void RdStatement::ReportDbCorruptedEvent(int errorCode) -{ - if (config_ == nullptr) { - return; - } - RdbCorruptedEvent eventInfo; - eventInfo.bundleName = config_->GetBundleName(); - eventInfo.moduleName = config_->GetModuleName(); - eventInfo.storeType = "RDB"; - eventInfo.storeName = config_->GetName(); - eventInfo.securityLevel = static_cast(config_->GetSecurityLevel()); - eventInfo.pathArea = static_cast(config_->GetArea()); - eventInfo.encryptStatus = static_cast(config_->IsEncrypt()); - eventInfo.integrityCheck = static_cast(config_->GetIntegrityCheck()); - eventInfo.errorCode = static_cast(errorCode); - eventInfo.systemErrorNo = errno; - eventInfo.errorOccurTime = time(nullptr); - std::string dbPath; - if (SqliteGlobalConfig::GetDbPath(*config_, dbPath) == E_OK && access(dbPath.c_str(), F_OK) == 0) { - eventInfo.dbFileStatRet = stat(dbPath.c_str(), &eventInfo.dbFileStat); - std::string walPath = dbPath + "-wal"; - eventInfo.walFileStatRet = stat(walPath.c_str(), &eventInfo.walFileStat); - } else { - eventInfo.dbFileStatRet = -1; - eventInfo.walFileStatRet = -1; - } - RdbFaultHiViewReporter::ReportRdbCorruptedFault(eventInfo); -} } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rd_utils.cpp b/relational_store/frameworks/native/rdb/src/rd_utils.cpp index 6c0a69d8..7acdf1af 100644 --- a/relational_store/frameworks/native/rdb/src/rd_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_utils.cpp @@ -80,7 +80,7 @@ int RdUtils::RdDbOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBOpenApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBOpenApi(dbPath, configStr, flags, db)); } @@ -92,55 +92,51 @@ int RdUtils::RdDbClose(GRD_DB *db, uint32_t flags) GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBCloseApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBCloseApi(db, flags)); } int RdUtils::RdDbRepair(const char *dbPath, const char *configStr) { - LOG_DEBUG("[RdUtils::RdDbRepair]"); if (GRD_KVApiInfo.DBRepairApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBRepairApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBRepairApi(dbPath, configStr)); } int RdUtils::RdSqlPrepare(GRD_DB *db, const char *str, uint32_t strLen, GRD_SqlStmt **stmt, const char **unusedStr) { - LOG_DEBUG("[RdUtils::RdSqlPrepare]"); if (GRD_KVApiInfo.DBSqlPrepare == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlPrepare == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlPrepare(db, str, strLen, stmt, unusedStr)); } int RdUtils::RdSqlReset(GRD_SqlStmt *stmt) { - LOG_DEBUG("[RdUtils::RdSqlReset]"); if (GRD_KVApiInfo.DBSqlReset == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlReset == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlReset(stmt)); } int RdUtils::RdSqlFinalize(GRD_SqlStmt *stmt) { - LOG_DEBUG("[RdUtils::RdSqlFinalize]"); if (GRD_KVApiInfo.DBSqlFinalize == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlFinalize == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlFinalize(stmt)); } @@ -152,12 +148,11 @@ void RdSqlFreeBlob(void *blobElementSize) int RdUtils::RdSqlBindBlob(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int32_t len, void (*freeFunc)(void *)) { - LOG_DEBUG("[RdUtils::RdSqlBindBlob]"); if (GRD_KVApiInfo.DBSqlBindBlob == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindBlob == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } if (len <= 0) { LOG_ERROR("Invalid len %{public}d", len); @@ -186,12 +181,11 @@ void RdSqlFreeCharStr(void *charStr) int RdUtils::RdSqlBindText(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int32_t len, void (*freeFunc)(void *)) { - LOG_DEBUG("[RdUtils::RdSqlBindText]"); if (GRD_KVApiInfo.DBSqlBindText == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindText == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } if (len <= 0) { LOG_ERROR("Invalid len %{public}d", len); @@ -215,48 +209,44 @@ int RdUtils::RdSqlBindText(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int int RdUtils::RdSqlBindInt(GRD_SqlStmt *stmt, uint32_t idx, int32_t val) { - LOG_DEBUG("[RdUtils::RdSqlBindInt]"); if (GRD_KVApiInfo.DBSqlBindInt == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindInt == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindInt(stmt, idx, val)); } int RdUtils::RdSqlBindInt64(GRD_SqlStmt *stmt, uint32_t idx, int64_t val) { - LOG_DEBUG("[RdUtils::RdSqlBindInt64]"); if (GRD_KVApiInfo.DBSqlBindInt64 == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindInt64 == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindInt64(stmt, idx, val)); } int RdUtils::RdSqlBindDouble(GRD_SqlStmt *stmt, uint32_t idx, double val) { - LOG_DEBUG("[RdUtils::RdSqlBindDouble]"); if (GRD_KVApiInfo.DBSqlBindDouble == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindDouble == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindDouble(stmt, idx, val)); } int RdUtils::RdSqlBindNull(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlBindNull]"); if (GRD_KVApiInfo.DBSqlBindNull == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindNull == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindNull(stmt, idx)); } @@ -269,12 +259,11 @@ void RdSqlFreeFloatArr(void *floatElement) int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, uint32_t dim, void (*freeFunc)(void *)) { - LOG_DEBUG("[RdUtils::RdSqlBindFloatVector]"); if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } if (dim <= 0) { LOG_ERROR("Invalid dim %{public}d", dim); @@ -298,31 +287,28 @@ int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, int RdUtils::RdSqlStep(GRD_SqlStmt *stmt) { - LOG_DEBUG("[RdUtils::RdSqlStep]"); if (GRD_KVApiInfo.DBSqlStep == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlStep == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlStep(stmt)); } int RdUtils::RdSqlColCnt(GRD_SqlStmt *stmt) { - LOG_DEBUG("[RdUtils::RdSqlColCnt]"); if (GRD_KVApiInfo.DBSqlColCnt == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlColCnt == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlColCnt(stmt)); } ColumnType RdUtils::RdSqlColType(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColType]"); if (GRD_KVApiInfo.DBSqlColType == nullptr) { GetApiInfoInstance(); } @@ -334,19 +320,17 @@ ColumnType RdUtils::RdSqlColType(GRD_SqlStmt *stmt, uint32_t idx) int RdUtils::RdSqlColBytes(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColBytes]"); if (GRD_KVApiInfo.DBSqlColBytes == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSqlColBytes == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBSqlColBytes(stmt, idx)); } char *RdUtils::RdSqlColName(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColName]"); if (GRD_KVApiInfo.DBSqlColName == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -358,7 +342,6 @@ char *RdUtils::RdSqlColName(GRD_SqlStmt *stmt, uint32_t idx) GRD_DbValueT RdUtils::RdSqlColValue(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColValue]"); if (GRD_KVApiInfo.DBSqlColValue == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -370,7 +353,6 @@ GRD_DbValueT RdUtils::RdSqlColValue(GRD_SqlStmt *stmt, uint32_t idx) uint8_t *RdUtils::RdSqlColBlob(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColBlob]"); if (GRD_KVApiInfo.DBSqlColBlob == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -382,7 +364,6 @@ uint8_t *RdUtils::RdSqlColBlob(GRD_SqlStmt *stmt, uint32_t idx) char *RdUtils::RdSqlColText(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColText]"); if (GRD_KVApiInfo.DBSqlColText == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -394,7 +375,6 @@ char *RdUtils::RdSqlColText(GRD_SqlStmt *stmt, uint32_t idx) int RdUtils::RdSqlColInt(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColInt]"); if (GRD_KVApiInfo.DBSqlColInt == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -406,7 +386,6 @@ int RdUtils::RdSqlColInt(GRD_SqlStmt *stmt, uint32_t idx) uint64_t RdUtils::RdSqlColInt64(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColInt64]"); if (GRD_KVApiInfo.DBSqlColInt64 == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -418,7 +397,6 @@ uint64_t RdUtils::RdSqlColInt64(GRD_SqlStmt *stmt, uint32_t idx) double RdUtils::RdSqlColDouble(GRD_SqlStmt *stmt, uint32_t idx) { - LOG_DEBUG("[RdUtils::RdSqlColDouble]"); if (GRD_KVApiInfo.DBSqlColDouble == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -430,7 +408,6 @@ double RdUtils::RdSqlColDouble(GRD_SqlStmt *stmt, uint32_t idx) const float *RdUtils::RdSqlColumnFloatVector(GRD_SqlStmt *stmt, uint32_t idx, uint32_t *dim) { - LOG_DEBUG("[RdUtils::RdSqlColumnFloatVector]"); if (GRD_KVApiInfo.DBSqlColumnFloatVector == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } @@ -442,24 +419,22 @@ const float *RdUtils::RdSqlColumnFloatVector(GRD_SqlStmt *stmt, uint32_t idx, ui int RdUtils::RdDbBackup(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen) { - LOG_DEBUG("[RdUtils::RdDbBackup]"); if (GRD_KVApiInfo.DBBackupApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBBackupApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBBackupApi(db, backupDbFile, encryptedKey, encryptedKeyLen)); } int RdUtils::RdDbRestore(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen) { - LOG_DEBUG("[RdUtils::RdDbRestore]"); if (GRD_KVApiInfo.DBRestoreApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBRestoreApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } return TransferGrdErrno(GRD_KVApiInfo.DBRestoreApi(db, backupDbFile, encryptedKey, encryptedKeyLen)); } @@ -470,7 +445,7 @@ int RdUtils::RdDbGetVersion(GRD_DB *db, GRD_ConfigTypeE type, int &version) GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBGetConfigApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } GRD_DbValueT value = GRD_KVApiInfo.DBGetConfigApi(db, type); version = value.value.longValue; @@ -483,7 +458,7 @@ int RdUtils::RdDbSetVersion(GRD_DB *db, GRD_ConfigTypeE type, int version) GRD_KVApiInfo = GetApiInfoInstance(); } if (GRD_KVApiInfo.DBSetConfigApi == nullptr) { - return TransferGrdErrno(GRD_INNER_ERR); + return E_NOT_SUPPORT; } GRD_DbValueT value; value.type = GRD_DB_DATATYPE_INTEGER; diff --git a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp index 0ced846d..62170e41 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp @@ -78,48 +78,27 @@ int RdbHelper::DeleteRdbStore(const std::string &dbFileName) return E_INVALID_FILE_PATH; } if (access(dbFileName.c_str(), F_OK) != 0) { - LOG_ERROR("Store to delete doesn't exist, path %{public}s", dbFileName.c_str()); + LOG_ERROR("Store to delete doesn't exist, path %{public}s", SqliteUtils::Anonymous(dbFileName).c_str()); return E_OK; // not not exist } + RdbStoreManager::GetInstance().Delete(dbFileName); - int result = remove(dbFileName.c_str()); - if (result != 0) { - LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the db file err = %{public}d", errno); - return E_REMOVE_FILE; - } + RdbSecurityManager::GetInstance().DelAllKeyFiles(dbFileName); + DeleteRdbStore(SqliteUtils::GetSlavePath(dbFileName)); - int errCode = DeleteRdFiles(dbFileName); - std::string shmFileName = dbFileName + "-shm"; - if (access(shmFileName.c_str(), F_OK) == 0) { - result = remove(shmFileName.c_str()); - if (result < 0) { - LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the shm file err = %{public}d", errno); - errCode = E_REMOVE_FILE; - } - } + RdbStoreConfig config(dbFileName); + config.SetDBType(DB_SQLITE); + int errCodeSqlite = Connection::Delete(config); - std::string walFileName = dbFileName + "-wal"; - if (access(walFileName.c_str(), F_OK) == 0) { - result = remove(walFileName.c_str()); - if (result < 0) { - LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the wal file err = %{public}d", errno); - errCode = E_REMOVE_FILE; - } - } + config.SetDBType(DB_VECTOR); + int errCodeVector = Connection::Delete(config); - std::string journalFileName = dbFileName + "-journal"; - if (access(journalFileName.c_str(), F_OK) == 0) { - result = remove(journalFileName.c_str()); - if (result < 0) { - LOG_ERROR("RdbHelper DeleteRdbStore failed to delete the journal file err = %{public}d", errno); - errCode = E_REMOVE_FILE; - } - } - RdbSecurityManager::GetInstance().DelAllKeyFiles(dbFileName); - LOG_INFO("Delete rdb store ret %{public}d, path %{public}s", errCode, dbFileName.c_str()); - DeleteRdbStore(SqliteUtils::GetSlavePath(dbFileName)); + int errCode = (errCodeSqlite == E_OK && errCodeVector == E_OK) ? E_OK : E_REMOVE_FILE; + LOG_INFO("Delete rdb store ret sqlite=%{public}d, vector=%{public}d, path %{public}s", + errCodeSqlite, errCodeVector, SqliteUtils::Anonymous(dbFileName).c_str()); return errCode; } + int RdbHelper::DeleteRdbStore(const RdbStoreConfig &config) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); @@ -128,18 +107,14 @@ int RdbHelper::DeleteRdbStore(const RdbStoreConfig &config) return E_INVALID_FILE_PATH; } if (access(dbFile.c_str(), F_OK) != 0) { - LOG_ERROR("not exist, path %{public}s", dbFile.c_str()); + LOG_ERROR("not exist, path %{public}s", SqliteUtils::Anonymous(dbFile).c_str()); return E_OK; // not not exist } RdbStoreManager::GetInstance().Delete(dbFile); - auto errCode = Connection::Delete(config); - if (errCode != E_OK) { - LOG_ERROR("delete the db file err = %{public}d", errno); - return E_REMOVE_FILE; - } + Connection::Delete(config); RdbSecurityManager::GetInstance().DelAllKeyFiles(dbFile); - LOG_INFO("Delete rdb store ret %{public}d, path %{public}s", errCode, dbFile.c_str()); - return errCode; + LOG_INFO("Delete rdb store, path %{public}s", SqliteUtils::Anonymous(dbFile).c_str()); + return E_OK; } } // namespace NativeRdb } // namespace OHOS 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 69899af6..f57884e0 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp @@ -481,12 +481,22 @@ bool RdbSecurityManager::LoadSecretKeyFromDisk(const std::string &keyPath, RdbSe } } + auto size = content.size(); + std::size_t offset = 0; auto iter = content.begin(); + if (offset + 1 >= static_cast(size)) { + return false; + } keyData.distributed = *iter; iter++; + offset++; std::vector createTime; - for (int i = 0; i < static_cast(sizeof(time_t) / sizeof(uint8_t)); i++) { + if (offset + static_cast(sizeof(time_t) / sizeof(uint8_t)) >= size) { + return false; + } + offset += sizeof(time_t) / sizeof(uint8_t); + for (std::size_t i = 0; i < sizeof(time_t) / sizeof(uint8_t); i++) { createTime.push_back(*iter); iter++; } @@ -495,6 +505,10 @@ bool RdbSecurityManager::LoadSecretKeyFromDisk(const std::string &keyPath, RdbSe keyData.timeValue = *reinterpret_cast(&createTime[0]); } + if (offset + AEAD_LEN >= static_cast(size)) { + return false; + } + offset = size; keyData.secretKey.insert(keyData.secretKey.end(), iter, content.end()); return true; @@ -598,15 +612,12 @@ bool RdbSecurityManager::HasRootKey() bool RdbSecurityManager::IsKeyFileEmpty(const std::string &keyFile) { - if (access(keyFile.c_str(), F_OK) != 0) { - return true; - } struct stat fileInfo; auto errCode = stat(keyFile.c_str(), &fileInfo); - if (errCode == 0 && fileInfo.st_size == 0) { + if (errCode != 0) { return true; } - return false; + return fileInfo.st_size == 0; } int32_t RdbSecurityManager::RestoreKeyFile(const std::string &dbPath, const std::vector &key) diff --git a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp index b8291009..7cb1bf23 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -254,7 +254,7 @@ int32_t RdbServiceProxy::UnSubscribe(const RdbSyncerParam ¶m, const Subscrib LOG_ERROR("observer is null."); return RDB_ERROR; } - if (DoUnSubscribe(param) != RDB_OK) { + if (DoUnSubscribe(param, option) != RDB_OK) { return RDB_ERROR; } auto name = RemoveSuffix(param.storeName_); @@ -269,13 +269,13 @@ int32_t RdbServiceProxy::UnSubscribe(const RdbSyncerParam ¶m, const Subscrib return RDB_OK; } -int32_t RdbServiceProxy::DoUnSubscribe(const RdbSyncerParam ¶m) +int32_t RdbServiceProxy::DoUnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option) { MessageParcel reply; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNSUBSCRIBE), reply, param); + int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNSUBSCRIBE), reply, param, option); if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", - status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); } return status; } @@ -592,4 +592,19 @@ int32_t RdbServiceProxy::UnlockCloudContainer(const RdbSyncerParam& param) } return status; } + +int32_t RdbServiceProxy::GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) +{ + MessageParcel reply; + int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_DEBUG_INFO), reply, param); + if (status != RDB_OK) { + LOG_ERROR("fail, status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, + param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); + } + if (!ITypesUtil::Unmarshal(reply, debugInfo)) { + LOG_ERROR("Unmarshal failed"); + status = RDB_ERROR; + } + return status; +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp index e738a8a4..dc8ad28c 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -27,6 +27,7 @@ #include "rdb_errno.h" #include "rdb_platform.h" #include "sqlite_sql_builder.h" +#include "sqlite_utils.h" namespace OHOS { using namespace Rdb; namespace NativeRdb { @@ -51,7 +52,8 @@ int RdbSqlUtils::CreateDirectory(const std::string &databaseDir) databaseDirectory = databaseDirectory + "/" + directory; if (access(databaseDirectory.c_str(), F_OK) != 0) { if (MkDir(databaseDirectory)) { - LOG_ERROR("failed to mkdir errno[%{public}d] %{public}s", errno, databaseDirectory.c_str()); + LOG_ERROR("failed to mkdir errno[%{public}d] %{public}s", errno, + SqliteUtils::Anonymous(databaseDirectory).c_str()); return E_CREATE_FOLDER_FAIL; } // Set the default ACL attribute to the database root directory to ensure that files created by the server @@ -80,8 +82,9 @@ std::pair RdbSqlUtils::GetDefaultDatabasePath(const std::strin errorCode = CreateDirectory(databaseDir); if (errorCode != E_OK) { - LOG_ERROR("failed errno[%{public}d] baseDir : %{public}s name : %{public}s customDir : %{public}s", - errno, baseDir.c_str(), name.c_str(), customDir.c_str()); + LOG_ERROR("failed errno[%{public}d] baseDir : %{public}s name : %{public}s customDir : %{public}s", errno, + SqliteUtils::Anonymous(baseDir).c_str(), SqliteUtils::Anonymous(name).c_str(), + SqliteUtils::Anonymous(customDir).c_str()); } return std::make_pair(databaseDir.append("/").append(name), errorCode); } @@ -94,8 +97,8 @@ std::string RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, cons std::string databaseDir = baseDir + "/rdb"; errorCode = CreateDirectory(databaseDir); if (errorCode != E_OK) { - LOG_ERROR( - "failed errno[%{public}d] baseDir : %{public}s name : %{public}s", errno, baseDir.c_str(), name.c_str()); + LOG_ERROR("failed errno[%{public}d] baseDir : %{public}s name : %{public}s", errno, + SqliteUtils::Anonymous(baseDir).c_str(), SqliteUtils::Anonymous(name).c_str()); } return databaseDir.append("/").append(name); } 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 e55701ff..f4ea51fb 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -31,6 +31,7 @@ #include "rdb_common.h" #include "rdb_errno.h" #include "rdb_radar_reporter.h" +#include "rdb_security_manager.h" #include "rdb_sql_statistic.h" #include "rdb_store.h" #include "rdb_trace.h" @@ -51,7 +52,6 @@ #include "raw_data_parser.h" #include "rdb_device_manager_adapter.h" #include "rdb_manager_impl.h" -#include "rdb_security_manager.h" #include "relational_store_manager.h" #include "runtime_config.h" #include "security_policy.h" @@ -77,73 +77,63 @@ static constexpr const char *BEGIN_TRANSACTION_SQL = "begin;"; static constexpr const char *COMMIT_TRANSACTION_SQL = "commit;"; static constexpr const char *ROLLBACK_TRANSACTION_SQL = "rollback;"; -void RdbStoreImpl::InitSyncerParam() +void RdbStoreImpl::InitSyncerParam(const RdbStoreConfig &config, bool created) { - syncerParam_.bundleName_ = config_.GetBundleName(); - syncerParam_.hapName_ = config_.GetModuleName(); - syncerParam_.storeName_ = config_.GetName(); - syncerParam_.customDir_ = config_.GetCustomDir(); - syncerParam_.area_ = config_.GetArea(); - syncerParam_.level_ = static_cast(config_.GetSecurityLevel()); - syncerParam_.type_ = config_.GetDistributedType(); - syncerParam_.isEncrypt_ = config_.IsEncrypt(); - syncerParam_.isAutoClean_ = config_.GetAutoClean(); - syncerParam_.isSearchable_ = config_.IsSearchable(); - syncerParam_.password_ = {}; - syncerParam_.haMode_ = config_.GetHaMode(); - syncerParam_.roleType_ = config_.GetRoleType(); + syncerParam_.bundleName_ = config.GetBundleName(); + syncerParam_.hapName_ = config.GetModuleName(); + syncerParam_.storeName_ = config.GetName(); + syncerParam_.customDir_ = config.GetCustomDir(); + syncerParam_.area_ = config.GetArea(); + syncerParam_.level_ = static_cast(config.GetSecurityLevel()); + syncerParam_.type_ = config.GetDistributedType(); + syncerParam_.isEncrypt_ = config.IsEncrypt(); + syncerParam_.isAutoClean_ = config.GetAutoClean(); + syncerParam_.isSearchable_ = config.IsSearchable(); + syncerParam_.password_ = config.GetEncryptKey(); + syncerParam_.haMode_ = config.GetHaMode(); + syncerParam_.roleType_ = config.GetRoleType(); + if (created) { + syncerParam_.infos_ = Connection::Collect(config); + } } int RdbStoreImpl::InnerOpen() { - LOG_DEBUG("open %{public}s.", SqliteUtils::Anonymous(path_).c_str()); + isOpen_ = true; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - pool_ = TaskExecutor::GetInstance().GetExecutor(); - - if (config_.GetRoleType() == OWNER) { - AfterOpen(config_); + if (isReadOnly_) { + return E_OK; } + AfterOpen(syncerParam_); int errCode = RegisterDataChangeCallback(); if (errCode != E_OK) { LOG_ERROR("RegisterCallBackObserver is failed, err is %{public}d.", errCode); } #endif - isOpen_ = true; return E_OK; } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - -void RdbStoreImpl::AfterOpen(const RdbStoreConfig &config) +void RdbStoreImpl::AfterOpen(const RdbParam ¶m, int32_t retry) { - std::vector key = config.GetEncryptKey(); - syncerParam_.password_ = std::vector(key.data(), key.data() + key.size()); - key.assign(key.size(), 0); - if (pool_ != nullptr) { - auto param = syncerParam_; - auto retry = 0; - UploadSchema(param, retry); - } -} - -void RdbStoreImpl::UploadSchema(const DistributedRdb::RdbSyncerParam ¶m, uint32_t retry) -{ - auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + auto [err, service] = RdbMgr::GetInstance().GetRdbService(param); if (err == E_NOT_SUPPORT) { return; } if (err != E_OK || service == nullptr) { - LOG_ERROR("GetRdbService failed, err: %{public}d, storeName: %{public}s.", err, param.storeName_.c_str()); + LOG_ERROR("GetRdbService failed, err: %{public}d, storeName: %{public}s.", err, + SqliteUtils::Anonymous(param.storeName_).c_str()); auto pool = TaskExecutor::GetInstance().GetExecutor(); if (err == E_SERVICE_NOT_FOUND && pool != nullptr && retry++ < MAX_RETRY_TIMES) { - pool->Schedule(std::chrono::seconds(RETRY_INTERVAL), [param, retry]() { UploadSchema(param, retry); }); + pool->Schedule(std::chrono::seconds(RETRY_INTERVAL), [param, retry]() { AfterOpen(param, retry); }); } return; } err = service->AfterOpen(param); if (err != E_OK) { - LOG_ERROR("AfterOpen failed, err: %{public}d, storeName: %{public}s.", err, param.storeName_.c_str()); + LOG_ERROR("AfterOpen failed, err: %{public}d, storeName: %{public}s.", err, + SqliteUtils::Anonymous(param.storeName_).c_str()); } } @@ -288,7 +278,7 @@ RdbStore::ModifyTime RdbStoreImpl::GetModifyTimeByRowId(const std::string &logTa int RdbStoreImpl::CleanDirtyData(const std::string &table, uint64_t cursor) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } auto connection = connectionPool_->AcquireConnection(false); @@ -301,42 +291,47 @@ int RdbStoreImpl::CleanDirtyData(const std::string &table, uint64_t cursor) #endif RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config) - : config_(config), isOpen_(false), isReadOnly_(config.IsReadOnly()), isMemoryRdb_(config.IsMemoryRdb()), - isEncrypt_(config.IsEncrypt()), path_(config.GetPath()), name_(config.GetName()), - fileType_(config.GetDatabaseFileType()), connectionPool_(nullptr), rebuild_(RebuiltType::NONE), - slaveStatus_(SlaveStatus::UNDEFINED) + : isMemoryRdb_(config.IsMemoryRdb()), config_(config), name_(config.GetName()), + fileType_(config.GetDatabaseFileType()) { + path_ = (config.GetRoleType() == VISITOR) ? config.GetVisitorDir() : config.GetPath(); + isReadOnly_ = config.IsReadOnly() || config.GetRoleType() == VISITOR; } RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config, int &errCode) - : config_(config), isReadOnly_(config.IsReadOnly()), isMemoryRdb_(config.IsMemoryRdb()), - isEncrypt_(config.IsEncrypt()), name_(config.GetName()), fileType_(config.GetDatabaseFileType()), - rebuild_(RebuiltType::NONE), slaveStatus_(SlaveStatus::UNDEFINED) + : isMemoryRdb_(config.IsMemoryRdb()), config_(config), name_(config.GetName()), + fileType_(config.GetDatabaseFileType()) { + isReadOnly_ = config.IsReadOnly() || config.GetRoleType() == VISITOR; path_ = (config.GetRoleType() == VISITOR) ? config.GetVisitorDir() : config.GetPath(); + bool created = access(path_.c_str(), F_OK) != 0; connectionPool_ = ConnectionPool::Create(config_, errCode); - InitSyncerParam(); - if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild() && !config.IsReadOnly()) { - LOG_ERROR("database corrupt, rebuild database %{public}s", name_.c_str()); + if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild() && !isReadOnly_) { + LOG_ERROR("database corrupt, rebuild database %{public}s", SqliteUtils::Anonymous(name_).c_str()); #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - auto [err, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); + RdbParam param; + param.bundleName_ = config_.GetBundleName(); + param.storeName_ = config_.GetName(); + auto [err, service] = RdbMgr::GetInstance().GetRdbService(param); if (service != nullptr) { - service->Disable(syncerParam_); + service->Disable(param); } #endif std::tie(rebuild_, connectionPool_) = ConnectionPool::HandleDataCorruption(config_, errCode); + created = true; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) if (service != nullptr) { - service->Enable(syncerParam_); + service->Enable(param); } #endif } if (connectionPool_ == nullptr || errCode != E_OK) { connectionPool_ = nullptr; - LOG_ERROR("Create connPool failed, err is %{public}d, path:%{public}s", errCode, path_.c_str()); + LOG_ERROR("Create connPool failed, err is %{public}d, path:%{public}s", errCode, + SqliteUtils::Anonymous(path_).c_str()); return; } - + InitSyncerParam(config_, created); InnerOpen(); } @@ -345,16 +340,6 @@ RdbStoreImpl::~RdbStoreImpl() connectionPool_ = nullptr; } -void RdbStoreImpl::RemoveDbFiles(std::string &path) -{ - SqliteUtils::DeleteFile(path); - SqliteUtils::DeleteFile(path + "-shm"); - SqliteUtils::DeleteFile(path + "-wal"); - SqliteUtils::DeleteFile(path + "-journal"); - SqliteUtils::DeleteFile(path + "-slaveFailure"); - SqliteUtils::DeleteFile(path + "-syncInterrupt"); -} - const RdbStoreConfig &RdbStoreImpl::GetConfig() { return config_; @@ -374,7 +359,7 @@ int RdbStoreImpl::BatchInsert(int64_t &outInsertNum, const std::string &table, c int RdbStoreImpl::BatchInsertEntry(int64_t &outInsertNum, const std::string &table, const std::vector &values) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } if (values.empty()) { @@ -475,7 +460,7 @@ int RdbStoreImpl::InsertWithConflictResolutionEntry(int64_t &outRowId, const std { SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -589,7 +574,7 @@ int RdbStoreImpl::UpdateWithConflictResolutionEntry(int &changedRows, const std: { SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -660,7 +645,7 @@ int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std:: const std::vector &bindArgs) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -723,7 +708,7 @@ std::pair> RdbStoreImpl::QuerySharingResourc if (config_.GetDBType() == DB_VECTOR) { return { E_NOT_SUPPORT, nullptr }; } - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return { errCode, nullptr }; } @@ -744,7 +729,7 @@ std::shared_ptr RdbStoreImpl::RemoteQuery(const std::string &device, } std::vector selectionArgs = predicates.GetWhereArgs(); std::string sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); - auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [err, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (err == E_NOT_SUPPORT) { errCode = err; return nullptr; @@ -841,7 +826,7 @@ int RdbStoreImpl::ExecuteSqlEntry(const std::string &sql, const std::vector(version)) { LOG_INFO("db:%{public}s exe DDL schema<%{public}" PRIi64 "->%{public}" PRIi64 "> sql:%{public}s.", - name_.c_str(), vSchema_, static_cast(version), sql.c_str()); + SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), sql.c_str()); vSchema_ = version; errCode = connectionPool_->RestartReaders(); } @@ -915,7 +900,7 @@ std::pair RdbStoreImpl::HandleDifferentSqlTypes(std::share auto [err, version] = statement->ExecuteForValue(); if (vSchema_ < static_cast(version)) { LOG_INFO("db:%{public}s exe DDL schema<%{public}" PRIi64 "->%{public}" PRIi64 "> sql:%{public}s.", - name_.c_str(), vSchema_, static_cast(version), sql.c_str()); + SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), sql.c_str()); vSchema_ = version; errCode = connectionPool_->RestartReaders(); } @@ -927,7 +912,7 @@ std::pair RdbStoreImpl::ExecuteEntry(const std::string &sq const std::vector &bindArgs, int64_t trxId) { ValueObject object; - if (config_.IsReadOnly()) { + if (isReadOnly_) { return { E_NOT_SUPPORT, object }; } @@ -1004,7 +989,7 @@ int RdbStoreImpl::ExecuteAndGetString( int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } auto [errCode, statement] = GetStatement(sql, false); @@ -1022,7 +1007,7 @@ int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::stri int RdbStoreImpl::ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } auto [errCode, statement] = GetStatement(sql, false); @@ -1078,27 +1063,13 @@ int RdbStoreImpl::GetSlaveName(const std::string &path, std::string &backupFileP return E_OK; } -int RdbStoreImpl::ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs) -{ - auto [errCode, statement] = BeginExecuteSql(sql); - if (statement == nullptr) { - return errCode; - } - - errCode = statement->Execute(bindArgs); - if (errCode != E_OK) { - LOG_ERROR("ExecuteSql ATTACH_BACKUP_SQL error %{public}d", errCode); - } - return errCode; -} - /** * Backup a database from a specified encrypted or unencrypted database file. */ int RdbStoreImpl::Backup(const std::string &databasePath, const std::vector &destEncryptKey) { - LOG_INFO("Backup db: %{public}s.", config_.GetName().c_str()); - if ((config_.GetRoleType() == VISITOR)) { + LOG_INFO("Backup db: %{public}s.", SqliteUtils::Anonymous(config_.GetName()).c_str()); + if (isReadOnly_) { return E_NOT_SUPPORT; } std::string backupFilePath; @@ -1111,6 +1082,9 @@ int RdbStoreImpl::Backup(const std::string &databasePath, const std::vector &destEncryptKey) { - if (config_.GetRoleType() == VISITOR) { + if (isReadOnly_) { return E_NOT_SUPPORT; - } else if (config_.GetDBType() == DB_VECTOR) { + } + + if (config_.GetDBType() == DB_VECTOR) { + if (config_.IsEncrypt()) { + return E_NOT_SUPPORT; + } + auto conn = connectionPool_->AcquireConnection(false); if (conn == nullptr) { return E_BASE; } - if (isEncrypt_) { - return E_NOT_SUPPORT; - } + return conn->Backup(databasePath, {}, false, slaveStatus_); } + if (config_.GetHaMode() != HAMode::SINGLE && SqliteUtils::IsSlaveDbName(databasePath)) { auto conn = connectionPool_->AcquireConnection(false); return conn == nullptr ? E_BASE : conn->Backup(databasePath, {}, false, slaveStatus_); } - auto [errCode, statement] = GetStatement(GlobalExpr::CIPHER_DEFAULT_ATTACH_HMAC_ALGO, true); - if (statement == nullptr) { - return E_BASE; + + auto [errCode, statement] = CreateWriteableStmt(GlobalExpr::CIPHER_DEFAULT_ATTACH_HMAC_ALGO); + if (errCode != E_OK || statement == nullptr) { + return errCode; } std::vector bindArgs; bindArgs.emplace_back(databasePath); - if (!destEncryptKey.empty() && !isEncrypt_) { + if (!destEncryptKey.empty() && !config_.IsEncrypt()) { bindArgs.emplace_back(destEncryptKey); statement->Execute(); -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - } else if (isEncrypt_) { + } else if (config_.IsEncrypt()) { std::vector key = config_.GetEncryptKey(); bindArgs.emplace_back(key); key.assign(key.size(), 0); statement->Execute(); -#endif } else { - std::string str = ""; - bindArgs.emplace_back(str); + bindArgs.emplace_back(""); } errCode = statement->Prepare(GlobalExpr::ATTACH_BACKUP_SQL); errCode = statement->Execute(bindArgs); if (errCode != E_OK) { return errCode; } + errCode = statement->Prepare(GlobalExpr::PRAGMA_BACKUP_JOUR_MODE_WAL); + errCode = statement->Execute(); + if (errCode != E_OK) { + return errCode; + } errCode = statement->Prepare(GlobalExpr::EXPORT_SQL); int ret = statement->Execute(); errCode = statement->Prepare(GlobalExpr::DETACH_BACKUP_SQL); @@ -1279,9 +1268,8 @@ int RdbStoreImpl::AttachInner( std::pair RdbStoreImpl::Attach( const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly()) || - config_.GetHaMode() != HAMode::SINGLE) { - return {E_NOT_SUPPORT, 0}; + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR) || config_.GetHaMode() != HAMode::SINGLE) { + return { E_NOT_SUPPORT, 0 }; } std::string dbPath; int err = SqliteGlobalConfig::GetDbPath(config, dbPath); @@ -1290,7 +1278,7 @@ std::pair RdbStoreImpl::Attach( } // encrypted databases are not supported to attach a non encrypted database. - if (!config.IsEncrypt() && isEncrypt_) { + if (!config.IsEncrypt() && config_.IsEncrypt()) { return { E_NOT_SUPPORT, 0 }; } @@ -1315,7 +1303,8 @@ std::pair RdbStoreImpl::Attach( } else if (err != E_OK) { LOG_ERROR("failed, errCode[%{public}d] fileName[%{public}s] attachName[%{public}s] attach fileName" "[%{public}s]", - err, config_.GetName().c_str(), attachName.c_str(), config.GetName().c_str()); + err, SqliteUtils::Anonymous(config_.GetName()).c_str(), attachName.c_str(), + SqliteUtils::Anonymous(config.GetName()).c_str()); return { err, 0 }; } if (!attachedInfo_.Insert(attachName, dbPath)) { @@ -1326,7 +1315,7 @@ std::pair RdbStoreImpl::Attach( std::pair RdbStoreImpl::Detach(const std::string &attachName, int32_t waitTime) { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return { E_NOT_SUPPORT, 0 }; } if (!attachedInfo_.Contains(attachName)) { @@ -1348,7 +1337,7 @@ std::pair RdbStoreImpl::Detach(const std::string &attachName, errCode = statement->Execute(bindArgs); if (errCode != E_OK) { LOG_ERROR("failed, errCode[%{public}d] fileName[%{public}s] attachName[%{public}s] attach", errCode, - config_.GetName().c_str(), attachName.c_str()); + SqliteUtils::Anonymous(config_.GetName()).c_str(), attachName.c_str()); return { errCode, 0 }; } @@ -1370,8 +1359,7 @@ std::pair RdbStoreImpl::Detach(const std::string &attachName, */ int RdbStoreImpl::GetVersion(int &version) { - bool isRead = (config_.IsReadOnly()) || (config_.GetRoleType() == VISITOR); - auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, isRead); + auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, isReadOnly_); if (statement == nullptr) { return errCode; } @@ -1389,7 +1377,7 @@ int RdbStoreImpl::GetVersion(int &version) */ int RdbStoreImpl::SetVersion(int version) { - if ((config_.GetRoleType() == VISITOR) || (config_.IsReadOnly())) { + if ((config_.GetRoleType() == VISITOR) || isReadOnly_) { return E_NOT_SUPPORT; } std::string sql = std::string(GlobalExpr::PRAGMA_VERSION) + " = " + std::to_string(version); @@ -1406,7 +1394,7 @@ int RdbStoreImpl::BeginTransaction() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } // size + 1 means the number of transactions in process @@ -1419,7 +1407,8 @@ int RdbStoreImpl::BeginTransaction() errCode = statement->Execute(); if (errCode != E_OK) { LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + return errCode; } connectionPool_->SetInTransaction(true); @@ -1427,7 +1416,7 @@ int RdbStoreImpl::BeginTransaction() // 1 means the number of transactions in process if (transactionId > 1) { LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); } return E_OK; @@ -1436,7 +1425,7 @@ int RdbStoreImpl::BeginTransaction() std::pair RdbStoreImpl::BeginTrans() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if (!config_.IsVector() || config_.IsReadOnly()) { + if (!config_.IsVector() || isReadOnly_) { return {E_NOT_SUPPORT, 0}; } @@ -1444,7 +1433,8 @@ std::pair RdbStoreImpl::BeginTrans() int64_t tmpTrxId = 0; auto [errCode, connection] = connectionPool_->CreateConnection(false); if (connection == nullptr) { - LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); + LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", + SqliteUtils::Anonymous(name_).c_str(), time); return {errCode, 0}; } tmpTrxId = newTrxId_.fetch_add(1); @@ -1463,13 +1453,14 @@ int RdbStoreImpl::RollBack() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } size_t transactionId = connectionPool_->GetTransactionStack().size(); if (connectionPool_->GetTransactionStack().empty()) { - LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId, name_.c_str()); + LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId, + SqliteUtils::Anonymous(name_).c_str()); return E_NO_TRANSACTION_IN_SESSION; } BaseTransaction transaction = connectionPool_->GetTransactionStack().top(); @@ -1480,13 +1471,14 @@ int RdbStoreImpl::RollBack() auto [errCode, statement] = GetStatement(transaction.GetRollbackStr()); if (statement == nullptr) { // size + 1 means the number of transactions in process - LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId + 1, name_.c_str()); + LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId + 1, + SqliteUtils::Anonymous(name_).c_str()); return E_DATABASE_BUSY; } errCode = statement->Execute(); if (errCode != E_OK) { LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); return errCode; } if (connectionPool_->GetTransactionStack().empty()) { @@ -1495,7 +1487,7 @@ int RdbStoreImpl::RollBack() // 1 means the number of transactions in process if (transactionId > 1) { LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); } return E_OK; } @@ -1503,7 +1495,7 @@ int RdbStoreImpl::RollBack() int RdbStoreImpl::ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute, const std::vector &bindArgs) { - if ((!config_.IsVector()) || (config_.IsReadOnly())) { + if ((!config_.IsVector()) || isReadOnly_) { return E_NOT_SUPPORT; } if (trxId == 0) { @@ -1518,7 +1510,8 @@ int RdbStoreImpl::ExecuteByTrxId(const std::string &sql, int64_t trxId, bool clo auto result = trxConnMap_.Find(trxId); auto connection = result.second; if (connection == nullptr) { - LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); + LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", + SqliteUtils::Anonymous(name_).c_str(), time); return E_ERROR; } auto [ret, statement] = GetStatement(sql, connection); @@ -1527,9 +1520,8 @@ int RdbStoreImpl::ExecuteByTrxId(const std::string &sql, int64_t trxId, bool clo } ret = statement->Execute(bindArgs); if (ret != E_OK) { - LOG_ERROR( - "transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode: %{public}d" PRIu64, trxId, - name_.c_str(), ret); + LOG_ERROR("transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode: %{public}d" PRIu64, trxId, + SqliteUtils::Anonymous(name_).c_str(), ret); trxConnMap_.Erase(trxId); return ret; } @@ -1552,7 +1544,7 @@ int RdbStoreImpl::Commit() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } size_t transactionId = connectionPool_->GetTransactionStack().size(); @@ -1564,25 +1556,27 @@ int RdbStoreImpl::Commit() std::string sqlStr = transaction.GetCommitStr(); if (sqlStr.size() <= 1) { LOG_WARN("id: %{public}zu, storeName: %{public}s, sql: %{public}s", - transactionId, name_.c_str(), sqlStr.c_str()); + transactionId, SqliteUtils::Anonymous(name_).c_str(), sqlStr.c_str()); connectionPool_->GetTransactionStack().pop(); return E_OK; } auto [errCode, statement] = GetStatement(sqlStr); if (statement == nullptr) { - LOG_ERROR("id: %{public}zu, storeName: %{public}s, statement error", transactionId, name_.c_str()); + LOG_ERROR("id: %{public}zu, storeName: %{public}s, statement error", transactionId, + SqliteUtils::Anonymous(name_).c_str()); return E_DATABASE_BUSY; } errCode = statement->Execute(); if (errCode != E_OK) { LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); return errCode; } connectionPool_->SetInTransaction(false); // 1 means the number of transactions in process if (transactionId > 1) { - LOG_WARN("id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, name_.c_str(), errCode); + LOG_WARN("id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); } connectionPool_->GetTransactionStack().pop(); return E_OK; @@ -1596,7 +1590,7 @@ int RdbStoreImpl::Commit(int64_t trxId) bool RdbStoreImpl::IsInTransaction() { - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR)) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return false; } return connectionPool_->IsInTransaction(); @@ -1690,12 +1684,13 @@ void RdbStoreImpl::DoCloudSync(const std::string &table) return; } } - if (pool_ == nullptr) { + auto pool = TaskExecutor::GetInstance().GetExecutor(); + if (pool == nullptr) { return; } auto interval = std::chrono::duration_cast(std::chrono::milliseconds(INTERVAL)); - pool_->Schedule(interval, [this]() { + pool->Schedule(interval, [this]() { std::shared_ptr> ptr; { std::lock_guard lock(mutex_); @@ -1758,8 +1753,8 @@ int RdbStoreImpl::GetDestPath(const std::string &backupPath, std::string &destPa int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector &newKey) { - LOG_INFO("Restore db: %{public}s.", config_.GetName().c_str()); - if (config_.IsReadOnly()) { + LOG_INFO("Restore db: %{public}s.", SqliteUtils::Anonymous(config_.GetName()).c_str()); + if (isReadOnly_) { return E_NOT_SUPPORT; } @@ -1788,10 +1783,15 @@ int RdbStoreImpl::Restore(const std::string &backupPath, const std::vectorEnable(syncerParam_); + if (errCode == E_OK) { + auto syncerParam = syncerParam_; + syncerParam.infos_ = Connection::Collect(config_); + service->AfterOpen(syncerParam); + } } #endif if (errCode == E_OK) { - ReportDbRestoreSuccessEvent(); + RdbFaultHiViewReporter::ReportRestore(RdbFaultHiViewReporter::Create(config_, E_OK)); rebuild_ = RebuiltType::NONE; } if (!cloudTables_.empty()) { @@ -1800,31 +1800,6 @@ int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector(config_.GetSecurityLevel()); - eventInfo.pathArea = static_cast(config_.GetArea()); - eventInfo.encryptStatus = static_cast(config_.IsEncrypt()); - eventInfo.integrityCheck = static_cast(config_.GetIntegrityCheck()); - eventInfo.errorCode = 0; // Rdb Restore Success - eventInfo.systemErrorNo = 0; - eventInfo.errorOccurTime = time(nullptr); - std::string dbPath; - if (SqliteGlobalConfig::GetDbPath(config_, dbPath) == E_OK && access(dbPath.c_str(), F_OK) == 0) { - eventInfo.dbFileStatRet = stat(dbPath.c_str(), &eventInfo.dbFileStat); - std::string walPath = dbPath + "-wal"; - eventInfo.walFileStatRet = stat(walPath.c_str(), &eventInfo.walFileStat); - } else { - eventInfo.dbFileStatRet = -1; - eventInfo.walFileStatRet = -1; - } - RdbFaultHiViewReporter::ReportRdbCorruptedFault(eventInfo); -} /** * Queries data in the database based on specified conditions. */ @@ -1848,14 +1823,14 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i const DistributedRdb::DistributedConfig &distributedConfig) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if (config_.GetDBType() == DB_VECTOR || config_.IsReadOnly()) { + if (config_.GetDBType() == DB_VECTOR || isReadOnly_) { return E_NOT_SUPPORT; } if (tables.empty()) { LOG_WARN("The distributed tables to be set is empty."); return E_OK; } - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; } @@ -1946,7 +1921,7 @@ int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predica int RdbStoreImpl::InnerSync(const DistributedRdb::RdbService::Option &option, const DistributedRdb::PredicatesMemo &predicates, const RdbStore::AsyncDetail &async) { - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode == E_NOT_SUPPORT) { return errCode; } @@ -2027,14 +2002,14 @@ int32_t RdbStoreImpl::SubscribeLocalDetail(const SubscribeOption &option, int32_t errCode = connection->Subscribe(option.event, observer); if (errCode != E_OK) { LOG_ERROR("subscribe local detail observer failed. db name:%{public}s errCode:%{public}" PRId32, - config_.GetName().c_str(), errCode); + SqliteUtils::Anonymous(config_.GetName()).c_str(), errCode); } return errCode; } int RdbStoreImpl::SubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) { - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; } @@ -2160,14 +2135,14 @@ int32_t RdbStoreImpl::UnsubscribeLocalDetail(const SubscribeOption& option, int32_t errCode = connection->Unsubscribe(option.event, observer); if (errCode != E_OK) { LOG_ERROR("unsubscribe local detail observer failed. db name:%{public}s errCode:%{public}" PRId32, - config_.GetName().c_str(), errCode); + SqliteUtils::Anonymous(config_.GetName()).c_str(), errCode); } return errCode; } int RdbStoreImpl::UnSubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) { - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; } @@ -2235,7 +2210,7 @@ int RdbStoreImpl::Notify(const std::string &event) int RdbStoreImpl::SetSearchable(bool isSearchable) { - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK || service == nullptr) { LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); return errCode; @@ -2248,7 +2223,7 @@ int RdbStoreImpl::RegisterAutoSyncCallback(std::shared_ptrSetExecutorPool(pool_); + delayNotifier_->SetExecutorPool(TaskExecutor::GetInstance().GetExecutor()); delayNotifier_->SetTask([param = syncerParam_] (const DistributedRdb::RdbChangedData& rdbChangedData, const RdbNotifyConfig& rdbNotifyConfig) -> int { - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(param); if (errCode == E_NOT_SUPPORT) { return errCode; } @@ -2297,7 +2272,7 @@ int RdbStoreImpl::RegisterDataChangeCallback() return E_OK; } - if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { + if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { return E_NOT_SUPPORT; } InitDelayNotifier(); @@ -2395,7 +2370,7 @@ std::pair RdbStoreImpl::LockCloudContainer() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); RdbRadar ret(Scene::SCENE_SYNC, __FUNCTION__, config_.GetBundleName()); - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode == E_NOT_SUPPORT) { LOG_ERROR("not support"); return { errCode, 0 }; @@ -2416,7 +2391,7 @@ int32_t RdbStoreImpl::UnlockCloudContainer() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); RdbRadar ret(Scene::SCENE_SYNC, __FUNCTION__, config_.GetBundleName()); - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode == E_NOT_SUPPORT) { LOG_ERROR("not support"); return errCode; @@ -2434,6 +2409,18 @@ int32_t RdbStoreImpl::UnlockCloudContainer() } #endif +std::pair> RdbStoreImpl::CreateWriteableStmt(const std::string &sql) +{ + auto config = config_; + config.SetHaMode(HAMode::SINGLE); + auto [errCode, conn] = Connection::Create(config, true); + if (errCode != E_OK || conn == nullptr) { + LOG_ERROR("create connection failed, err:%{public}d", errCode); + return { errCode, nullptr }; + } + return conn->CreateStatement(sql, conn); +} + std::pair> RdbStoreImpl::GetStatement( const std::string &sql, std::shared_ptr conn) const { @@ -2498,12 +2485,13 @@ bool RdbStoreImpl::TryGetMasterSlaveBackupPath(const std::string &srcPath, std:: bool RdbStoreImpl::IsSlaveDiffFromMaster() const { std::string failureFlagFile = config_.GetPath() + "-slaveFailure"; - return access(failureFlagFile.c_str(), F_OK) == 0; + std::string slaveDbPath = SqliteUtils::GetSlavePath(config_.GetPath()); + return access(failureFlagFile.c_str(), F_OK) == 0 || access(slaveDbPath.c_str(), F_OK) != 0; } int32_t RdbStoreImpl::ExchangeSlaverToMaster() { - if (config_.GetRoleType() == VISITOR || config_.IsReadOnly()) { + if (isReadOnly_) { return E_OK; } auto conn = connectionPool_->AcquireConnection(false); @@ -2512,12 +2500,15 @@ int32_t RdbStoreImpl::ExchangeSlaverToMaster() } auto strategy = conn->GenerateExchangeStrategy(slaveStatus_); if (strategy != ExchangeStrategy::NOT_HANDLE) { - LOG_WARN("exchange st:%{public}d, %{public}s,", strategy, config_.GetName().c_str()); + LOG_WARN("exchange st:%{public}d, %{public}s,", strategy, SqliteUtils::Anonymous(config_.GetName()).c_str()); } int ret = E_OK; if (strategy == ExchangeStrategy::RESTORE) { - ret = conn->Restore({}, {}, slaveStatus_); + conn = nullptr; + // disable is required before restore + ret = Restore({}, {}); } else if (strategy == ExchangeStrategy::BACKUP) { + // async backup ret = conn->Backup({}, {}, true, slaveStatus_); } return ret; diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index c8c65e17..7a069b47 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -35,10 +35,13 @@ #endif #include "sqlite_utils.h" #include "string_utils.h" +#include "rdb_fault_hiview_reporter.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; +__attribute__((used)) +const bool RdbStoreManager::regCollector_ = RdbFaultHiViewReporter::RegCollector(RdbStoreManager::Collector); RdbStoreManager &RdbStoreManager::GetInstance() { static RdbStoreManager manager; @@ -83,28 +86,25 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con if (config.GetRoleType() == OWNER && !config.IsReadOnly()) { errCode = SetSecurityLabel(config); if (errCode != E_OK) { - LOG_ERROR("fail, storeName:%{public}s security %{public}d errCode:%{public}d", config.GetName().c_str(), - config.GetSecurityLevel(), errCode); + LOG_ERROR("fail, storeName:%{public}s security %{public}d errCode:%{public}d", + SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetSecurityLevel(), errCode); return nullptr; } if (config.IsVector()) { storeCache_[path] = rdbStore; return rdbStore; } + (void)rdbStore->ExchangeSlaverToMaster(); errCode = ProcessOpenCallback(*rdbStore, config, version, openCallback); if (errCode != E_OK) { LOG_ERROR("fail, storeName:%{public}s path:%{public}s ProcessOpenCallback errCode:%{public}d", - config.GetName().c_str(), config.GetPath().c_str(), errCode); + SqliteUtils::Anonymous(config.GetName()).c_str(), + SqliteUtils::Anonymous(config.GetPath()).c_str(), errCode); return nullptr; } } storeCache_[path] = rdbStore; - errCode = rdbStore->ExchangeSlaverToMaster(); - if (errCode != E_OK) { - LOG_ERROR("fail, name:%{public}s err:%{public}d", config.GetName().c_str(), errCode); - return nullptr; - } return rdbStore; } @@ -113,11 +113,11 @@ bool RdbStoreManager::IsConfigInvalidChanged(const std::string &path, const RdbS Param param = GetSyncParam(config); Param tempParam; if (bundleName_.empty()) { - LOG_WARN("Config has no bundleName, path: %{public}s", path.c_str()); + LOG_WARN("Config has no bundleName, path: %{public}s", SqliteUtils::Anonymous(path).c_str()); return false; } if (!configCache_.Get(path, tempParam)) { - LOG_WARN("Not found config cache, path: %{public}s", path.c_str()); + LOG_WARN("Not found config cache, path: %{public}s", SqliteUtils::Anonymous(path).c_str()); tempParam = param; if (GetParamFromService(tempParam) == E_OK) { configCache_.Set(path, tempParam); @@ -130,8 +130,8 @@ bool RdbStoreManager::IsConfigInvalidChanged(const std::string &path, const RdbS tempParam.isEncrypt_ != param.isEncrypt_) { LOG_ERROR("Store config invalid change, storeName %{public}s, securitylevel: %{public}d -> %{public}d, " "area: %{public}d -> %{public}d, isEncrypt: %{public}d -> %{public}d", - path.c_str(), tempParam.level_, param.level_, tempParam.area_, param.area_, tempParam.isEncrypt_, - param.isEncrypt_); + SqliteUtils::Anonymous(path).c_str(), tempParam.level_, param.level_, tempParam.area_, param.area_, + tempParam.isEncrypt_, param.isEncrypt_); return true; } return false; @@ -270,5 +270,25 @@ int RdbStoreManager::SetSecurityLabel(const RdbStoreConfig &config) #endif return E_OK; } + +std::map RdbStoreManager::Collector(const RdbStoreConfig &config) +{ + std::map debugInfos; +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) + Param param = GetSyncParam(config); + auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + if (err != E_OK || service == nullptr) { + LOG_DEBUG("GetRdbService failed, err is %{public}d.", err); + return std::map(); + } + err = service->GetDebugInfo(param, debugInfos); + if (err != E_OK) { + LOG_ERROR("GetDebugInfo failed, storeName:%{public}s, err = %{public}d", + SqliteUtils::Anonymous(param.storeName_).c_str(), err); + return std::map(); + } +#endif + return debugInfos; +} } // namespace NativeRdb } // namespace OHOS 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 45c7169c..b974052b 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp @@ -20,14 +20,14 @@ bool Marshalling(const SyncerParam &input, MessageParcel &data) { return ITypesUtil::Marshal(data, input.bundleName_, input.hapName_, input.storeName_, input.area_, input.level_, input.type_, input.isEncrypt_, input.password_, input.customDir_, input.isAutoClean_, - input.isSearchable_, input.haMode_); + input.isSearchable_, input.haMode_, input.infos_); } template<> bool Unmarshalling(SyncerParam &output, MessageParcel &data) { return ITypesUtil::Unmarshal(data, output.bundleName_, output.hapName_, output.storeName_, output.area_, output.level_, output.type_, output.isEncrypt_, output.password_, output.customDir_, output.isAutoClean_, - output.isSearchable_, output.haMode_); + output.isSearchable_, output.haMode_, output.infos_); } template<> @@ -217,7 +217,7 @@ bool Unmarshalling(Reference &output, MessageParcel &data) template<> bool Marshalling(const BigInt& input, MessageParcel& data) { - return ITypesUtil::Marshal(data, input.Sign(), input.Value()); + return Marshal(data, input.Sign(), input.Value()); } template<> @@ -225,10 +225,20 @@ bool Unmarshalling(BigInt& output, MessageParcel& data) { int32_t sign = 0; std::vector value; - if (!ITypesUtil::Unmarshal(data, sign, value)) { + if (!Unmarshal(data, sign, value)) { return false; } output = BigInt(sign, std::move(value)); return true; } +template<> +bool Marshalling(const DebugInfo &input, MessageParcel &data) +{ + return Marshal(data, input.inode_, input.mode_, input.uid_, input.gid_); +} +template<> +bool Unmarshalling(DebugInfo &output, MessageParcel &data) +{ + return Unmarshal(data, output.inode_, output.mode_, output.uid_, output.gid_); +} } \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/share_block.cpp b/relational_store/frameworks/native/rdb/src/share_block.cpp index 6a6a53b7..2d466aad 100644 --- a/relational_store/frameworks/native/rdb/src/share_block.cpp +++ b/relational_store/frameworks/native/rdb/src/share_block.cpp @@ -32,7 +32,6 @@ const int ERROR_STATUS = -1; const unsigned int SLEEP_TIME = 1000; // move to the highest 32 bits of 64 bits number const int RETRY_TIME = 50; -const unsigned int OFFSET = 32; int SeriAddRow(void *pCtx, int addedRows) { @@ -88,15 +87,6 @@ int SeriPutOther(void *pCtx, int addedRows, int column) return serializer->PutOther(addedRows, column); } -int ClearSharedBlock(AppDataFwk::SharedBlock *sharedBlock) -{ - int status = sharedBlock->Clear(); - if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { - return ERROR_STATUS; - } - return status; -} - int SharedBlockSetColumnNum(AppDataFwk::SharedBlock *sharedBlock, int columnNum) { int status = sharedBlock->SetColumnNum(columnNum); @@ -348,16 +338,5 @@ bool ResetStatement(SharedBlockInfo *info, sqlite3_stmt *stmt) } return true; } - -int64_t GetCombinedData(int startPos, int totalRows) -{ - if (startPos > totalRows) { - LOG_ERROR("startPos %{public}d > actual rows %{public}d", startPos, totalRows); - } - - auto high = static_cast(static_cast(startPos)); - auto low = static_cast(static_cast(totalRows)); - return static_cast((high << OFFSET) | low); -} } // namespace NativeRdb } // namespace OHOS \ 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 737f529a..e06f41c8 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -54,14 +54,22 @@ namespace NativeRdb { using namespace OHOS::Rdb; using namespace std::chrono; using RdbKeyFile = RdbSecurityManager::KeyFileType; - constexpr const char *INTEGRITIES[] = {nullptr, "PRAGMA quick_check", "PRAGMA integrity_check"}; +constexpr SqliteConnection::Suffix SqliteConnection::FILE_SUFFIXES[]; +constexpr const char *SqliteConnection::MERGE_ASSETS_FUNC; +constexpr const char *SqliteConnection::MERGE_ASSET_FUNC; +constexpr int SqliteConnection::DEFAULT_BUSY_TIMEOUT_MS; +constexpr int SqliteConnection::BACKUP_PAGES_PRE_STEP; // 1024 * 4 * 12800 == 50m +constexpr int SqliteConnection::BACKUP_PRE_WAIT_TIME; +constexpr uint32_t SqliteConnection::NO_ITER; __attribute__((used)) const int32_t SqliteConnection::regCreator_ = Connection::RegisterCreator(DB_SQLITE, SqliteConnection::Create); __attribute__((used)) const int32_t SqliteConnection::regRepairer_ = Connection::RegisterRepairer(DB_SQLITE, SqliteConnection::Repair); __attribute__((used)) const int32_t SqliteConnection::regDeleter_ = Connection::RegisterDeleter(DB_SQLITE, SqliteConnection::Delete); +__attribute__((used)) +const int32_t SqliteConnection::regCollector_ = Connection::RegisterCollector(DB_SQLITE, SqliteConnection::Collect); std::pair> SqliteConnection::Create(const RdbStoreConfig &config, bool isWrite) { @@ -74,15 +82,47 @@ std::pair> SqliteConnection::Create(const R int32_t SqliteConnection::Delete(const RdbStoreConfig &config) { auto path = config.GetPath(); - SqliteUtils::DeleteFile(path); - SqliteUtils::DeleteFile(path + "-shm"); - SqliteUtils::DeleteFile(path + "-wal"); - SqliteUtils::DeleteFile(path + "-journal"); - SqliteUtils::DeleteFile(path + "-slaveFailure"); - SqliteUtils::DeleteFile(path + "-syncInterrupt"); + for (auto &suffix : FILE_SUFFIXES) { + SqliteUtils::DeleteFile(path + suffix.suffix_); + } return E_OK; } +std::map SqliteConnection::Collect(const RdbStoreConfig &config) +{ + std::map collection; + std::string path; + Info info; + SqliteGlobalConfig::GetDbPath(config, path); + for (auto &suffix : FILE_SUFFIXES) { + if (suffix.debug_ == nullptr) { + continue; + } + auto file = path + suffix.suffix_; + struct stat fileStat; + if (stat(file.c_str(), &fileStat) != 0) { + continue; + } + info.inode_ = fileStat.st_ino; + info.oldInode_ = 0; + info.atime_.sec_ = fileStat.st_atime; + info.mtime_.sec_ = fileStat.st_mtime; + info.ctime_.sec_ = fileStat.st_ctime; +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) + info.atime_.nsec_ = fileStat.st_atim.tv_nsec; + info.mtime_.nsec_ = fileStat.st_mtim.tv_nsec; + info.ctime_.nsec_ = fileStat.st_ctim.tv_nsec; +#endif + info.size_ = fileStat.st_size; + info.dev_ = fileStat.st_dev; + info.mode_ = fileStat.st_mode; + info.uid_ = fileStat.st_uid; + info.gid_ = fileStat.st_gid; + collection.insert(std::pair{ suffix.debug_, info }); + } + return collection; +} + SqliteConnection::SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection) : dbHandle_(nullptr), isWriter_(isWriteConnection), isReadOnly_(false), maxVariableNumber_(0), filePath(""), config_(config) @@ -122,7 +162,7 @@ int SqliteConnection::CreateSlaveConnection(const RdbStoreConfig &config, bool i return errCode; } -RdbStoreConfig SqliteConnection::GetSlaveRdbStoreConfig(const RdbStoreConfig rdbConfig) +RdbStoreConfig SqliteConnection::GetSlaveRdbStoreConfig(const RdbStoreConfig &rdbConfig) { RdbStoreConfig rdbStoreConfig(SqliteUtils::GetSlavePath(rdbConfig.GetPath())); rdbStoreConfig.SetEncryptStatus(rdbConfig.IsEncrypt()); @@ -187,22 +227,35 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) } if (isWriter_) { + struct stat fileInfo; + if (stat(dbPath.c_str(), &fileInfo) == 0) { + LOG_INFO("open database path [%{public}s] ino[%{public}" PRIu32 + "] config is [%{public}d, %{public}d, %{public}d, %{public}d, %{public}s, %{public}s, %{public}d," + "%{public}d, %{public}d]", + SqliteUtils::Anonymous(dbPath).c_str(), static_cast(fileInfo.st_ino), config.IsEncrypt(), + config.GetArea(), config.GetHaMode(), config.GetSecurityLevel(), + SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetBundleName().c_str(), config.GetRoleType(), + config.IsReadOnly(), config.GetDBType()); + } TryCheckPoint(); ValueObject checkResult{"ok"}; auto index = static_cast(config.GetIntegrityCheck()); if (index < static_cast(sizeof(INTEGRITIES) / sizeof(INTEGRITIES[0]))) { auto sql = INTEGRITIES[index]; if (sql != nullptr) { - LOG_INFO("%{public}s : %{public}s, ", sql, config.GetName().c_str()); + LOG_INFO("%{public}s : %{public}s, ", sql, SqliteUtils::Anonymous(config.GetName()).c_str()); std::tie(errCode, checkResult) = ExecuteForValue(sql); } if (errCode == E_OK && static_cast(checkResult) != "ok") { - LOG_ERROR("%{public}s integrity check result is %{public}s, sql:%{public}s", config.GetName().c_str(), + LOG_ERROR("%{public}s integrity check result is %{public}s, sql:%{public}s", + SqliteUtils::Anonymous(config.GetName()).c_str(), static_cast(checkResult).c_str(), sql); - ReportDbCorruptedEvent(errCode, static_cast(checkResult)); + RdbFaultHiViewReporter::ReportFault( + RdbFaultHiViewReporter::Create(config, errCode, static_cast(checkResult))); } else { LOG_DEBUG("%{public}s integrity check err:%{public}d, result is %{public}s, sql:%{public}s", - config.GetName().c_str(), errCode, static_cast(checkResult).c_str(), sql); + SqliteUtils::Anonymous(config.GetName()).c_str(), errCode, + static_cast(checkResult).c_str(), sql); } } } @@ -211,39 +264,12 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) return E_OK; } -void SqliteConnection::ReportDbCorruptedEvent(int errorCode, const std::string &checkResultInfo) -{ - RdbCorruptedEvent eventInfo; - eventInfo.bundleName = config_.GetBundleName(); - eventInfo.moduleName = config_.GetModuleName(); - eventInfo.storeType = "RDB"; - eventInfo.storeName = config_.GetName(); - eventInfo.securityLevel = static_cast(config_.GetSecurityLevel()); - eventInfo.pathArea = static_cast(config_.GetArea()); - eventInfo.encryptStatus = static_cast(config_.IsEncrypt()); - eventInfo.integrityCheck = static_cast(config_.GetIntegrityCheck()); - eventInfo.errorCode = static_cast(errorCode); - eventInfo.systemErrorNo = errno; - eventInfo.appendix = checkResultInfo; - eventInfo.errorOccurTime = time(nullptr); - std::string dbPath; - if (SqliteGlobalConfig::GetDbPath(config_, dbPath) == E_OK && access(dbPath.c_str(), F_OK) == 0) { - eventInfo.dbFileStatRet = stat(dbPath.c_str(), &eventInfo.dbFileStat); - std::string walPath = dbPath + "-wal"; - eventInfo.walFileStatRet = stat(walPath.c_str(), &eventInfo.walFileStat); - } else { - eventInfo.dbFileStatRet = -1; - eventInfo.walFileStatRet = -1; - } - RdbFaultHiViewReporter::ReportRdbCorruptedFault(eventInfo); -} - int32_t SqliteConnection::OpenDatabase(const std::string &dbPath, int openFileFlags) { int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle_, openFileFlags, nullptr); if (errCode != SQLITE_OK) { LOG_ERROR("fail to open database errCode=%{public}d, dbPath=%{public}s, flags=%{public}d, errno=%{public}d", - errCode, dbPath.c_str(), openFileFlags, errno); + errCode, SqliteUtils::Anonymous(dbPath).c_str(), openFileFlags, errno); #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) auto const pos = dbPath.find_last_of("\\/"); if (pos != std::string::npos) { @@ -351,6 +377,9 @@ int SqliteConnection::Configure(const RdbStoreConfig &config, std::string &dbPat return errCode; } + // set the user version to the wal file; + SetWalFile(config); + errCode = SetJournalSizeLimit(config); if (errCode != E_OK) { return errCode; @@ -523,7 +552,8 @@ int SqliteConnection::ReSetKey(const RdbStoreConfig &config) if (!IsWriter()) { return E_OK; } - LOG_INFO("name = %{public}s, iter = %{public}d", config.GetName().c_str(), config.GetIter()); + LOG_INFO("name = %{public}s, iter = %{public}d", SqliteUtils::Anonymous(config.GetName()).c_str(), + config.GetIter()); std::vector newKey = config.GetNewEncryptKey(); int errCode = sqlite3_rekey(dbHandle_, static_cast(newKey.data()), static_cast(newKey.size())); newKey.assign(newKey.size(), 0); @@ -548,15 +578,15 @@ int SqliteConnection::SetEncrypt(const RdbStoreConfig &config) key.assign(key.size(), 0); if (errCode != E_OK) { if (!newKey.empty()) { - LOG_INFO("use new key, iter=%{public}d err=%{public}d errno=%{public}d name=%{public}s", - config.GetIter(), errCode, errno, config.GetName().c_str()); + LOG_INFO("use new key, iter=%{public}d err=%{public}d errno=%{public}d name=%{public}s", config.GetIter(), + errCode, errno, SqliteUtils::Anonymous(config.GetName()).c_str()); errCode = SetEncryptKey(newKey, config.GetIter()); } newKey.assign(newKey.size(), 0); if (errCode != E_OK) { errCode = SetServiceKey(config, errCode); LOG_ERROR("fail, iter=%{public}d err=%{public}d errno=%{public}d name=%{public}s", config.GetIter(), - errCode, errno, config.GetName().c_str()); + errCode, errno, SqliteUtils::Anonymous(config.GetName()).c_str()); return errCode; } config.ChangeEncryptKey(); @@ -704,7 +734,7 @@ int SqliteConnection::SetJournalSizeLimit(const RdbStoreConfig &config) int SqliteConnection::SetAutoCheckpoint(const RdbStoreConfig &config) { - if (isReadOnly_ || config.IsAutoCheck() == GlobalExpr::DB_AUTO_CHECK) { + if (isReadOnly_ || !config.IsAutoCheck()) { return E_OK; } @@ -726,6 +756,18 @@ int SqliteConnection::SetAutoCheckpoint(const RdbStoreConfig &config) return errCode; } +int SqliteConnection::SetWalFile(const RdbStoreConfig &config) +{ + if (!IsWriter()) { + return E_OK; + } + auto [errCode, version] = ExecuteForValue(GlobalExpr::PRAGMA_VERSION); + if (errCode != E_OK) { + return errCode; + } + return ExecuteSql(std::string(GlobalExpr::PRAGMA_VERSION) + "=?", { std::move(version) }); +} + int SqliteConnection::SetWalSyncMode(const std::string &syncMode) { std::string targetValue = SqliteGlobalConfig::GetSyncMode(); @@ -884,7 +926,12 @@ int SqliteConnection::TryCheckPoint() std::string walName = sqlite3_filename_wal(sqlite3_db_filename(dbHandle_, "main")); int fileSize = SqliteUtils::GetFileSize(walName); - if (fileSize <= GlobalExpr::DB_WAL_SIZE_LIMIT_MIN) { + if (fileSize < 0) { + LOG_ERROR("Invalid file size for WAL: %{public}s size is %{public}d", + SqliteUtils::Anonymous(walName).c_str(), fileSize); + return E_WAL_SIZE_OVER_LIMIT; + } + if (static_cast(fileSize) <= GlobalExpr::DB_WAL_SIZE_LIMIT_MIN) { return E_OK; } int errCode = sqlite3_wal_checkpoint_v2(dbHandle_, nullptr, SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr); @@ -910,8 +957,8 @@ int SqliteConnection::LimitWalSize() std::string walName = sqlite3_filename_wal(sqlite3_db_filename(dbHandle_, "main")); int fileSize = SqliteUtils::GetFileSize(walName); - if (fileSize > GlobalExpr::DB_WAL_SIZE_LIMIT_MAX) { - LOG_ERROR("the WAL file size over default limit, %{public}s size is %{public}d", + if (fileSize < 0 || static_cast(fileSize) > GlobalExpr::DB_WAL_SIZE_LIMIT_MAX) { + LOG_ERROR("The WAL file size exceeds the limit, %{public}s size is %{public}d", SqliteUtils::Anonymous(walName).c_str(), fileSize); return E_WAL_SIZE_OVER_LIMIT; } @@ -1132,10 +1179,10 @@ int32_t SqliteConnection::Backup(const std::string &databasePath, const std::vec LOG_INFO("backing up, return:%{public}s", config_.GetName().c_str()); return E_OK; } - LOG_INFO("begin backup to slave:%{public}s, isAsync:%{public}d", SqliteUtils::Anonymous(databasePath).c_str(), - isAsync); + LOG_INFO("begin backup to slave:%{public}s, isAsync:%{public}d", + SqliteUtils::Anonymous(databasePath).c_str(), isAsync); if (!isAsync) { - if (config_.GetHaMode() == HAMode::MANUAL_TRIGGER && slaveConnection_ == nullptr) { + if (slaveConnection_ == nullptr) { RdbStoreConfig rdbSlaveStoreConfig = GetSlaveRdbStoreConfig(config_); int errCode = CreateSlaveConnection(rdbSlaveStoreConfig, true, false); if (errCode != E_OK) { @@ -1193,13 +1240,13 @@ int SqliteConnection::LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHan continue; } if (access(path.c_str(), F_OK) != 0) { - LOG_ERROR("no file, errno:%{public}d %{public}s", errno, path.c_str()); + LOG_ERROR("no file, errno:%{public}d %{public}s", errno, SqliteUtils::Anonymous(path).c_str()); return E_INVALID_FILE_PATH; } err = sqlite3_load_extension(dbHandle, path.c_str(), nullptr, nullptr); if (err != SQLITE_OK) { - LOG_ERROR("load error. err=%{public}d, errno=%{public}d, errmsg:%{public}s, lib=%{public}s", - err, errno, sqlite3_errmsg(dbHandle), path.c_str()); + LOG_ERROR("load error. err=%{public}d, errno=%{public}d, errmsg:%{public}s, lib=%{public}s", err, errno, + sqlite3_errmsg(dbHandle), SqliteUtils::Anonymous(path).c_str()); break; } } @@ -1251,7 +1298,7 @@ int SqliteConnection::ExchangeSlaverToMaster(bool isRestore, SlaveStatus &curSta curStatus = SlaveStatus::BACKING_UP; auto [isReturn, err] = ExchangeVerify(isRestore); if (isReturn) { - curStatus = err == E_OK ? SlaveStatus::UNDEFINED : SlaveStatus::DB_NOT_EXITS; + curStatus = SlaveStatus::UNDEFINED; return err; } @@ -1267,56 +1314,65 @@ int SqliteConnection::ExchangeSlaverToMaster(bool isRestore, SlaveStatus &curSta do { if (!isRestore && curStatus == SlaveStatus::BACKUP_INTERRUPT) { LOG_INFO("backup slave was interrupt!"); - (void)sqlite3_backup_finish(pBackup); - (void)SqliteConnection::Delete(slaveConnection_->config_); - slaveConnection_ = nullptr; - return E_BACKUP_INTERRUPT; + rc = E_BACKUP_INTERRUPT; + break; } rc = sqlite3_backup_step(pBackup, BACKUP_PAGES_PRE_STEP); - LOG_INFO("backup slave process cur/total:%{public}d/%{public}d, isRestore:%{public}d", + LOG_INFO("backup slave process cur/total:%{public}d/%{public}d, rs:%{public}d, isRestore:%{public}d", sqlite3_backup_pagecount(pBackup) - sqlite3_backup_remaining(pBackup), sqlite3_backup_pagecount(pBackup), - isRestore); - if (!isRestore && (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED)) { + rc, isRestore); + if (!isRestore) { sqlite3_sleep(BACKUP_PRE_WAIT_TIME); } - } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); + } while (sqlite3_backup_pagecount(pBackup) != 0 && (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED)); (void)sqlite3_backup_finish(pBackup); if (rc != SQLITE_DONE) { - curStatus = SlaveStatus::BACKUP_INTERRUPT; - LOG_WARN("backup slave err:%{public}d, isRestore:%{public}d", rc, isRestore); - return SQLiteError::ErrNo(rc); - } else { - isRestore ? TryCheckPoint() : slaveConnection_->TryCheckPoint(); - curStatus = SlaveStatus::BACKUP_FINISHED; - SqliteUtils::TryAccessSlaveLock(config_.GetPath(), true, false); - SqliteUtils::TryAccessSlaveLock(config_.GetPath(), true, false, true); - LOG_INFO("backup slave success, isRestore:%{public}d", isRestore); + LOG_ERROR("backup slave err:%{public}d, isRestore:%{public}d", rc, isRestore); + if (!isRestore) { + RdbStoreConfig slaveConfig(slaveConnection_->config_.GetPath()); + if (rc != SQLITE_BUSY && rc != SQLITE_LOCKED) { + slaveConnection_ = nullptr; + (void)SqliteConnection::Delete(slaveConfig); + } + curStatus = SlaveStatus::BACKUP_INTERRUPT; + } + return rc == E_BACKUP_INTERRUPT ? E_BACKUP_INTERRUPT : SQLiteError::ErrNo(rc); } + isRestore ? TryCheckPoint() : slaveConnection_->TryCheckPoint(); + curStatus = SlaveStatus::BACKUP_FINISHED; + SqliteUtils::TryAccessSlaveLock(config_.GetPath(), true, false); + SqliteUtils::TryAccessSlaveLock(config_.GetPath(), true, false, true); + LOG_INFO("backup slave success, isRestore:%{public}d", isRestore); return E_OK; } ExchangeStrategy SqliteConnection::GenerateExchangeStrategy(const SlaveStatus &status) { if (dbHandle_ == nullptr || slaveConnection_ == nullptr || slaveConnection_->dbHandle_ == nullptr || - config_.GetHaMode() != HAMode::MAIN_REPLICA || status == SlaveStatus::BACKING_UP) { + config_.GetHaMode() == HAMode::SINGLE || status == SlaveStatus::BACKING_UP) { return ExchangeStrategy::NOT_HANDLE; } - std::string failureFlagFile = config_.GetPath() + "-slaveFailure"; - if (status == SlaveStatus::DB_NOT_EXITS || status == SlaveStatus::BACKUP_INTERRUPT) { - return ExchangeStrategy::BACKUP; - } static const std::string querySql = "SELECT COUNT(*) FROM sqlite_master WHERE type='table';"; auto [mRet, mObj] = ExecuteForValue(querySql); if (mRet != E_OK) { - return ExchangeStrategy::NOT_HANDLE; + LOG_WARN("main abnormal, err:%{public}d", mRet); + return ExchangeStrategy::RESTORE; + } + int64_t mCount = static_cast(mObj); + // trigger mode only does restore, not backup + if (config_.GetHaMode() == HAMode::MANUAL_TRIGGER) { + return mCount == 0 ? ExchangeStrategy::RESTORE : ExchangeStrategy::NOT_HANDLE; } auto [sRet, sObj] = slaveConnection_->ExecuteForValue(querySql); if (sRet != E_OK) { LOG_WARN("slave db abnormal, need backup, err:%{public}d", sRet); return ExchangeStrategy::BACKUP; } - int64_t mCount = static_cast(mObj); + if (status == SlaveStatus::DB_NOT_EXITS || status == SlaveStatus::BACKUP_INTERRUPT) { + return ExchangeStrategy::BACKUP; + } int64_t sCount = static_cast(sObj); + std::string failureFlagFile = config_.GetPath() + "-slaveFailure"; if (mCount == sCount && access(failureFlagFile.c_str(), F_OK) != 0) { LOG_INFO("equal, main:%{public}" PRId64 ",slave:%{public}" PRId64, mCount, sCount); return ExchangeStrategy::NOT_HANDLE; @@ -1324,23 +1380,20 @@ ExchangeStrategy SqliteConnection::GenerateExchangeStrategy(const SlaveStatus &s if (mCount == 0) { LOG_INFO("main empty, main:%{public}" PRId64 ",slave:%{public}" PRId64, mCount, sCount); return ExchangeStrategy::RESTORE; - } else { - auto [cRet, cObj] = ExecuteForValue(INTEGRITIES[1]); // 1 is quick_check - if (cRet != E_OK || (static_cast(cObj) != "ok")) { - LOG_ERROR("main corrupt, need restore, ret:%{public}s, cRet:%{public}d", - static_cast(cObj).c_str(), cRet); - return ExchangeStrategy::RESTORE; - } else { - LOG_INFO("not equal, main:%{public}" PRId64 ",slave:%{public}" PRId64, mCount, sCount); - return ExchangeStrategy::BACKUP; - } } - return ExchangeStrategy::NOT_HANDLE; + auto [cRet, cObj] = ExecuteForValue(INTEGRITIES[1]); // 1 is quick_check + if (cRet != E_OK || (static_cast(cObj) != "ok")) { + LOG_ERROR("main corrupt, need restore, ret:%{public}s, cRet:%{public}d, slave:%{public}" PRId64, + static_cast(cObj).c_str(), cRet, sCount); + return sCount == 0 ? ExchangeStrategy::NOT_HANDLE : ExchangeStrategy::RESTORE; + } + LOG_INFO("backup, main:%{public}" PRId64 ",slave:%{public}" PRId64, mCount, sCount); + return ExchangeStrategy::BACKUP; } int32_t SqliteConnection::Repair(const RdbStoreConfig &config) { - if (config.GetHaMode() != MAIN_REPLICA) { + if (config.GetHaMode() != MAIN_REPLICA && config.GetHaMode() != MANUAL_TRIGGER) { return E_NOT_SUPPORT; } std::shared_ptr connection = std::make_shared(config, true); @@ -1366,7 +1419,7 @@ int32_t SqliteConnection::Repair(const RdbStoreConfig &config) ret = connection->ExchangeSlaverToMaster(true, curStatus); if (ret != E_OK) { LOG_ERROR("repair failed, [%{public}s]->[%{public}s], err:%{public}d", rdbSlaveStoreConfig.GetName().c_str(), - config.GetName().c_str(), ret); + SqliteUtils::Anonymous(config.GetName()).c_str(), ret); } else { LOG_INFO("repair main success:%{public}s", SqliteUtils::Anonymous(config.GetPath()).c_str()); } @@ -1386,11 +1439,6 @@ bool SqliteConnection::IsRepairable() LOG_INFO("cancel repair, ret:%{public}d", qRet); return false; } - auto [cRet, cObj] = slaveConnection_->ExecuteForValue(INTEGRITIES[1]); // 1 is quick check - if (cRet != E_OK || (static_cast(cObj) != "ok")) { - LOG_ERROR("cancel repair, ret:%{public}s, cRet:%{public}d", static_cast(cObj).c_str(), cRet); - return false; - } return true; } @@ -1400,16 +1448,24 @@ std::pair SqliteConnection::ExchangeVerify(bool isRestore) LOG_WARN("slave conn invalid"); return { true, E_OK }; } - if (!SqliteUtils::TryAccessSlaveLock(config_.GetPath(), false, true)) { - LOG_WARN("try create slave lock failed! isRestore:%{public}d", isRestore); + if (access(config_.GetPath().c_str(), F_OK) != 0) { + LOG_WARN("main no exist, isR:%{public}d, %{public}s", isRestore, config_.GetName().c_str()); + return { true, E_DB_NOT_EXIST }; } if (isRestore) { auto [cRet, cObj] = slaveConnection_->ExecuteForValue(INTEGRITIES[2]); // 2 is integrity_check if (cRet != E_OK || (static_cast(cObj) != "ok")) { - LOG_ERROR("slave may corrupt, cancel backup, ret:%{public}s, cRet:%{public}d", + LOG_ERROR("slave may corrupt, cancel, ret:%{public}s, cRet:%{public}d", static_cast(cObj).c_str(), cRet); return { true, E_SQLITE_CORRUPT }; } + if (!IsRepairable()) { + return { true, E_OK }; + } + } else { + if (!SqliteUtils::TryAccessSlaveLock(config_.GetPath(), false, true)) { + LOG_WARN("try create slave lock failed! isRestore:%{public}d", isRestore); + } } return { false, E_OK }; } diff --git a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp index 433b648f..9ce21e20 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp @@ -60,12 +60,13 @@ void SqliteGlobalConfig::Log(const void *data, int err, const char *msg) if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE || err == SQLITE_WARNING_AUTOINDEX) { if (verboseLog) { - LOG_INFO("Error(%{public}d) %{public}s ", err, msg); + LOG_INFO("Error(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } } else if (errType == SQLITE_WARNING) { - LOG_WARN("WARNING(%{public}d) %{public}s ", err, msg); + LOG_WARN("WARNING(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } else { - LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno, msg); + LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno, + SqliteUtils::Anonymous(msg).c_str()); } } @@ -110,8 +111,8 @@ int SqliteGlobalConfig::GetDbPath(const RdbStoreConfig &config, std::string &dbP if (config.GetStorageMode() == StorageMode::MODE_MEMORY) { if (config.GetRoleType() == VISITOR) { - LOG_ERROR("not support MODE_MEMORY, storeName:%{public}s, role:%{public}d", config.GetName().c_str(), - config.GetRoleType()); + LOG_ERROR("not support MODE_MEMORY, storeName:%{public}s, role:%{public}d", + SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetRoleType()); return E_NOT_SUPPORT; } dbPath = SqliteGlobalConfig::GetMemoryDbPath(); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp index 133ff618..f4807182 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp @@ -33,20 +33,6 @@ std::vector g_onConflictClause = { SqliteSqlBuilder::SqliteSqlBuilder() {} SqliteSqlBuilder::~SqliteSqlBuilder() {} -/** - * Build a delete SQL string using the given condition for SQLite. - */ -std::string SqliteSqlBuilder::BuildDeleteString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset) -{ - std::string sql; - sql.append("Delete ") - .append("FROM ") - .append(HandleTable(tableName)) - .append(BuildSqlStringFromPredicates(index, "", whereClause, group, order, limit, offset)); - return sql; -} - /** * Build a count SQL string using the given condition for SQLite. */ @@ -108,19 +94,6 @@ int SqliteSqlBuilder::BuildQueryString(bool distinct, const std::string &table, return E_OK; } -/** - * Build a count SQL string using the given condition for SQLite. - */ -std::string SqliteSqlBuilder::BuildCountString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset) -{ - std::string sql; - sql.append("SELECT COUNT(*) FROM ") - .append(HandleTable(tableName)) - .append(BuildSqlStringFromPredicates(index, "", whereClause, group, order, limit, offset)); - return sql; -} - std::string SqliteSqlBuilder::BuildSqlStringFromPredicates(const std::string &index, const std::string &joinClause, const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset) { @@ -158,23 +131,6 @@ std::string SqliteSqlBuilder::BuildSqlStringFromPredicates(const AbsPredicates & return sqlString; } -std::string SqliteSqlBuilder::BuildSqlStringFromPredicatesNoWhere(const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset) -{ - std::string limitStr = (limit == AbsPredicates::INIT_LIMIT_VALUE) ? "" : std::to_string(limit); - std::string offsetStr = (offset == AbsPredicates::INIT_OFFSET_VALUE) ? "" : std::to_string(offset); - - std::string sqlString; - AppendClause(sqlString, " INDEXED BY ", index); - AppendClause(sqlString, " ", whereClause); - AppendClause(sqlString, " GROUP BY ", group); - AppendClause(sqlString, " ORDER BY ", order); - AppendClause(sqlString, " LIMIT ", limitStr); - AppendClause(sqlString, " OFFSET ", offsetStr); - - return sqlString; -} - void SqliteSqlBuilder::AppendClause( std::string &builder, const std::string &name, const std::string &clause, const std::string &table) { diff --git a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp index fe0d2e29..c393aefd 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp @@ -56,6 +56,7 @@ SqliteStatement::~SqliteStatement() SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL_RES, seqId_); Finalize(); conn_ = nullptr; + config_ = nullptr; } int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) @@ -75,8 +76,8 @@ int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) ReadFile2Buffer(); } int ret = SQLiteError::ErrNo(errCode); - if (ret == E_SQLITE_CORRUPT) { - ReportDbCorruptedEvent(ret); + if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } PrintInfoForDbError(ret); return ret; @@ -98,7 +99,8 @@ void SqliteStatement::PrintInfoForDbError(int errorCode) } if (errorCode == E_SQLITE_ERROR || errorCode == E_SQLITE_BUSY || errorCode == E_SQLITE_LOCKED || errorCode == E_SQLITE_IOERR || errorCode == E_SQLITE_CORRUPT || errorCode == E_SQLITE_CANTOPEN) { - LOG_ERROR(" DbError errorCode: %{public}d DbName: %{public}s ", errorCode, config_->GetName().c_str()); + LOG_ERROR(" DbError errorCode: %{public}d DbName: %{public}s ", errorCode, + SqliteUtils::Anonymous(config_->GetName()).c_str()); } } @@ -114,7 +116,8 @@ void SqliteStatement::ReadFile2Buffer() uint64_t buffer[BUFFER_LEN] = {0x0}; FILE *file = fopen(fileName.c_str(), "r"); if (file == nullptr) { - LOG_ERROR("open db file failed: %{public}s, errno is %{public}d", fileName.c_str(), errno); + LOG_ERROR( + "open db file failed: %{public}s, errno is %{public}d", SqliteUtils::Anonymous(fileName).c_str(), errno); return; } size_t readSize = fread(buffer, sizeof(uint64_t), BUFFER_LEN, file); @@ -277,8 +280,8 @@ int SqliteStatement::InnerStep() { SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_); int ret = SQLiteError::ErrNo(sqlite3_step(stmt_)); - if (ret == E_SQLITE_CORRUPT) { - ReportDbCorruptedEvent(ret); + if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } PrintInfoForDbError(ret); return ret; @@ -691,35 +694,6 @@ int SqliteStatement::ModifyLockStatus(const std::string &table, const std::vecto return E_ERROR; } -void SqliteStatement::ReportDbCorruptedEvent(int errorCode) -{ - if (config_ == nullptr) { - return; - } - RdbCorruptedEvent eventInfo; - eventInfo.bundleName = config_->GetBundleName(); - eventInfo.moduleName = config_->GetModuleName(); - eventInfo.storeType = "RDB"; - eventInfo.storeName = config_->GetName(); - eventInfo.securityLevel = static_cast(config_->GetSecurityLevel()); - eventInfo.pathArea = static_cast(config_->GetArea()); - eventInfo.encryptStatus = static_cast(config_->IsEncrypt()); - eventInfo.integrityCheck = static_cast(config_->GetIntegrityCheck()); - eventInfo.errorCode = static_cast(errorCode); - eventInfo.systemErrorNo = errno; - eventInfo.errorOccurTime = time(nullptr); - std::string dbPath; - if (SqliteGlobalConfig::GetDbPath(*config_, dbPath) == E_OK && access(dbPath.c_str(), F_OK) == 0) { - eventInfo.dbFileStatRet = stat(dbPath.c_str(), &eventInfo.dbFileStat); - std::string walPath = dbPath + "-wal"; - eventInfo.walFileStatRet = stat(walPath.c_str(), &eventInfo.walFileStat); - } else { - eventInfo.dbFileStatRet = -1; - eventInfo.walFileStatRet = -1; - } - RdbFaultHiViewReporter::ReportRdbCorruptedFault(eventInfo); -} - int SqliteStatement::InnerFinalize() { if (stmt_ == nullptr) { @@ -733,7 +707,6 @@ int SqliteStatement::InnerFinalize() columnCount_ = -1; numParameters_ = 0; types_ = std::vector(); - config_ = nullptr; if (errCode != SQLITE_OK) { LOG_ERROR("finalize ret is %{public}d, errno is %{public}d", errCode, errno); return SQLiteError::ErrNo(errCode); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp index 547004c6..74a02a04 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "logger.h" #include "rdb_errno.h" @@ -36,11 +37,13 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -constexpr int32_t HEAD_SIZE = 3; -constexpr int32_t END_SIZE = 3; -constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; -constexpr const char *REPLACE_CHAIN = "***"; -constexpr const char *DEFAULT_ANONYMOUS = "******"; +/* A continuous number must contain at least eight digits, because the employee ID has eight digits, + and the mobile phone number has 11 digits. The UUID is longer */ +constexpr int32_t CONTINUOUS_DIGITS_MINI_SIZE = 5; +constexpr int32_t FILE_PATH_MINI_SIZE = 6; +constexpr int32_t AREA_MINI_SIZE = 4; +constexpr int32_t AREA_OFFSET_SIZE = 5; +constexpr int32_t PRE_OFFSET_SIZE = 1; constexpr SqliteUtils::SqlType SqliteUtils::SQL_TYPE_MAP[]; constexpr const char *SqliteUtils::ON_CONFLICT_CLAUSE[]; @@ -52,12 +55,12 @@ int SqliteUtils::GetSqlStatementType(const std::string &sql) if (alnum == sql.end()) { return STATEMENT_ERROR; } - auto pos = alnum - sql.begin(); + auto pos = static_cast(alnum - sql.begin()); /* 3 represents the number of prefix characters that need to be extracted and checked */ if (pos + 3 >= sql.length()) { return STATEMENT_ERROR; } - /* analyze the sql type through first 3 character */ + /* analyze the sql type through first 3 characters */ std::string prefixSql = StrToUpper(sql.substr(pos, 3)); SqlType type = { prefixSql.c_str(), STATEMENT_OTHER }; auto comp = [](const SqlType &first, const SqlType &second) { @@ -117,9 +120,13 @@ const char *SqliteUtils::GetConflictClause(int conflictResolution) bool SqliteUtils::DeleteFile(const std::string &filePath) { + if (access(filePath.c_str(), F_OK) != 0) { + return true; + } auto ret = remove(filePath.c_str()); if (ret != 0) { - LOG_WARN("remove file failed errno %{public}d ret %{public}d %{public}s", errno, ret, filePath.c_str()); + LOG_WARN("remove file failed errno %{public}d ret %{public}d %{public}s", errno, ret, + Anonymous(filePath).c_str()); return false; } return true; @@ -130,7 +137,7 @@ bool SqliteUtils::RenameFile(const std::string &srcFile, const std::string &dest auto ret = rename(srcFile.c_str(), destFile.c_str()); if (ret != 0) { LOG_WARN("rename failed errno %{public}d ret %{public}d %{public}s -> %{public}s", errno, ret, - destFile.c_str(), srcFile.c_str()); + SqliteUtils::Anonymous(destFile).c_str(), srcFile.c_str()); return false; } return true; @@ -140,13 +147,13 @@ bool SqliteUtils::CopyFile(const std::string &srcFile, const std::string &destFi { std::ifstream src(srcFile.c_str(), std::ios::binary); if (!src.is_open()) { - LOG_WARN("open srcFile failed errno %{public}d %{public}s", errno, srcFile.c_str()); + LOG_WARN("open srcFile failed errno %{public}d %{public}s", errno, SqliteUtils::Anonymous(srcFile).c_str()); return false; } std::ofstream dst(destFile.c_str(), std::ios::binary); if (!dst.is_open()) { src.close(); - LOG_WARN("open destFile failed errno %{public}d %{public}s", errno, destFile.c_str()); + LOG_WARN("open destFile failed errno %{public}d %{public}s", errno, SqliteUtils::Anonymous(destFile).c_str()); return false; } dst << src.rdbuf(); @@ -155,17 +162,83 @@ bool SqliteUtils::CopyFile(const std::string &srcFile, const std::string &destFi return true; } -std::string SqliteUtils::Anonymous(const std::string &srcFile) +std::string SqliteUtils::GetAnonymousName(const std::string &fileName) { - if (srcFile.length() <= HEAD_SIZE) { - return DEFAULT_ANONYMOUS; + std::vector alnum; + std::vector noAlnum; + std::string alnumStr; + std::string noAlnumStr; + for (const auto &letter : fileName) { + if (isxdigit(letter)) { + if (!noAlnumStr.empty()) { + noAlnum.push_back(noAlnumStr); + noAlnumStr.clear(); + alnum.push_back(""); + } + alnumStr += letter; + } else { + if (!alnumStr.empty()) { + alnum.push_back(alnumStr); + alnumStr.clear(); + noAlnum.push_back(""); + } + noAlnumStr += letter; + } + } + if (!alnumStr.empty()) { + alnum.push_back(alnumStr); + noAlnum.push_back(""); + } + if (!noAlnumStr.empty()) { + noAlnum.push_back(alnumStr); + alnum.push_back(""); } + std::string res = ""; + for (size_t i = 0; i < alnum.size(); ++i) { + res += (AnonyDigits(alnum[i]) + noAlnum[i]); + } + return res; +} - if (srcFile.length() < MIN_SIZE) { - return (srcFile.substr(0, HEAD_SIZE) + REPLACE_CHAIN); +std::string SqliteUtils::AnonyDigits(const std::string &fileName) +{ + int digitsNum = fileName.size(); + if (digitsNum < CONTINUOUS_DIGITS_MINI_SIZE) { + return fileName; + } + constexpr int longDigits = 7; + int endDigitsNum = 4; + int shortEndDigitsNum = 3; + std::string name = fileName; + std::string last = ""; + if (digitsNum >= CONTINUOUS_DIGITS_MINI_SIZE && digitsNum < longDigits) { + last = name.substr(name.size() - shortEndDigitsNum); + } else { + last = name.substr(name.size() - endDigitsNum); } - return (srcFile.substr(0, HEAD_SIZE) + REPLACE_CHAIN + srcFile.substr(srcFile.length() - END_SIZE, END_SIZE)); + return "***" + last; +} + +std::string SqliteUtils::Anonymous(const std::string &srcFile) +{ + auto pre = srcFile.find("/"); + auto end = srcFile.rfind("/"); + if (pre == std::string::npos || end - pre < FILE_PATH_MINI_SIZE) { + return GetAnonymousName(srcFile); + } + auto path = srcFile.substr(pre, end - pre); + auto area = path.find("/el"); + if (area == std::string::npos || area + AREA_MINI_SIZE > path.size()) { + path = ""; + } else if (area + AREA_OFFSET_SIZE < path.size()) { + path = path.substr(area, AREA_MINI_SIZE) + "/***"; + } else { + path = path.substr(area, AREA_MINI_SIZE); + } + std::string fileName = srcFile.substr(end); // rdb file name + fileName = GetAnonymousName(fileName); + return srcFile.substr(0, pre + PRE_OFFSET_SIZE) + "***" + path + fileName; } int SqliteUtils::GetFileSize(const std::string &fileName) 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 6b67314f..6e120446 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -60,32 +60,6 @@ StepResultSet::~StepResultSet() Close(); } -int StepResultSet::InitRowCount() -{ - auto statement = GetStatement(); - if (statement == nullptr) { - return NO_COUNT; - } - int32_t count = NO_COUNT; - int32_t status = E_OK; - int32_t retry = 0; - do { - status = statement->Step(); - if (status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) { - retry++; - usleep(STEP_QUERY_RETRY_INTERVAL); - continue; - } - count++; - } while (status == E_OK || - ((status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) && retry < STEP_QUERY_RETRY_MAX_TIMES)); - if (status != E_NO_MORE_ROWS) { - lastErr_ = status; - count = NO_COUNT; - } - statement->Reset(); - return count; -} /** * Obtain session and prepare precompile statement for step query */ diff --git a/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h b/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h index 36a506f7..2316e878 100644 --- a/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h +++ b/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h @@ -88,6 +88,7 @@ enum class RdbServiceInterfaceCode { RDB_SERVICE_CMD_GET_PASSWORD, RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER, RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER, + RDB_SERVICE_CMD_GET_DEBUG_INFO, RDB_SERVICE_CMD_MAX }; } // namespace RelationalStore diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h index d728bf8b..d7b66279 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h @@ -36,6 +36,7 @@ public: bool isCompensation = false; }; using ResultSet = NativeRdb::ResultSet; + inline static constexpr const char *SERVICE_NAME = "relational_store"; virtual std::string ObtainDistributedTableName(const std::string &device, const std::string &table) = 0; @@ -87,7 +88,8 @@ public: virtual std::pair LockCloudContainer(const RdbSyncerParam ¶m) = 0; virtual int32_t UnlockCloudContainer(const RdbSyncerParam ¶m) = 0; - inline static constexpr const char *SERVICE_NAME = "relational_store"; + + virtual int32_t GetDebugInfo(const RdbSyncerParam ¶m, std::map &debugInfo) = 0; }; } } // namespace OHOS::DistributedRdb diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h index 6db88ec2..3b86b0c2 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h @@ -545,19 +545,9 @@ public: } } - if (this->encryptKey_.size() != config.encryptKey_.size()) { - return false; - } - - for (size_t i = 0; i < encryptKey_.size(); i++) { - if (this->encryptKey_[i] != config.encryptKey_[i]) { - return false; - } - } - return this->path_ == config.path_ && this->storageMode_ == config.storageMode_ && this->journalMode_ == config.journalMode_ && this->syncMode_ == config.syncMode_ && - this->databaseFileType == config.databaseFileType && this->isEncrypt_ == config.isEncrypt_ && + this->databaseFileType == config.databaseFileType && IsEncrypt() == config.IsEncrypt() && this->securityLevel_ == config.securityLevel_ && this->journalSize_ == config.journalSize_ && this->pageSize_ == config.pageSize_ && this->readConSize_ == config.readConSize_ && this->customDir_ == config.customDir_ && this->allowRebuilt_ == config.allowRebuilt_ && diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h index 39b91e6c..96ba6ce3 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h @@ -36,6 +36,23 @@ enum RdbDistributedType { RDB_DISTRIBUTED_TYPE_MAX }; +struct RdbDebugInfo { + struct DebugTime { + int64_t sec_ = 0; + int64_t nsec_ = 0; + }; + uint64_t inode_ = 0; + uint64_t oldInode_ = 0; + DebugTime atime_; + DebugTime mtime_; + DebugTime ctime_; + size_t size_ = 0; + uint32_t dev_ = 0; + uint32_t mode_ = 0; + uint32_t uid_ = 0; + uint32_t gid_ = 0; +}; + struct RdbSyncerParam { std::string bundleName_; std::string hapName_; @@ -50,6 +67,7 @@ struct RdbSyncerParam { bool isAutoClean_ = true; bool isSearchable_ = false; std::vector password_; + std::map infos_; ~RdbSyncerParam() { password_.assign(password_.size(), 0); diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h index 5b86cf10..faf4b73b 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h @@ -188,19 +188,9 @@ public: } } - if (this->encryptKey_.size() != config.encryptKey_.size()) { - return false; - } - - for (size_t i = 0; i < encryptKey_.size(); i++) { - if (this->encryptKey_[i] != config.encryptKey_[i]) { - return false; - } - } - return this->path_ == config.path_ && this->storageMode_ == config.storageMode_ && this->journalMode_ == config.journalMode_ && this->syncMode_ == config.syncMode_ && - this->databaseFileType == config.databaseFileType && this->isEncrypt_ == config.isEncrypt_ && + this->databaseFileType == config.databaseFileType && IsEncrypt() == config.IsEncrypt() && this->securityLevel_ == config.securityLevel_ && this->journalSize_ == config.journalSize_ && this->pageSize_ == config.pageSize_ && this->readConSize_ == config.readConSize_ && this->customDir_ == config.customDir_ && this->allowRebuilt_ == config.allowRebuilt_ && diff --git a/relational_store/interfaces/ndk/src/relational_store.cpp b/relational_store/interfaces/ndk/src/relational_store.cpp index 4e1c8307..dd51957c 100644 --- a/relational_store/interfaces/ndk/src/relational_store.cpp +++ b/relational_store/interfaces/ndk/src/relational_store.cpp @@ -15,6 +15,8 @@ #define LOG_TAG "RelationalStore" #include "relational_store.h" +#include "convertor_error_code.h" +#include "grd_api_manager.h" #include "logger.h" #include "modify_time_cursor.h" #include "raw_data_parser.h" @@ -22,22 +24,168 @@ #include "rdb_helper.h" #include "rdb_predicates.h" #include "rdb_sql_utils.h" +#include "rdb_store_config.h" #include "relational_cursor.h" #include "relational_predicates.h" #include "relational_predicates_objects.h" #include "relational_store_error_code.h" #include "relational_store_impl.h" +#include "relational_store_inner.h" #include "relational_types_v0.h" #include "relational_values_bucket.h" #include "securec.h" #include "sqlite_global_config.h" -#include "convertor_error_code.h" using namespace OHOS::RdbNdk; using namespace OHOS::DistributedRdb; constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class. constexpr int RDB_CONFIG_SIZE_V0 = 41; constexpr int RDB_CONFIG_SIZE_V1 = 45; +constexpr int RDB_CONFIG_V2_MAGIC_CODE = 0xDBCF2ADE; +constexpr int RDB_SQLITE = 1; +constexpr int RDB_CARLEY = 2; + +static int g_supportDbTypes[] = {RDB_SQLITE, RDB_CARLEY}; + +struct OH_Rdb_ConfigV2 { + int magicNum = RDB_CONFIG_V2_MAGIC_CODE; + std::string dataBaseDir = ""; + std::string storeName = ""; + std::string bundleName = ""; + std::string moduleName = ""; + bool isEncrypt = false; + int securityLevel = 0; + int area = 0; + int dbType = RDB_SQLITE; +}; + +OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig() +{ + return new (std::nothrow) OH_Rdb_ConfigV2(); +} + +int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when destroy.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + delete config; + config = nullptr; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetDataBaseDir(OH_Rdb_ConfigV2 *config, const char *dataBaseDir) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when Set DataBaseDir.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->dataBaseDir = std::string(dataBaseDir); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x When set storeName.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->storeName = std::string(storeName); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set bundleName.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->bundleName = std::string(bundleName); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set moduleName.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->moduleName = std::string(moduleName); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetEncrypt(OH_Rdb_ConfigV2 *config, bool isEncrypt) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set encrypt.", (config == nullptr), + (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->isEncrypt = isEncrypt; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set security level.", + (config == nullptr), (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + if (securityLevel < S1 || securityLevel > S4) { + LOG_ERROR("securityLevel value is out of range %{public}d", securityLevel); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->securityLevel = securityLevel; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set area.", (config == nullptr), + (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + if (area < RDB_SECURITY_AREA_EL1 || area > RDB_SECURITY_AREA_EL5) { + LOG_ERROR("area value is out of range %{public}d", area); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + config->area = area; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Rdb_SetDbType(OH_Rdb_ConfigV2 *config, int dbType) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || + (dbType < RDB_SQLITE || dbType > RDB_CARLEY)) { + LOG_ERROR("config is null %{public}d or magicNum not valid %{public}d or dbType is out of range %{public}d", + (config == nullptr), (config == nullptr ? 0 : config->magicNum), dbType); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + if (dbType == RDB_CARLEY && !(OHOS::NativeRdb::IsUsingArkData())) { + return OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED; + } + config->dbType = dbType; + return OH_Rdb_ErrCode::RDB_OK; +} + +const int *OH_Rdb_GetSupportDBType(int *numType) +{ + if (numType == nullptr) { + return nullptr; + } + // if use arkData, then numType will be 2 {RDB_SQLITE and RDB_CARLEY}, otherwise only 1 {RDB_SQLITE} + *numType = OHOS::NativeRdb::IsUsingArkData() ? 2 : 1; + return g_supportDbTypes; +} + OH_VObject *OH_Rdb_CreateValueObject() { return new (std::nothrow) RelationalPredicatesObjects(); @@ -63,10 +211,9 @@ OHOS::RdbNdk::RelationalStore::RelationalStore(std::shared_ptr lock(mutex_) ; - bool result = std::any_of(callbacks_.begin(), callbacks_.end(), [callback](const auto &observer) { - return *observer == callback; - }); + std::lock_guard lock(mutex_); + bool result = std::any_of( + callbacks_.begin(), callbacks_.end(), [callback](const auto &observer) { return *observer == callback; }); if (result) { LOG_INFO("duplicate subscribe."); return OH_Rdb_ErrCode::RDB_OK; @@ -83,7 +230,7 @@ int RelationalStore::SubscribeAutoSyncProgress(const Rdb_ProgressObserver *callb int RelationalStore::UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback) { - std::lock_guard lock(mutex_) ; + std::lock_guard lock(mutex_); for (auto it = callbacks_.begin(); it != callbacks_.end();) { if (callback != nullptr && !(**it == callback)) { ++it; @@ -164,6 +311,36 @@ RelationalStore *GetRelationalStore(OH_Rdb_Store *store) return static_cast(store); } +static OHOS::NativeRdb::RdbStoreConfig GetRdbStoreConfig(const OH_Rdb_ConfigV2 *config, int *errCode) +{ + if (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE || + (OHOS::NativeRdb::SecurityLevel(config->securityLevel) < OHOS::NativeRdb::SecurityLevel::S1 || + OHOS::NativeRdb::SecurityLevel(config->securityLevel) >= OHOS::NativeRdb::SecurityLevel::LAST) || + (config->area < RDB_SECURITY_AREA_EL1 || config->area > RDB_SECURITY_AREA_EL5) || + (config->dbType < RDB_SQLITE || config->dbType > RDB_CARLEY)) { + *errCode = OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + LOG_ERROR("Config magic number is not valid %{public}x or securityLevel %{public}d area %{public}d" + "dbType %{public}d ret %{public}d", config->magicNum, config->securityLevel, config->area, config->dbType, + *errCode); + return OHOS::NativeRdb::RdbStoreConfig(""); + } + std::string realPath = + OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode); + if (*errCode != 0) { + *errCode = ConvertorErrorCode::NativeToNdk(*errCode); + LOG_ERROR("Get database path failed from new config, ret %{public}d ", *errCode); + return OHOS::NativeRdb::RdbStoreConfig(""); + } + OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath); + rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); + rdbStoreConfig.SetEncryptStatus(config->isEncrypt); + rdbStoreConfig.SetArea(config->area - 1); + rdbStoreConfig.SetIsVector(config->dbType == RDB_CARLEY); + rdbStoreConfig.SetBundleName(config->bundleName); + rdbStoreConfig.SetName(config->storeName); + return rdbStoreConfig; +} + OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) { if (config == nullptr || config->selfSize > RDB_CONFIG_SIZE_V1 || errCode == nullptr) { @@ -184,7 +361,7 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); rdbStoreConfig.SetEncryptStatus(config->isEncrypt); if (config->selfSize > RDB_CONFIG_SIZE_V0) { - rdbStoreConfig.SetArea(config->area); + rdbStoreConfig.SetArea(config->area - 1); } if (config->bundleName != nullptr) { rdbStoreConfig.SetBundleName(config->bundleName); @@ -202,6 +379,29 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) return new (std::nothrow) RelationalStore(store); } +OH_Rdb_Store *OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 *config, int *errCode) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || errCode == nullptr) { + LOG_ERROR("Parameters set error:config is NULL ? %{public}d or magicNum is not valid %{public}d or" + " errCode is NULL ? %{public}d ", (config == nullptr), (config == nullptr ? 0 : config->magicNum), + (errCode == nullptr)); + return nullptr; + } + OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig = GetRdbStoreConfig(config, errCode); + if (*errCode != OH_Rdb_ErrCode::RDB_OK) { + return nullptr; + } + MainOpenCallback callback; + std::shared_ptr store = + OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode); + *errCode = ConvertorErrorCode::NativeToNdk(*errCode); + if (store == nullptr) { + LOG_ERROR("Get RDB Store fail %{public}s", rdbStoreConfig.GetPath().c_str()); + return nullptr; + } + return new (std::nothrow) RelationalStore(store); +} + int OH_Rdb_CloseStore(OH_Rdb_Store *store) { auto rdbStore = GetRelationalStore(store); @@ -227,6 +427,22 @@ int OH_Rdb_DeleteStore(const OH_Rdb_Config *config) return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath)); } +int OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 *config) +{ + if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) { + LOG_ERROR("config is NULL ? %{public}d, config is invalid ? %{public}d", (config == nullptr), + (config == nullptr ? 0 : config->magicNum)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + int errCode = OHOS::NativeRdb::E_OK; + std::string realPath = + OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode); + if (errCode != OHOS::NativeRdb::E_OK) { + return ConvertorErrorCode::NativeToNdk(errCode); + } + return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath)); +} + int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) { auto rdbStore = GetRelationalStore(store); @@ -294,7 +510,9 @@ OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql) return nullptr; } std::shared_ptr resultSet = - rdbStore->GetStore()->QuerySql(sql, std::vector{}); + rdbStore->GetStore()->GetDbType() == OHOS::NativeRdb::DB_VECTOR + ? rdbStore->GetStore()->QueryByStep(sql, std::vector{}) + : rdbStore->GetStore()->QuerySql(sql, std::vector{}); if (resultSet == nullptr) { return nullptr; } @@ -311,6 +529,16 @@ int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) rdbStore->GetStore()->ExecuteSql(sql, std::vector{})); } +int OH_Rdb_ExecuteByTrxId(OH_Rdb_Store *store, int64_t trxId, const char *sql) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || sql == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + return ConvertorErrorCode::NativeToNdk( + (rdbStore->GetStore()->Execute(sql, std::vector{}, trxId)).first); +} + int OH_Rdb_BeginTransaction(OH_Rdb_Store *store) { auto rdbStore = GetRelationalStore(store); @@ -338,6 +566,35 @@ int OH_Rdb_Commit(OH_Rdb_Store *store) return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit()); } +int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || trxId == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + std::pair res = rdbStore->GetStore()->BeginTrans(); + *trxId = res.second; + return ConvertorErrorCode::NativeToNdk(res.first); +} + +int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack(trxId)); +} + +int OH_Rdb_CommitByTrxId(OH_Rdb_Store *store, int64_t trxId) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit(trxId)); +} + int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath) { auto rdbStore = GetRelationalStore(store); @@ -393,7 +650,7 @@ static std::pair Convert(const Rdb_DistributedCo } int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, - const Rdb_DistributedConfig *config) + const Rdb_DistributedConfig *config) { auto rdbStore = GetRelationalStore(store); if (rdbStore == nullptr || type != Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD || (count > 0 && tables == nullptr)) { @@ -412,8 +669,8 @@ int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint3 } tableNames.emplace_back(tables[i]); } - return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetDistributedTables(tableNames, - DistributedTableType::DISTRIBUTED_CLOUD, { cfg.isAutoSync })); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetDistributedTables( + tableNames, DistributedTableType::DISTRIBUTED_CLOUD, { cfg.isAutoSync })); } OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values) @@ -552,6 +809,9 @@ Rdb_TableDetails *RelationalProgressDetails::GetTableDetails(int paraVersion) case TABLE_DETAIL_V0: { auto length = sizeof(TableDetailsV0) * (tableLength + 1); auto *detailsV0 = (TableDetailsV0 *)ResizeBuff(length); + if (detailsV0 == nullptr) { + return nullptr; + } (void)memset_s(detailsV0, length, 0, length); int index = 0; for (const auto &pair : tableDetails_) { @@ -607,8 +867,8 @@ Rdb_TableDetails *OH_Rdb_GetTableDetails(Rdb_ProgressDetails *progress, int32_t return details->GetTableDetails(version); } -int OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, - const Rdb_ProgressObserver *observer) +int OH_Rdb_CloudSync( + OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, const Rdb_ProgressObserver *observer) { auto rdbStore = GetRelationalStore(store); if (rdbStore == nullptr || mode < RDB_SYNC_MODE_TIME_FIRST || mode > RDB_SYNC_MODE_CLOUD_FIRST || @@ -710,7 +970,7 @@ OH_Cursor *OH_Rdb_QueryLockedRow( return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet)); } -NDKDetailProgressObserver::NDKDetailProgressObserver(const Rdb_ProgressObserver *callback):callback_(callback) +NDKDetailProgressObserver::NDKDetailProgressObserver(const Rdb_ProgressObserver *callback) : callback_(callback) { } @@ -729,7 +989,9 @@ bool NDKDetailProgressObserver::operator==(const Rdb_ProgressObserver *callback) return callback == callback_; } -NDKStoreObserver::NDKStoreObserver(const Rdb_DataObserver *observer, int mode) : mode_(mode), observer_(observer) {} +NDKStoreObserver::NDKStoreObserver(const Rdb_DataObserver *observer, int mode) : mode_(mode), observer_(observer) +{ +} void NDKStoreObserver::OnChange(const std::vector &devices) { @@ -768,8 +1030,8 @@ int32_t NDKStoreObserver::GetKeyDataType(std::vector(changeInfo)); + GetKeyInfoSize(std::forward(changeInfo)); std::unique_ptr buffer = std::make_unique(size); Rdb_ChangeInfo **infos = (Rdb_ChangeInfo **)(buffer.get()); if (infos == nullptr) { @@ -805,15 +1067,15 @@ void NDKStoreObserver::OnChange(const Origin &origin, const RdbStoreObserver::Pr infos[index]->deleted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_DELETE]); ConvertKeyInfoData(data, it->second[RdbStoreObserver::CHG_TYPE_INSERT]); infos[index]->inserted.data = data; - ConvertKeyInfoData(data+infos[index]->inserted.count, it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); - infos[index]->updated.data = data+infos[index]->inserted.count; - ConvertKeyInfoData(data+infos[index]->inserted.count+infos[index]->updated.count, + ConvertKeyInfoData(data + infos[index]->inserted.count, it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); + infos[index]->updated.data = data + infos[index]->inserted.count; + ConvertKeyInfoData(data + infos[index]->inserted.count + infos[index]->updated.count, it->second[RdbStoreObserver::CHG_TYPE_DELETE]); - infos[index]->deleted.data = data+infos[index]->inserted.count+infos[index]->updated.count; + infos[index]->deleted.data = data + infos[index]->inserted.count + infos[index]->updated.count; index++; } - (*observer_->callback.detailsObserver)(observer_->context, const_cast(infos), count); + (*observer_->callback.detailsObserver)(observer_->context, const_cast(infos), count); } } @@ -822,8 +1084,8 @@ void NDKStoreObserver::OnChange() RdbStoreObserver::OnChange(); } -void NDKStoreObserver::ConvertKeyInfoData(Rdb_KeyInfo::Rdb_KeyData *keyInfoData, - std::vector &primaryKey) +void NDKStoreObserver::ConvertKeyInfoData( + Rdb_KeyInfo::Rdb_KeyData *keyInfoData, std::vector &primaryKey) { if (keyInfoData == nullptr || primaryKey.empty()) { LOG_WARN("no data, keyInfoData is nullptr:%{public}d", keyInfoData == nullptr); diff --git a/relational_store/interfaces/ndk/src/relational_store_inner.h b/relational_store/interfaces/ndk/src/relational_store_inner.h new file mode 100644 index 00000000..ad27a587 --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_store_inner.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RELATIONAL_STORE_INNER_H +#define RELATIONAL_STORE_INNER_H + +#include "relational_store.h" + +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif // API_EXPORT + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_Rdb_ConfigV2 OH_Rdb_ConfigV2; +API_EXPORT OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig(); +API_EXPORT int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config); + +API_EXPORT int OH_Rdb_SetDataBaseDir(OH_Rdb_ConfigV2 *config, const char *dataBaseDir); +API_EXPORT int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName); +API_EXPORT int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName); +API_EXPORT int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName); +API_EXPORT int OH_Rdb_SetEncrypt(OH_Rdb_ConfigV2 *config, bool isEncrypt); +API_EXPORT int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel); +API_EXPORT int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area); +API_EXPORT int OH_Rdb_SetDbType(OH_Rdb_ConfigV2 *config, int dbType); +API_EXPORT const int *OH_Rdb_GetSupportDBType(int *numType); + +API_EXPORT OH_Rdb_Store *OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 *config, int *errCode); +API_EXPORT int OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 *config); + +API_EXPORT int OH_Rdb_ExecuteByTrxId(OH_Rdb_Store *store, int64_t trxId, const char *sql); +API_EXPORT int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId); +API_EXPORT int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId); +API_EXPORT int OH_Rdb_CommitByTrxId(OH_Rdb_Store *store, int64_t trxId); + +#ifdef __cplusplus +} +#endif + +#endif // RELATIONAL_STORE_INNER_H diff --git a/relational_store/test/native/rdb/BUILD.gn b/relational_store/test/native/rdb/BUILD.gn index 8ea7afb2..8266a721 100644 --- a/relational_store/test/native/rdb/BUILD.gn +++ b/relational_store/test/native/rdb/BUILD.gn @@ -100,6 +100,7 @@ ohos_unittest("NativeRdbTest") { "unittest/rdb_sqlite_shared_result_set_test.cpp", "unittest/rdb_step_result_get_row_test.cpp", "unittest/rdb_step_result_set_test.cpp", + "unittest/rdb_store_backup_restore_test.cpp", "unittest/rdb_store_concurrent_test.cpp", "unittest/rdb_store_config_test.cpp", "unittest/rdb_store_impl_test.cpp", @@ -112,6 +113,7 @@ ohos_unittest("NativeRdbTest") { "unittest/rdb_utils_test.cpp", "unittest/rdb_value_bucket_test.cpp", "unittest/rdb_wal_limit_test.cpp", + "unittest/sqlite_utils_test.cpp", "unittest/value_object_test.cpp", ] diff --git a/relational_store/test/native/rdb/unittest/common.h b/relational_store/test/native/rdb/unittest/common.h index c6b11f15..730c4f1a 100644 --- a/relational_store/test/native/rdb/unittest/common.h +++ b/relational_store/test/native/rdb/unittest/common.h @@ -29,6 +29,8 @@ struct RowData { int age; double salary; std::vector blobType; + AssetValue asset; + std::vector assets; }; struct RowDatas { diff --git a/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp b/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp index b93d5dc8..44bf9c36 100644 --- a/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp @@ -575,7 +575,7 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_010, TestSize.Level1) RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); LOG_INFO("RdbStore_DoubleWrite_010 reopen slave db finish"); - + WaitForBackupFinish(BACKUP_FINISHED); RdbDoubleWriteTest::CheckNumber(slaveStore, count); } @@ -804,16 +804,7 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_016, TestSize.Level1) RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); config.SetHaMode(HAMode::MAIN_REPLICA); - class Callback016 : public RdbOpenCallback { - public: - int OnCreate(RdbStore &store) override { - return E_OK; - } - int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override { - return E_OK; - }; - }; - Callback016 helper; + DoubleWriteTestOpenCallback helper; int errCode; store = RdbHelper::GetRdbStore(config, 1, helper, errCode); EXPECT_EQ(errCode, E_OK); @@ -1016,6 +1007,7 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_023, TestSize.Level1) DoubleWriteTestOpenCallback helper; store = RdbHelper::GetRdbStore(config, 1, helper, errCode); EXPECT_NE(store, nullptr); + ASSERT_TRUE(store->IsSlaveDiffFromMaster()); LOG_INFO("RdbStore_DoubleWrite_023 reopen finish"); int64_t id = 10; @@ -1140,4 +1132,210 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_025, TestSize.Level1) EXPECT_EQ(resultSet->GetRowCount(countNum), errCode); EXPECT_GT(countNum, count); EXPECT_LE(countNum, count + count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_026 + * @tc.desc: open MANUAL_TRIGGER db, write, restore, insert, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_026, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MANUAL_TRIGGER); + DoubleWriteTestOpenCallback helper; + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + ASSERT_NE(store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + + EXPECT_EQ(store->Restore(std::string(""), {}), E_INVALID_FILE_PATH); + + id = 2000; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(store, count + count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_027 + * @tc.desc: open MANUAL_TRIGGER db, write, close, corrupt db, reopen, insert, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_027, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MANUAL_TRIGGER); + config.SetAllowRebuild(true); + DoubleWriteTestOpenCallback helper; + + RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME); + DoubleWriteTestOpenCallback slaveHelper; + RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); + EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + ASSERT_NE(store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(slaveStore, count); + + store = nullptr; + + std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary); + ASSERT_TRUE(file.is_open() == true); + file.seekp(30, std::ios::beg); + ASSERT_TRUE(file.good() == true); + char bytes[2] = {0x6, 0x6}; + file.write(bytes, 2); + ASSERT_TRUE(file.good() == true); + file.close(); + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + ASSERT_NE(store, nullptr); + + id = 1000; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(store, count + count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_029 + * @tc.desc: open db, write, corrupt slave db, backup, backup, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_029, TestSize.Level1) +{ + InitDb(); + int64_t id = 10; + int count = 100; + Insert(id, count); + + std::fstream slaveFile(SLAVE_DATABASE_NAME, std::ios::in | std::ios::out | std::ios::trunc); + ASSERT_TRUE(slaveFile.is_open() == true); + slaveFile << "0000"; + slaveFile.flush(); + slaveFile.close(); + + std::fstream slaveWalFile(SLAVE_DATABASE_NAME + "-wal", std::ios::in | std::ios::out | std::ios::trunc); + ASSERT_TRUE(slaveWalFile.is_open() == true); + slaveWalFile << "0000"; + slaveWalFile.flush(); + slaveWalFile.close(); + + EXPECT_NE(store->Backup(std::string(""), {}), E_OK); + LOG_INFO("RdbStore_DoubleWrite_029 backup again"); + EXPECT_EQ(store->Backup(std::string(""), {}), E_OK); + + RdbDoubleWriteTest::CheckNumber(store, count); + RdbDoubleWriteTest::CheckNumber(slaveStore, -1, E_SQLITE_IOERR); + + int errCode = E_OK; + slaveStore = nullptr; + RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME); + DoubleWriteTestOpenCallback slaveHelper; + RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); + EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); + + RdbDoubleWriteTest::CheckNumber(slaveStore, count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_030 + * @tc.desc: open db, write, delete main db, restore, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_030, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MAIN_REPLICA); + config.SetAllowRebuild(true); + DoubleWriteTestOpenCallback helper; + RdbDoubleWriteTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(RdbDoubleWriteTest::store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + + SqliteUtils::DeleteFile(DATABASE_NAME); + + EXPECT_EQ(store->Restore(std::string(""), {}), E_OK); + EXPECT_EQ(access(DATABASE_NAME.c_str(), F_OK) == 0, true); + + id = 666; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(store, count + count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_031 + * @tc.desc: open MANUAL_TRIGGER db, write, backup, delete main db, restore, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_031, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MANUAL_TRIGGER); + DoubleWriteTestOpenCallback helper; + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(RdbDoubleWriteTest::store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + + EXPECT_EQ(store->Backup(std::string(""), {}), E_OK); + + SqliteUtils::DeleteFile(DATABASE_NAME); + + EXPECT_EQ(store->Restore(std::string(""), {}), E_OK); + EXPECT_EQ(access(DATABASE_NAME.c_str(), F_OK) == 0, true); + + id = 666; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(store, count + count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_032 + * @tc.desc: open MANUAL_TRIGGER db, write, backup, close, delete main db, reopen, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_032, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MANUAL_TRIGGER); + DoubleWriteTestOpenCallback helper; + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(RdbDoubleWriteTest::store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + + EXPECT_EQ(store->Backup(std::string(""), {}), E_OK); + + store = nullptr; + + SqliteUtils::DeleteFile(DATABASE_NAME); + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(RdbDoubleWriteTest::store, nullptr); + EXPECT_EQ(access(DATABASE_NAME.c_str(), F_OK) == 0, true); + + id = 666; + Insert(id, count); + RdbDoubleWriteTest::CheckNumber(store, count + count); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp b/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp index 77c3a8cc..f5f79624 100644 --- a/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp @@ -65,6 +65,13 @@ void RdbHelperTest::TearDown(void) { } +class RdbHelperTestWrongSqlOpenCallback : public RdbOpenCallback { +public: + int OnCreate(RdbStore &store) override; + int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override; + static const std::string WRONG_SQL_TEST; +}; + class RdbHelperTestOpenCallback : public RdbOpenCallback { public: int OnCreate(RdbStore &store) override; @@ -72,16 +79,30 @@ public: static const std::string CREATE_TABLE_TEST; }; -const std::string RdbHelperTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABL IF NOT EXISTS test " +const std::string RdbHelperTestWrongSqlOpenCallback::WRONG_SQL_TEST = "CREATE TABL IF NOT EXISTS test " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER, salary REAL, " + "blobType BLOB)"; +const std::string RdbHelperTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test " "(id INTEGER PRIMARY KEY AUTOINCREMENT, " "name TEXT NOT NULL, age INTEGER, salary REAL, " "blobType BLOB)"; +int RdbHelperTestWrongSqlOpenCallback::OnCreate(RdbStore &store) +{ + return store.ExecuteSql(WRONG_SQL_TEST); +} + int RdbHelperTestOpenCallback::OnCreate(RdbStore &store) { return store.ExecuteSql(CREATE_TABLE_TEST); } +int RdbHelperTestWrongSqlOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) +{ + return E_OK; +} + int RdbHelperTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) { return E_OK; @@ -98,7 +119,7 @@ HWTEST_F(RdbHelperTest, DeleteDatabaseCache_001, TestSize.Level1) { int errCode = E_OK; RdbStoreConfig config(RdbHelperTest::rdbStorePath); - RdbHelperTestOpenCallback helper; + RdbHelperTestWrongSqlOpenCallback helper; std::shared_ptr rdbStore = RdbHelper::GetRdbStore(config, 1, helper, errCode); EXPECT_EQ(rdbStore, nullptr); } @@ -110,8 +131,19 @@ HWTEST_F(RdbHelperTest, DeleteDatabaseCache_001, TestSize.Level1) */ HWTEST_F(RdbHelperTest, DeleteDatabase_001, TestSize.Level1) { - int ret = RdbHelper::DeleteRdbStore("test"); - EXPECT_EQ(ret, E_OK); + int errCode = E_OK; + RdbStoreConfig config1(RdbHelperTest::rdbStorePath); + RdbStoreConfig config2("test"); + RdbStoreConfig config3(""); + RdbHelperTestOpenCallback helper; + std::shared_ptr rdbStore = RdbHelper::GetRdbStore(config1, 1, helper, errCode); + EXPECT_NE(rdbStore, nullptr); + int ret1 = RdbHelper::DeleteRdbStore(config1); + EXPECT_EQ(ret1, E_OK); + int ret2 = RdbHelper::DeleteRdbStore(config2); + EXPECT_EQ(ret2, E_OK); + int ret3 = RdbHelper::DeleteRdbStore(config3); + EXPECT_EQ(ret3, E_INVALID_FILE_PATH); } /** @@ -128,3 +160,56 @@ HWTEST_F(RdbHelperTest, GetDatabase_001, TestSize.Level0) EXPECT_EQ(store, nullptr); EXPECT_EQ(errCode, E_INVALID_FILE_PATH); } + +HWTEST_F(RdbHelperTest, GetDatabase_002, TestSize.Level0) +{ + const std::string dbPath = RDB_TEST_PATH + "GetDatabase.db"; + RdbStoreConfig config(dbPath); + std::string bundleName = "com.ohos.config.GetDatabase"; + config.SetBundleName(bundleName); + config.SetSecurityLevel(SecurityLevel::S1); + config.SetArea(1); + config.SetEncryptStatus(true); + + RdbHelper::DeleteRdbStore(config); + + int errCode = E_OK; + + RdbHelperTestOpenCallback helper; + std::shared_ptr rdbStore1 = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(rdbStore1, nullptr); + + std::shared_ptr rdbStore2 = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(rdbStore2, nullptr); + + EXPECT_EQ(rdbStore1, rdbStore2); +} + +HWTEST_F(RdbHelperTest, GetDatabase_003, TestSize.Level0) +{ + const std::string dbPath = RDB_TEST_PATH + "GetDatabase.db"; + RdbStoreConfig config(dbPath); + std::string bundleName = "com.ohos.config.GetDatabase"; + config.SetBundleName(bundleName); + config.SetSecurityLevel(SecurityLevel::S1); + config.SetArea(1); + config.SetEncryptStatus(true); + + RdbHelper::DeleteRdbStore(config); + + int errCode = E_OK; + + RdbHelperTestOpenCallback helper; + std::shared_ptr rdbStore1 = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(rdbStore1, nullptr); + + config.SetSecurityLevel(SecurityLevel::S2); + std::shared_ptr rdbStore2 = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(rdbStore2, nullptr); + + EXPECT_NE(rdbStore1, rdbStore2); +} \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp b/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp index 22094b12..3f47bd56 100644 --- a/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp @@ -21,6 +21,7 @@ #include "common.h" #include "rdb_errno.h" +#include "file_ex.h" using namespace testing::ext; using namespace OHOS::NativeRdb; @@ -99,4 +100,24 @@ HWTEST_F(RdbSecurityManagerTest, LockUnlock, TestSize.Level1) ASSERT_TRUE(afterUnlock); thread.join(); } + +/** + * @tc.name: LoadSecretKeyFromDiskTest + * @tc.desc: test load secret key from disk test + * @tc.type: FUNC + */ +HWTEST_F(RdbSecurityManagerTest, LoadSecretKeyFromDiskTest, TestSize.Level1) +{ + std::string name = "secret_key_load_test"; + auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key"; + RdbSecurityManager::KeyFiles keyFile(keyPath); + + const std::string file = keyFile.GetKeyFile(RdbSecurityManager::KeyFileType::PUB_KEY_FILE); + std::vector content = { 'a' }; + bool ret = OHOS::SaveBufferToFile(file, content); + ASSERT_TRUE(ret); + RdbPassword pwd = + RdbSecurityManager::GetInstance().GetRdbPassword(keyPath, RdbSecurityManager::KeyFileType::PUB_KEY_FILE); + ASSERT_EQ(pwd.GetSize(), 0); +} } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp new file mode 100644 index 00000000..0207f442 --- /dev/null +++ b/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rdb_store_impl.h" + +#include + +#include +#include +#include + +#include "common.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" + +using namespace testing::ext; +using namespace OHOS::NativeRdb; + +class RdbStoreBackupRestoreTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp() {} + void TearDown() {} + void CheckResultSet(std::shared_ptr &store); + void CheckAge(std::shared_ptr &resultSet); + void CheckSalary(std::shared_ptr &resultSet); + void CheckBlob(std::shared_ptr &resultSet); + + static constexpr char DATABASE_NAME[] = "/data/test/backup_restore_test.db"; + static constexpr char BACKUP_DATABASE_NAME[] = "/data/test/backup_restore_test_backup.db"; +}; + +class RdbStoreBackupRestoreTestOpenCallback : public RdbOpenCallback { +public: + int OnCreate(RdbStore &store) override; + int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override; + static const std::string CREATE_TABLE_TEST; +}; + +const std::string RdbStoreBackupRestoreTestOpenCallback::CREATE_TABLE_TEST = + std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER, salary " + "REAL, blobType BLOB)"); + +int RdbStoreBackupRestoreTestOpenCallback::OnCreate(RdbStore &store) +{ + return store.ExecuteSql(CREATE_TABLE_TEST); +} + +int RdbStoreBackupRestoreTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) +{ + return E_OK; +} + +void RdbStoreBackupRestoreTest::CheckResultSet(std::shared_ptr &store) +{ + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + EXPECT_NE(resultSet, nullptr); + + int columnIndex; + int intVal; + std::string strVal; + ColumnType columnType; + int position; + int ret = resultSet->GetRowIndex(position); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(position, -1); + + ret = resultSet->GetColumnType(0, columnType); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + + ret = resultSet->GetColumnIndex("id", columnIndex); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnIndex, 0); + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER); + ret = resultSet->GetInt(columnIndex, intVal); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, intVal); + + ret = resultSet->GetColumnIndex("name", columnIndex); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnType, ColumnType::TYPE_STRING); + ret = resultSet->GetString(columnIndex, strVal); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ("zhangsan", strVal); + + CheckAge(resultSet); + CheckSalary(resultSet); + CheckBlob(resultSet); + + ret = resultSet->GoToNextRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +void RdbStoreBackupRestoreTest::CheckAge(std::shared_ptr &resultSet) +{ + int columnIndex; + int intVal; + ColumnType columnType; + int ret = resultSet->GetColumnIndex("age", columnIndex); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER); + ret = resultSet->GetInt(columnIndex, intVal); + EXPECT_EQ(ret, E_OK); + // 18: age is 18 + EXPECT_EQ(18, intVal); +} + +void RdbStoreBackupRestoreTest::CheckSalary(std::shared_ptr &resultSet) +{ + int columnIndex; + double dVal; + ColumnType columnType; + int ret = resultSet->GetColumnIndex("salary", columnIndex); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT); + ret = resultSet->GetDouble(columnIndex, dVal); + EXPECT_EQ(ret, E_OK); + // 100.5: salary is 100.5 + EXPECT_EQ(100.5, dVal); +} + +void RdbStoreBackupRestoreTest::CheckBlob(std::shared_ptr &resultSet) +{ + int columnIndex; + std::vector blob; + ColumnType columnType; + int ret = resultSet->GetColumnIndex("blobType", columnIndex); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(columnType, ColumnType::TYPE_BLOB); + ret = resultSet->GetBlob(columnIndex, blob); + EXPECT_EQ(ret, E_OK); + // 3: blob size + EXPECT_EQ(3, static_cast(blob.size())); + // 1: blob[0] is 1 + EXPECT_EQ(1, blob[0]); + // 2: blob[1] is 2 + EXPECT_EQ(2, blob[1]); + // 3: blob[2] is 3 + EXPECT_EQ(3, blob[2]); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_001 + * @tc.desc: backup and restore + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_001, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); + values.PutDouble("salary", 100.5); + values.PutBlob("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + int deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + CheckResultSet(store); + + RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::DATABASE_NAME); + RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::BACKUP_DATABASE_NAME); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_002 + * @tc.desc: backup and restore for broken original and broken backup db + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_002, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(DATABASE_NAME); + config.SetEncryptStatus(true); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); + values.PutDouble("salary", 100.5); + values.PutBlob("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + store = nullptr; + + std::ofstream fsDb(DATABASE_NAME, std::ios_base::binary | std::ios_base::out); + fsDb.seekp(64); + fsDb.write("hello", 5); + fsDb.close(); + std::ofstream fsBackupDb(BACKUP_DATABASE_NAME, std::ios_base::binary | std::ios_base::out); + fsBackupDb.seekp(64); + fsBackupDb.write("hello", 5); + fsBackupDb.close(); + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_SQLITE_CORRUPT); + RdbHelper::DeleteRdbStore(DATABASE_NAME); + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_SQLITE_CORRUPT); + + ret = store->ExecuteSql(RdbStoreBackupRestoreTestOpenCallback::CREATE_TABLE_TEST); + EXPECT_EQ(ret, E_OK); + + RdbHelper::DeleteRdbStore(DATABASE_NAME); + RdbHelper::DeleteRdbStore(BACKUP_DATABASE_NAME); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_003 + * @tc.desc: backup and restore + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_003, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetAllowRebuild(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); + values.PutDouble("salary", 100.5); + values.PutBlob("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + int deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + CheckResultSet(store); + + RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::DATABASE_NAME); + RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::BACKUP_DATABASE_NAME); +} diff --git a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp index 504fe8c8..767de0e4 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp @@ -784,4 +784,75 @@ HWTEST_F(RdbStoreImplTest, UnlockCloudContainerTest, TestSize.Level2) EXPECT_NE(E_OK, result); store = nullptr; RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); +} + +/* * + * @tc.name: LockCloudContainerTest001 + * @tc.desc: lock cloudContainer testCase + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreImplTest, LockCloudContainerTest001, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME); + config.SetName("RdbStore_impl_test.db"); + config.SetBundleName("com.example.distributed.rdb"); + RdbStoreImplTestOpenCallback helper; + std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + ASSERT_NE(store, nullptr); + EXPECT_EQ(E_OK, errCode); + // GetRdbService succeeded if configuration file has already been configured + auto ret = store->RdbStore::LockCloudContainer(); + EXPECT_EQ(E_OK, ret.first); + EXPECT_EQ(0, ret.second); + store = nullptr; + RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); +} + +/* * + * @tc.name: UnlockCloudContainerTest001 + * @tc.desc: unlock cloudContainer testCase + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreImplTest, UnlockCloudContainerTest001, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME); + config.SetName("RdbStore_impl_test.db"); + config.SetBundleName("com.example.distributed.rdb"); + RdbStoreImplTestOpenCallback helper; + std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + ASSERT_NE(store, nullptr); + EXPECT_EQ(E_OK, errCode); + // GetRdbService succeeded if configuration file has already been configured + auto result = store->RdbStore::UnlockCloudContainer(); + EXPECT_EQ(E_OK, result); + store = nullptr; + RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); +} + +/* * + * @tc.name: SetSearchableTest + * @tc.desc: SetSearchable testCase + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreImplTest, SetSearchableTest, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME); + config.SetBundleName(""); + RdbStoreImplTestOpenCallback helper; + std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(E_OK, errCode); + + int result = store->SetSearchable(true); + EXPECT_EQ(E_INVALID_ARGS, result); + RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); + + config.SetBundleName("com.example.distributed.rdb"); + EXPECT_EQ(E_OK, errCode); + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(E_OK, errCode); + result = store->SetSearchable(true); + EXPECT_EQ(E_OK, result); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp index ffcbe105..f022abb7 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp @@ -143,6 +143,7 @@ void SubObserver::OnChange(const Origin &origin, const PrimaryFields &fields, Rd void SubObserver::OnChange() { + count++; const std::string CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test " "(id INTEGER PRIMARY KEY AUTOINCREMENT, " "name TEXT NOT NULL, age INTEGER, salary " @@ -150,14 +151,14 @@ void SubObserver::OnChange() RdbStoreSubTest::store->ExecuteSql(CREATE_TABLE_TEST); ValuesBucket values; int64_t id; - values.PutInt("id", 1); + values.PutInt("id", count); values.PutString("name", std::string("zhangsan")); values.PutInt("age", 18); values.PutDouble("salary", 100.5); values.PutBlob("blobType", std::vector{ 1, 2, 3 }); int ret = RdbStoreSubTest::store->Insert(id, "test", values); EXPECT_EQ(ret, E_OK); - EXPECT_EQ(1, id); + EXPECT_EQ(count, id); } void SubObserver::RegisterCallback(const CheckOnChangeFunc &callback) @@ -224,7 +225,9 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeRemote, TestSize.Level1) { EXPECT_NE(store, nullptr) << "store is null"; EXPECT_NE(observer_, nullptr) << "observer is null"; - auto status = store->Subscribe({ SubscribeMode::REMOTE }, observer_.get()); + auto status = store->Subscribe({ SubscribeMode::REMOTE, "observer" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::REMOTE, "observer" }, observer_.get()); EXPECT_EQ(status, E_OK); } @@ -239,7 +242,9 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeCloud, TestSize.Level1) { EXPECT_NE(store, nullptr) << "store is null"; EXPECT_NE(observer_, nullptr) << "observer is null"; - auto status = store->Subscribe({ SubscribeMode::CLOUD }, observer_.get()); + auto status = store->Subscribe({ SubscribeMode::CLOUD, "observer" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::CLOUD, "observer" }, observer_.get()); EXPECT_EQ(status, E_OK); } @@ -254,7 +259,9 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeCloudDetail, TestSize.Level1) { EXPECT_NE(store, nullptr) << "store is null"; EXPECT_NE(observer_, nullptr) << "observer is null"; - auto status = store->Subscribe({ SubscribeMode::CLOUD_DETAIL }, observer_.get()); + auto status = store->Subscribe({ SubscribeMode::CLOUD_DETAIL, "observer" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::CLOUD_DETAIL, "observer" }, observer_.get()); EXPECT_EQ(status, E_OK); } @@ -269,16 +276,59 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeLocal, TestSize.Level1) { EXPECT_NE(store, nullptr) << "store is null"; EXPECT_NE(observer_, nullptr) << "observer is null"; - auto status = store->Subscribe({ SubscribeMode::LOCAL, "observer" }, observer_.get()); + auto status = store->Subscribe({ SubscribeMode::LOCAL, "observer1" }, observer_.get()); + store->Subscribe({ SubscribeMode::LOCAL, "observer1" }, observer_.get()); + EXPECT_EQ(status, E_OK); + store->Subscribe({ SubscribeMode::LOCAL, "observer2" }, observer_.get()); EXPECT_EQ(status, E_OK); - status = store->Notify("observer"); + status = store->Notify("observer1"); EXPECT_EQ(status, E_OK); + status = store->Notify("observer2"); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(observer_->count, 2); std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); int count; resultSet->GetRowCount(count); - EXPECT_EQ(1, count); + EXPECT_EQ(observer_->count, count); + status = store->UnSubscribe({ SubscribeMode::LOCAL, "nonexistent" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL, "observer1" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL, "nonexistent" }, nullptr); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL, "observer2" }, nullptr); + EXPECT_EQ(status, E_OK); + status = store->Notify("observer1"); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeLocalShared + * @tc.desc: RdbStoreSubscribe + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeLocalShared, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(observer_, nullptr) << "observer is null"; + auto status = store->Subscribe({ SubscribeMode::LOCAL_SHARED, "observer1" }, observer_.get()); + store->Subscribe({ SubscribeMode::LOCAL_SHARED, "observer1" }, observer_.get()); + EXPECT_EQ(status, E_OK); + store->Subscribe({ SubscribeMode::LOCAL_SHARED, "observer2" }, observer_.get()); + EXPECT_EQ(status, E_OK); + + status = store->UnSubscribe({ SubscribeMode::LOCAL_SHARED, "nonexistent" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL_SHARED, "observer1" }, observer_.get()); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL_SHARED, "nonexistent" }, nullptr); + EXPECT_EQ(status, E_OK); + status = store->UnSubscribe({ SubscribeMode::LOCAL_SHARED, "observer2" }, nullptr); + EXPECT_EQ(status, E_OK); } /** @@ -501,6 +551,10 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeLocalDetail005, TestSize.Level1) EXPECT_EQ(observer_->count, 1); status = store->UnsubscribeObserver({ SubscribeMode::LOCAL_DETAIL, "dataChange" }, observer_); EXPECT_EQ(status, E_OK); + status = store->SubscribeObserver({ SubscribeMode::LOCAL_DETAIL, "dataChange" }, observer_); + EXPECT_EQ(status, E_OK); + status = store->UnsubscribeObserver({ SubscribeMode::LOCAL_DETAIL, "dataChange" }, nullptr); + EXPECT_EQ(status, E_OK); observer_->RegisterCallback(nullptr); } diff --git a/relational_store/test/native/rdb/unittest/rdb_update_test.cpp b/relational_store/test/native/rdb/unittest/rdb_update_test.cpp index 6619c44d..83319dff 100644 --- a/relational_store/test/native/rdb/unittest/rdb_update_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_update_test.cpp @@ -50,9 +50,14 @@ public: }; const std::string UpdateTestOpenCallback::CREATE_TABLE_TEST = - std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, " - "name TEXT UNIQUE, age INTEGER, salary " - "REAL, blobType BLOB)"); + std::string("CREATE TABLE IF NOT EXISTS test (") + + std::string("id INTEGER PRIMARY KEY AUTOINCREMENT, ") + + std::string("name TEXT UNIQUE, ") + + std::string("age INTEGER, ") + + std::string("salary REAL, ") + + std::string("blobType BLOB, ") + + std::string("assetType ASSET, ") + + std::string("assetsType ASSETS)"); int UpdateTestOpenCallback::OnCreate(RdbStore &store) { @@ -286,6 +291,162 @@ HWTEST_F(RdbStoreUpdateTest, RdbStore_Update_006, TestSize.Level1) EXPECT_EQ(ret, E_OK); } +/** + * @tc.name: RdbStore_Update_007 + * @tc.desc: test RdbStore update asset + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreUpdateTest, RdbStore_Update_007, TestSize.Level1) +{ + std::shared_ptr &store = RdbStoreUpdateTest::store; + ValuesBucket values; + AssetValue value{ .version = 1, .name = "123", .uri = "your test path", .createTime = "13", .modifyTime = "13" }; + int changedRows; + int64_t id; + values.PutNull("assetType"); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(3, id); + values.Clear(); + values.Put("assetType", value); + ret = store->Update(changedRows, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, changedRows); + std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + + RdbStoreUpdateTest::ExpectValue(resultSet, RowData{ .id = 3, + .asset{ .version = 1, + .status = AssetValue::STATUS_INSERT, + .name = "123", + .uri = "your test path", + .createTime = "13", + .modifyTime = "13" + } }); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/** + * @tc.name: RdbStore_Update_008 + * @tc.desc: test RdbStore update asset + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreUpdateTest, RdbStore_Update_008, TestSize.Level1) +{ + std::shared_ptr &store = RdbStoreUpdateTest::store; + ValuesBucket values; + AssetValue valueDef{ + .version = 0, + .name = "123", + .uri = "my test path", + .createTime = "12", + .modifyTime = "12", + }; + AssetValue value{ .version = 2, .name = "456", .uri = "your test path", .createTime = "15", .modifyTime = "15" }; + int changedRows; + int64_t id; + values.Put("assetType", valueDef); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(4, id); + values.Clear(); + values.Put("assetType", value); + ret = store->Update(changedRows, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, changedRows); + std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + RdbStoreUpdateTest::ExpectValue(resultSet, + RowData{ .id = 4, + .asset{ .version = 0, .name = "123", .uri = "my test path", .createTime = "12", .modifyTime = "12" } }); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/** + * @tc.name: RdbStore_Update_009 + * @tc.desc: test RdbStore update asset + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreUpdateTest, RdbStore_Update_009, TestSize.Level1) +{ + std::shared_ptr &store = RdbStoreUpdateTest::store; + ValuesBucket values; + AssetValue valueDef{ .version = 0, + .status = AssetValue::STATUS_NORMAL, + .name = "123", + .uri = "my test path", + .createTime = "12", + .modifyTime = "12", + .size = "543", + .hash = "321" }; + AssetValue value{ .name = "123" }; + value.status = AssetValue::STATUS_DELETE; + int changedRows; + int64_t id; + values.Put("assetType", valueDef); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(5, id); + values.Clear(); + values.Put("assetType", value); + ret = store->Update(changedRows, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, changedRows); + std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + RdbStoreUpdateTest::ExpectValue(resultSet, RowData{ .id = 5, + .asset{ .version = 0, + .status = AssetValue::Status::STATUS_DELETE, + .name = "123", + .uri = "my test path", + .createTime = "12", + .modifyTime = "", + .size = "", + .hash = "" } }); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/** + * @tc.name: RdbStore_Update_010 + * @tc.desc: test RdbStore update assets + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreUpdateTest, RdbStore_Update_010, TestSize.Level1) +{ + std::shared_ptr &store = RdbStoreUpdateTest::store; + ValuesBucket values; + std::vector assetsDef{ + { .version = 0, .name = "123", .uri = "my test path", .createTime = "12", .modifyTime = "12" } + }; + AssetValue value1{ .version = 1, .name = "123", .uri = "your test path", .createTime = "13", .modifyTime = "13" }; + AssetValue value2{ .version = 2, .name = "123", .uri = "your test path", .createTime = "14", .modifyTime = "14" }; + AssetValue value3{ .version = 3, .name = "456", .uri = "your test path", .createTime = "15", .modifyTime = "15" }; + auto assets = ValueObject::Assets({ value1, value2, value3 }); + int changedRows; + int64_t id; + values.Put("assetsType", assetsDef); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(6, id); + values.Clear(); + values.Put("assetsType", assets); + + ret = store->Update(changedRows, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, changedRows); +} + /** * @tc.name: RdbStore_UpdateWithConflictResolution_001 * @tc.desc: test RdbStore UpdateWithConflictResolution diff --git a/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp b/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp index 36334aba..a66d7b45 100644 --- a/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp @@ -52,26 +52,6 @@ HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_001, TestSize.Level1) EXPECT_EQ(true, SqliteUtils::IsSpecial(7)); } -/** - * @tc.name: RdbStore_SqliteUtils_002 - * @tc.desc: Abnormal testCase of sqlite_utils for Anonymous, if len(srcFile) < HEAD_SIZE - * @tc.type: FUNC - */ -HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_002, TestSize.Level2) -{ - EXPECT_EQ("******", SqliteUtils::Anonymous("ac")); -} - -/** - * @tc.name: RdbStore_SqliteUtils_003 - * @tc.desc: Abnormal testCase of sqlite_utils for Anonymous, if len(srcFile) < MIN_SIZE - * @tc.type: FUNC - */ -HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_003, TestSize.Level2) -{ - EXPECT_EQ("abc***", SqliteUtils::Anonymous("abc/def")); -} - /** * @tc.name: RdbStore_SqliteUtils_004 * @tc.desc: Abnormal testCase of string_utils for SurroundWithQuote, if value is "" diff --git a/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp b/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp new file mode 100644 index 00000000..0cebc8f9 --- /dev/null +++ b/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sqlite_utils.h" + +#include + +#include +#include + +using namespace testing::ext; +using namespace OHOS::NativeRdb; + +class SqliteUtilsTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(void){}; + void TearDown(void){}; +}; + +void SqliteUtilsTest::SetUpTestCase(void) +{ +} + +void SqliteUtilsTest::TearDownTestCase(void) +{ +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_001, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("30005245854585524412855412_rdb_test.db"), "***5412_rdb_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_002, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("rdb_test_30005245854585524412855412.db"), "rdb_test_***5412.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_003, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("rdb_30005245854585524412855412_test.db"), "rdb_***5412_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_004, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("rdb_300052_test.db"), "rdb_***052_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_005, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("rdb_30005_test.db"), "rdb_***005_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_006, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("rdb_3000523_test.db"), "rdb_***0523_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_007, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous( + "file /data/stage/el2/database/rdb/ddddddd/30005245854585524412855412_rdb_test.db"), + "file /***/el2/***/***5412_rdb_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_008, TestSize.Level1) +{ + EXPECT_EQ( + SqliteUtils::Anonymous("file /data/stage/database/rdb/ddddddd/30005245854585524412855412_rdb_test.db"), + "file /***/***5412_rdb_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_009, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous( + "file /data/stage/el2/database/rdb/ddddddd/3E00mnj5H54efg5G4K1ABC5412_rdb_test.db"), + "file /***/el2/***/3E00mnj5H54efg5G4K***5412_rdb_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_010, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("/data/stage/el2/database/rdb/ddddddd/3E00mnj5H54efg5G4K1ABC5412_rdb_test.db"), + "/***/el2/***/3E00mnj5H54efg5G4K***5412_rdb_test.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0011, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("30005245854585524412855412.db"), "***5412.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0012, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("thequickbrownfoxjumpoverthelazydog.db"), "thequickbrownfoxjumpoverthelazydog.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0013, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("123edf4.db"), "***edf4.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0014, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("K123edfK.db"), "K***edfK.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0015, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("K23edfK.db"), "K***edfK.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0016, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("__23edf__.db"), "__***edf__.db"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0017, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::Anonymous("K3edfK.db"), "K3edfK.db"); +} \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 601f86cb..c219bebd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -152,7 +152,7 @@ target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../udmf/framework/innerkitsimpl/test/unittest UdmfTestSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../udmf/framework/innerkitsimpl/test/unittest/mock UdmfTestSrc) add_executable(UdmfTest ${UdmfTestSrc} ${mainSrc} ${serviceSrc}) -target_link_libraries(UdmfTest ${links} gtest_main gcov gmock udmf) +target_link_libraries(UdmfTest ${links} gtest_main gcov gmock udmf udmf_ndk) target_include_directories(UdmfTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../udmf/framework/common) target_include_directories(UdmfTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../udmf/framework/innerkitsimpl/data) target_include_directories(UdmfTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../udmf/framework/innerkitsimpl/service) diff --git a/udmf/CMakeLists.txt b/udmf/CMakeLists.txt index 36985223..ba53702c 100644 --- a/udmf/CMakeLists.txt +++ b/udmf/CMakeLists.txt @@ -49,4 +49,6 @@ add_library(udmf_channel SHARED ${udmf_channel_src}) target_link_libraries(udmf_channel mock udmf) add_library(udmf_ndk SHARED ${udmf_ndk_src}) -target_link_libraries(udmf_ndk mock udmf) \ No newline at end of file +target_link_libraries(udmf_ndk mock udmf) +target_include_directories(udmf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/ndk/data) +target_include_directories(udmf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/framework/ndkimpl/data) \ No newline at end of file diff --git a/udmf/bundle.json b/udmf/bundle.json index 7f913248..11cd8805 100644 --- a/udmf/bundle.json +++ b/udmf/bundle.json @@ -49,7 +49,9 @@ }, "build": { "sub_component": [ - "//foundation/distributeddatamgr/udmf:udmf_packages" + "//foundation/distributeddatamgr/udmf:udmf_packages", + "//foundation/distributeddatamgr/udmf/interfaces/cj:cj_unified_data_channel_ffi", + "//foundation/distributeddatamgr/udmf/interfaces/cj:cj_uniform_type_descriptor_ffi" ], "inner_kits": [ { diff --git a/udmf/framework/common/graph.cpp b/udmf/framework/common/graph.cpp index 8d34a8b5..3cc46db7 100644 --- a/udmf/framework/common/graph.cpp +++ b/udmf/framework/common/graph.cpp @@ -26,7 +26,7 @@ Graph::Graph(uint32_t vertexNum):vertexNum_(vertexNum) Graph::~Graph() { - for (auto &vertexNode : adjList_) { + for (const auto &vertexNode : adjList_) { EdgeNode *edge = vertexNode.firstEdge; while (edge != nullptr) { EdgeNode *nextEdge = edge->next; diff --git a/udmf/framework/common/tlv_object.cpp b/udmf/framework/common/tlv_object.cpp index b49a8c64..f68df376 100644 --- a/udmf/framework/common/tlv_object.cpp +++ b/udmf/framework/common/tlv_object.cpp @@ -4,7 +4,7 @@ * 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 + * 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, @@ -30,6 +30,17 @@ TLVObject::TLVObject(std::vector &buffer) void TLVObject::SetFile(std::FILE *file) { file_ = file; + if (fseek(file_, 0, SEEK_END) != 0) { + LOG_ERROR(UDMF_SERVICE, "fseek to end error!"); + } + + auto total = ftell(file_); + if (total < 0) { + LOG_ERROR(UDMF_SERVICE, "Values are out of range, total:%{public}ld", total); + return; + } + total_ = static_cast(total); + ResetCursor(); } void TLVObject::UpdateSize() @@ -45,1078 +56,333 @@ std::vector TLVObject::GetBuffer() return *buffer_; } -void TLVObject::Count(const uint32_t value) +size_t TLVObject::GetTotal() { - total_ += sizeof(value) + sizeof(TLVHead); + return total_; } -void TLVObject::Count(const uint64_t value) +size_t TLVObject::GetCursor() { - total_ += sizeof(value) + sizeof(TLVHead); + return cursor_; } -void TLVObject::Count(const int32_t value) +size_t TLVObject::OffsetHead() { - total_ += sizeof(value) + sizeof(TLVHead); -} - -void TLVObject::Count(const int64_t value) -{ - total_ += sizeof(value) + sizeof(TLVHead); -} - -void TLVObject::Count(const float value) -{ - total_ += sizeof(value) + sizeof(TLVHead); -} - -void TLVObject::Count(const double value) -{ - total_ += sizeof(value) + sizeof(TLVHead); -} - -void TLVObject::Count(const std::string &value) -{ - total_ += value.size() + sizeof(TLVHead); -} - -void TLVObject::Count(const std::vector &value) -{ - std::size_t expectSize = sizeof(TLVHead); - expectSize += value.size(); - total_ += expectSize; -} - -void TLVObject::Count(const UDVariant &value) -{ - total_ += sizeof(TLVHead); - auto int32Value = std::get_if(&value); - if (int32Value != nullptr) { - Count(std::get(value)); - return; - } - auto int64Value = std::get_if(&value); - if (int64Value != nullptr) { - Count(std::get(value)); - return; - } - auto boolValue = std::get_if(&value); - if (boolValue != nullptr) { - Count(std::get(value)); - return; - } - auto doubleValue = std::get_if(&value); - if (doubleValue != nullptr) { - Count(std::get(value)); - return; - } - auto strValue = std::get_if(&value); - if (strValue != nullptr) { - Count(std::get(value)); - return; - } - auto vecValue = std::get_if>(&value); - if (vecValue != nullptr) { - Count(std::get>(value)); - return; - } - total_ += sizeof(TLVHead); -} - -void TLVObject::Count(const ValueType &value) -{ - total_ += sizeof(TLVHead); - auto int32Value = std::get_if(&value); - if (int32Value != nullptr) { - Count(std::get(value)); - return; - } - auto int64Value = std::get_if(&value); - if (int64Value != nullptr) { - Count(std::get(value)); - return; - } - auto boolValue = std::get_if(&value); - if (boolValue != nullptr) { - Count(std::get(value)); - return; - } - auto doubleValue = std::get_if(&value); - if (doubleValue != nullptr) { - Count(std::get(value)); - return; - } - auto strValue = std::get_if(&value); - if (strValue != nullptr) { - Count(std::get(value)); - return; - } - auto vecValue = std::get_if>(&value); - if (vecValue != nullptr) { - Count(std::get>(value)); - return; - } - auto wantValue = std::get_if>(&value); - if (wantValue != nullptr) { - Count(std::get>(value)); - return; - } - auto pixelMapValue = std::get_if>(&value); - if (pixelMapValue != nullptr) { - Count(std::get>(value)); - return; - } - auto objectValue = std::get_if>(&value); - if (objectValue != nullptr) { - Count(std::get>(value)); - return; - } - auto undefinedValue = std::get_if(&value); - if (undefinedValue != nullptr) { - Count(std::get(value)); - return; - } - auto nullValue = std::get_if(&value); - if (nullValue != nullptr) { - Count(std::get(value)); - return; + if (file_ != nullptr) { + if (fseek(file_, sizeof(TLVHead), SEEK_CUR) != 0) { + LOG_ERROR(UDMF_SERVICE, "OffsetHead file error!"); + return 0; + } } - total_ += sizeof(TLVHead); + cursor_ += sizeof(TLVHead); + return cursor_; } -void TLVObject::Count(const UDDetails &value) +void TLVObject::ResetCursor() { - for (auto &item : value) { - Count(item.first); - Count(item.second); + cursor_ = 0; + if (file_ != nullptr) { + if (fseek(file_, 0, SEEK_SET) != 0) { + LOG_ERROR(UDMF_SERVICE, "ResetCursor file error!"); + } } - total_ += sizeof(TLVHead); } -void TLVObject::Count(const UnifiedKey &value) +size_t TLVObject::Count(const std::string &value) { - Count(value.key); - Count(value.intention); - Count(value.bundleName); - Count(value.groupId); + auto size = sizeof(TLVHead) + value.size(); + total_ += size; + return size; } -void TLVObject::Count(const Privilege &value) +size_t TLVObject::Count(const std::vector &value) { - Count(value.tokenId); - Count(value.readPermission); - Count(value.writePermission); + auto size = sizeof(TLVHead) + value.size(); + total_ += size; + return size; } -void TLVObject::Count(const std::shared_ptr &value) +size_t TLVObject::Count(const OHOS::AAFwk::Want &value) { - std::size_t expectSize = sizeof(TLVHead); Parcel parcel; - if (!value->Marshalling(parcel)) { - LOG_ERROR(TlvObject, "Marshalling Want failed."); - return; + if (!value.Marshalling(parcel)) { + LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count"); + return 0; } - expectSize += parcel.GetDataSize(); - total_ += expectSize; + auto size = sizeof(TLVHead) + parcel.GetDataSize(); + total_ += size; + return size; } -void TLVObject::Count(const std::shared_ptr &value) +size_t TLVObject::Count(const std::monostate &value) { - std::size_t expectSize = sizeof(TLVHead); - std::vector val; - if (!value->EncodeTlv(val)) { - LOG_ERROR(TlvObject, "Marshalling PixelMap failed."); - return; - } - expectSize += val.size(); - total_ += expectSize; + auto size = sizeof(TLVHead); + total_ += size; + return size; } -void TLVObject::Count(const std::shared_ptr &value) +size_t TLVObject::Count(const void *value) { - for (auto &item : value->value_) { - Count(item.first); - Count(item.second); - } - total_ += sizeof(TLVHead); -} - -void TLVObject::Count(const std::monostate &value) -{ - total_ += sizeof(TLVHead); -} - -void TLVObject::Count(const void *value) -{ - total_ += sizeof(TLVHead); + auto size = sizeof(TLVHead); + total_ += size; + return size; } -bool TLVObject::WriteString(const std::string &value) +bool TLVObject::Write(TAG tag, const std::string &value) { - PrepareBuffer(sizeof(TLVHead) + value.size()); if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write. tag=%{public}hu, value=%{public}s", tag, + value.c_str()); return false; } - auto *tlvHead = reinterpret_cast(buffer_->data() + cursor_); - tlvHead->tag = HostToNet(static_cast(TAG::TAG_STRING)); + auto tlvHead = reinterpret_cast(GetStartCursor()); + tlvHead->tag = HostToNet(static_cast(tag)); tlvHead->len = HostToNet((uint32_t)value.size()); if (!value.empty()) { auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size()); if (err != EOK) { + LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write. tag=%{public}hu, value=%{public}s", tag, + value.c_str()); return false; } } - if (!SaveBufferToFile()) { - return false; - } cursor_ += sizeof(TLVHead) + value.size(); - return true; + return SaveBufferToFile(); } -bool TLVObject::ReadString(std::string &value) +bool TLVObject::Read(std::string &value, const TLVHead &head) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } if (!HasExpectBuffer(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read string. tag=%{public}hu", head.tag); return false; } if (!LoadBufferFormFile(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read string. tag=%{public}hu", head.tag); return false; } - value.append(reinterpret_cast(buffer_->data() + cursor_), head.len); + auto startCursor = GetStartCursor(); + value.append(reinterpret_cast(startCursor), head.len); cursor_ += head.len; - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } return true; } -bool TLVObject::WriteVector(const std::vector &value) +bool TLVObject::Write(TAG tag, const std::vector &value) { - PrepareBuffer(sizeof(TLVHead) + value.size()); if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write u8 vector. tag=%{public}hu", tag); return false; } - WriteHead(static_cast(TAG::TAG_VECTOR), cursor_, value.size()); - cursor_ += sizeof(TLVHead); - + auto tlvHead = reinterpret_cast(GetStartCursor()); + tlvHead->tag = HostToNet(static_cast(tag)); + tlvHead->len = HostToNet(static_cast(value.size())); if (!value.empty()) { - auto err = memcpy_s(buffer_->data() + cursor_, buffer_->size() - cursor_, value.data(), value.size()); + auto err = memcpy_s(tlvHead->value, value.size(), value.data(), value.size()); if (err != EOK) { + LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write u8 vector. tag=%{public}hu", tag); return false; } } - if (!SaveBufferToFile()) { - return false; - } - cursor_ += value.size(); - return true; + cursor_ += sizeof(TLVHead) + value.size(); + return SaveBufferToFile(); } -bool TLVObject::ReadVector(std::vector &value) + +bool TLVObject::Read(std::vector &value, const TLVHead &head) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } if (!HasExpectBuffer(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read u8 vector. tag=%{public}hu", head.tag); return false; } if (!LoadBufferFormFile(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read u8 vector. tag=%{public}hu", head.tag); return false; } - std::vector buff(buffer_->data() + cursor_, buffer_->data() + cursor_ + head.len); + auto startCursor = GetStartCursor(); + std::vector buff(startCursor, startCursor + head.len); value = std::move(buff); cursor_ += head.len; - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } - return true; -} - -bool TLVObject::WriteVariantInner(TAG &tag, const UDVariant &value) -{ - auto int32Value = std::get_if(&value); - if (int32Value != nullptr) { - if (!WriteBasic(TAG::TAG_INT32, std::get(value))) { - return false; - } - tag = TAG::TAG_INT32; - } - auto int64Value = std::get_if(&value); - if (int64Value != nullptr) { - if (!WriteBasic(TAG::TAG_INT64, std::get(value))) { - return false; - } - tag = TAG::TAG_INT64; - } - auto boolValue = std::get_if(&value); - if (boolValue != nullptr) { - if (!WriteBasic(TAG::TAG_BOOL, std::get(value))) { - return false; - } - tag = TAG::TAG_BOOL; - } - auto doubleValue = std::get_if(&value); - if (doubleValue != nullptr) { - if (!WriteBasic(TAG::TAG_DOUBLE, std::get(value))) { - return false; - } - tag = TAG::TAG_DOUBLE; - } - auto stringValue = std::get_if(&value); - if (stringValue != nullptr) { - if (!WriteString(std::get(value))) { - return false; - } - tag = TAG::TAG_STRING; - } - auto vectorValue = std::get_if>(&value); - if (vectorValue != nullptr) { - if (!WriteVector(std::get>(value))) { - return false; - } - tag = TAG::TAG_VECTOR; - } - return true; -} - -bool TLVObject::WriteVariant(const UDVariant &value) -{ - if (!HasExpectBuffer(sizeof(TLVHead))) { - return false; - } - if (file_ != nullptr) { - std::vector reserved {}; - reserved.resize(sizeof(TLVHead)); - if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) { - return false; - } - } - auto tagCursor = cursor_; - cursor_ += sizeof(TLVHead); - auto valueCursor = cursor_; - TAG tag = TAG::TAG_BUTT; - if (!WriteVariantInner(tag, value)) { - return false; - } - if (!PrepareHeader(cursor_, tagCursor, valueCursor)) { - return false; - } - WriteHead(static_cast(tag), tagCursor, cursor_ - valueCursor); - if (!SaveBufferToFile()) { - return false; - } - if (file_ != nullptr) { - fseek(file_, 0, SEEK_END); - cursor_ += sizeof(TLVHead); - } - return true; -} - -bool TLVObject::ReadVariantInner(uint16_t tag, UDVariant &value) -{ - switch (tag) { - case static_cast(TAG::TAG_INT32): { - int32_t int32Value; - if (!ReadBasic(int32Value)) { - return false; - } - value.emplace(int32Value); - break; - } - case static_cast(TAG::TAG_INT64): { - int64_t int64Value; - if (!ReadBasic(int64Value)) { - return false; - } - value.emplace(int64Value); - break; - } - case static_cast(TAG::TAG_BOOL): { - bool boolValue; - if (!ReadBasic(boolValue)) { - return false; - } - value.emplace(boolValue); - break; - } - case static_cast(TAG::TAG_DOUBLE): { - double doubleValue; - if (!ReadBasic(doubleValue)) { - return false; - } - value.emplace(doubleValue); - break; - } - default: { - return false; - } - } - return true; -} - -bool TLVObject::ReadVariant(UDVariant &value) -{ - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - switch (head.tag) { - case static_cast(TAG::TAG_INT32): - case static_cast(TAG::TAG_INT64): - case static_cast(TAG::TAG_BOOL): - case static_cast(TAG::TAG_DOUBLE): { - if (!ReadVariantInner(head.tag, value)) { - return false; - } - break; - } - case static_cast(TAG::TAG_STRING): { - std::string stringValue; - if (!ReadString(stringValue)) { - return false; - } - value.emplace(stringValue); - break; - } - case static_cast(TAG::TAG_VECTOR): { - std::vector vectorValue; - if (!ReadVector(vectorValue)) { - return false; - } - value.emplace>(vectorValue); - break; - } - default: { - return false; - } - } - - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } return true; } -bool TLVObject::WriteVariantInner(TAG &tag, const ValueType &value) -{ - if (std::get_if(&value) != nullptr) { - if (!WriteBasic(TAG::TAG_INT32, std::get(value))) { - return false; - } - tag = TAG::TAG_INT32; - } else if (std::get_if(&value) != nullptr) { - if (!WriteBasic(TAG::TAG_INT64, std::get(value))) { - return false; - } - tag = TAG::TAG_INT64; - } else if (std::get_if(&value) != nullptr) { - if (!WriteBasic(TAG::TAG_BOOL, std::get(value))) { - return false; - } - tag = TAG::TAG_BOOL; - } else if (std::get_if(&value) != nullptr) { - if (!WriteBasic(TAG::TAG_DOUBLE, std::get(value))) { - return false; - } - tag = TAG::TAG_DOUBLE; - } else if (std::get_if(&value) != nullptr) { - if (!WriteString(std::get(value))) { - return false; - } - tag = TAG::TAG_STRING; - } else if (std::get_if>(&value) != nullptr) { - if (!WriteVector(std::get>(value))) { - return false; - } - tag = TAG::TAG_VECTOR; - } else if (std::get_if>(&value) != nullptr) { - if (!WriteWant(std::get>(value))) { - return false; - } - tag = TAG::TAG_WANT; - } else if (std::get_if>(&value) != nullptr) { - if (!WritePixelMap(std::get>(value))) { - return false; - } - tag = TAG::TAG_PIXELMAP; - } else if (std::get_if>(&value) != nullptr) { - if (!WriteObject(std::get>(value))) { - return false; - } - tag = TAG::TAG_OBJECT; - } else if (std::get_if(&value) != nullptr) { - if (!WriteUndefined(std::get(value))) { - return false; - } - tag = TAG::TAG_UNDEFINED; - } else if (std::get_if(&value) != nullptr) { - if (!WriteNull(nullptr)) { - return false; - } - tag = TAG::TAG_NULL; - } - return true; -} - -bool TLVObject::WriteVariant(const ValueType &value) -{ - if (!HasExpectBuffer(sizeof(TLVHead))) { - return false; - } - if (file_ != nullptr) { - std::vector reserved {}; - reserved.resize(sizeof(TLVHead)); - if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) { - return false; - } - } - auto tagCursor = cursor_; - cursor_ += sizeof(TLVHead); - auto valueCursor = cursor_; - TAG tag = TAG::TAG_BUTT; - if (!WriteVariantInner(tag, value)) { - return false; - } - if (!PrepareHeader(cursor_, tagCursor, valueCursor)) { - return false; - } - WriteHead(static_cast(tag), tagCursor, cursor_ - valueCursor); - if (!SaveBufferToFile()) { - return false; - } - if (file_ != nullptr) { - fseek(file_, 0, SEEK_END); - cursor_ += sizeof(TLVHead); - } - return true; -} - -bool TLVObject::ReadVariantInner(uint16_t tag, ValueType &value) -{ - switch (tag) { - case static_cast(TAG::TAG_INT32): { - int32_t int32Value; - if (!ReadBasic(int32Value)) { - return false; - } - value.emplace(int32Value); - break; - } - case static_cast(TAG::TAG_INT64): { - int64_t int64Value; - if (!ReadBasic(int64Value)) { - return false; - } - value.emplace(int64Value); - break; - } - case static_cast(TAG::TAG_BOOL): { - bool boolValue; - if (!ReadBasic(boolValue)) { - return false; - } - value.emplace(boolValue); - break; - } - case static_cast(TAG::TAG_DOUBLE): { - double doubleValue; - if (!ReadBasic(doubleValue)) { - return false; - } - value.emplace(doubleValue); - break; - } - default: { - return false; - } - } - return true; -} - -bool TLVObject::ReadVariant(ValueType &value) -{ - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - switch (head.tag) { - case static_cast(TAG::TAG_INT32): - case static_cast(TAG::TAG_INT64): - case static_cast(TAG::TAG_BOOL): - case static_cast(TAG::TAG_DOUBLE): { - if (!ReadVariantInner(head.tag, value)) { - return false; - } - break; - } - case static_cast(TAG::TAG_STRING): { - std::string stringValue; - if (!ReadString(stringValue)) { - return false; - } - value.emplace(stringValue); - break; - } - case static_cast(TAG::TAG_VECTOR): { - std::vector vectorValue; - if (!ReadVector(vectorValue)) { - return false; - } - value.emplace>(vectorValue); - break; - } - case static_cast(TAG::TAG_WANT): { - std::shared_ptr wantValue = nullptr; - if (!ReadWant(wantValue)) { - return false; - } - value.emplace>(wantValue); - break; - } - case static_cast(TAG::TAG_PIXELMAP): { - std::shared_ptr pixelMapValue = nullptr; - if (!ReadPixelMap(pixelMapValue)) { - return false; - } - value.emplace>(pixelMapValue); - break; - } - case static_cast(TAG::TAG_OBJECT): { - std::shared_ptr objectValue = nullptr; - if (!ReadObject(objectValue)) { - return false; - } - value.emplace>(objectValue); - break; - } - case static_cast(TAG::TAG_UNDEFINED): { - std::monostate monoValue; - if (!ReadUndefined(monoValue)) { - return false; - } - value.emplace(monoValue); - break; - } - case static_cast(TAG::TAG_NULL): { - nullptr_t nullValue = nullptr; - if (!ReadNull(nullValue)) { - return false; - } - value.emplace(nullValue); - break; - } - default: { - return false; - } - } - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } - return true; -} - -bool TLVObject::WriteMap(const UDDetails &value) -{ - if (!HasExpectBuffer(sizeof(TLVHead))) { - return false; - } - if (file_ != nullptr) { - std::vector reserved {}; - reserved.resize(sizeof(TLVHead)); - if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) { - return false; - } - } - - auto tagCursor = cursor_; - cursor_ += sizeof(TLVHead); - auto valueCursor = cursor_; - - size_t total = 0; - for (const auto &item : value) { - if (!WriteString(item.first)) { - return false; - } - total += cursor_; - - if (!WriteVariant(item.second)) { - return false; - } - total += cursor_; - } - if (!PrepareHeader(total, tagCursor, valueCursor)) { - return false; - } - WriteHead(static_cast(TAG::TAG_MAP), tagCursor, cursor_ - valueCursor); - if (!SaveBufferToFile()) { - return false; - } - if (file_ != nullptr) { - fseek(file_, 0, SEEK_END); - } - return true; -} - -bool TLVObject::ReadMap(UDDetails &value) -{ - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - if (file_ != nullptr) { - cursor_ = 0; - } - auto mapEnd = cursor_ + head.len; - size_t total = 0; - while ((file_ == nullptr && cursor_ < mapEnd) || (file_ != nullptr && total < head.len)) { - std::string itemKey = ""; - if (!ReadString(itemKey)) { - return false; - } - total += cursor_; - UDVariant itemValue; - if (!ReadVariant(itemValue)) { - return false; - } - total += cursor_; - value.emplace(itemKey, itemValue); - } - return true; -} - -bool TLVObject::WriteObject(const std::shared_ptr &value) -{ - if (!HasExpectBuffer(sizeof(TLVHead))) { - return false; - } - if (file_ != nullptr) { - std::vector reserved {}; - reserved.resize(sizeof(TLVHead)); - if (fwrite(reserved.data(), sizeof(uint8_t), reserved.size(), file_) != reserved.size()) { - return false; - } - } - - auto tagCursor = cursor_; - cursor_ += sizeof(TLVHead); - auto valueCursor = cursor_; - - size_t total = 0; - for (const auto &item : value->value_) { - if (!WriteString(item.first)) { - return false; - } - total += cursor_; - - if (!WriteVariant(item.second)) { - return false; - } - total += cursor_; - } - if (!PrepareHeader(total, tagCursor, valueCursor)) { - return false; - } - WriteHead(static_cast(TAG::TAG_OBJECT), tagCursor, cursor_ - valueCursor); - if (!SaveBufferToFile()) { - return false; - } - if (file_ != nullptr) { - fseek(file_, 0, SEEK_END); - } - return true; -} - -bool TLVObject::ReadObject(std::shared_ptr &value) -{ - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - if (file_ != nullptr) { - cursor_ = 0; - } - value = std::make_shared(); - auto mapEnd = cursor_ + head.len; - size_t total = 0; - while ((file_ == nullptr && cursor_ < mapEnd) || (file_ != nullptr && total < head.len)) { - std::string itemKey = ""; - if (!ReadString(itemKey)) { - return false; - } - total += cursor_; - ValueType itemValue; - if (!ReadVariant(itemValue)) { - return false; - } - total += cursor_; - value->value_.emplace(itemKey, itemValue); - } - return true; -} - -bool TLVObject::WriteWant(const std::shared_ptr &value) +bool TLVObject::Write(TAG tag, const OHOS::AAFwk::Want &value) { Parcel parcel; - if (!value->Marshalling(parcel)) { - LOG_ERROR(TlvObject, "Marshalling Want failed."); + if (!value.Marshalling(parcel)) { + LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag); return false; } auto size = parcel.GetDataSize(); auto buffer = parcel.GetData(); - PrepareBuffer(sizeof(TLVHead) + size); if (!HasExpectBuffer(sizeof(TLVHead) + size)) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write want. tag=%{public}hu", tag); return false; } - WriteHead(static_cast(TAG::TAG_WANT), cursor_, size); - cursor_ += sizeof(TLVHead); - + auto tlvHead = reinterpret_cast(GetStartCursor()); + tlvHead->tag = HostToNet(static_cast(tag)); + tlvHead->len = HostToNet(static_cast(size)); if (size != 0) { - auto err = memcpy_s(buffer_->data() + cursor_, buffer_->size() - cursor_, - reinterpret_cast(buffer), size); + auto err = memcpy_s(tlvHead->value, size, reinterpret_cast(buffer), size); if (err != EOK) { + LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag); return false; } } - if (SaveBufferToFile()) { - return false; - } - cursor_ += size; - return true; + cursor_ += sizeof(TLVHead) + size; + return SaveBufferToFile(); } -bool TLVObject::ReadWant(std::shared_ptr &value) +bool TLVObject::Read(OHOS::AAFwk::Want &value, const TLVHead &head) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } if (!HasExpectBuffer(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read want. tag=%{public}hu", head.tag); return false; } if (!LoadBufferFormFile(head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read want. tag=%{public}hu", head.tag); return false; } - std::vector buff(buffer_->data() + cursor_, buffer_->data() + cursor_ + head.len); + auto startCursor = GetStartCursor(); + std::vector buff(startCursor, startCursor + head.len); auto buffer = (uintptr_t)(buff.data() + cursor_); cursor_ += head.len; - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } Parcel parcel; if (!parcel.ParseFrom(buffer, head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag); return false; } auto want = AAFwk::Want::Unmarshalling(parcel); if (want == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag); return false; } - value = std::make_shared(*want); + value = *want; return true; } -bool TLVObject::WritePixelMap(const std::shared_ptr &value) +bool TLVObject::Write(TAG tag, const std::monostate &value) { - std::vector val; - if (!value->EncodeTlv(val)) { - return false; - } - - PrepareBuffer(sizeof(TLVHead) + val.size()); - if (!HasExpectBuffer(sizeof(TLVHead) + val.size())) { - return false; - } - WriteHead(static_cast(TAG::TAG_PIXELMAP), cursor_, val.size()); - cursor_ += sizeof(TLVHead); + return WriteHead(static_cast(tag), (uint32_t)0); +} - if (!val.empty()) { - auto err = memcpy_s(buffer_->data() + cursor_, buffer_->size() - cursor_, val.data(), val.size()); - if (err != EOK) { - return false; - } - } - if (!SaveBufferToFile()) { - return false; - } - cursor_ += val.size(); +bool TLVObject::Read(std::monostate &value, const TLVHead &head) +{ return true; } -bool TLVObject::ReadPixelMap(std::shared_ptr &value) +bool TLVObject::Write(TAG tag, const void *value) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - if (!LoadBufferFormFile(head.len)) { - return false; - } - std::vector buff(buffer_->data() + cursor_, buffer_->data() + cursor_ + head.len); - value = std::shared_ptr(OHOS::Media::PixelMap::DecodeTlv(buff)); - - cursor_ += head.len; - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } - return true; + return WriteHead(static_cast(tag), (uint32_t)0); } -bool TLVObject::WriteUndefined(const std::monostate &value) + +bool TLVObject::Read(void *value, const TLVHead &head) { - PrepareBuffer(sizeof(TLVHead)); - if (!HasExpectBuffer(sizeof(TLVHead))) { - return false; - } - auto *tlvHead = reinterpret_cast(buffer_->data() + cursor_); - tlvHead->tag = HostToNet(static_cast(TAG::TAG_UNDEFINED)); - tlvHead->len = HostToNet((uint32_t)0); - if (!SaveBufferToFile()) { - return false; - } - cursor_ += sizeof(TLVHead); + value = nullptr; return true; } -bool TLVObject::ReadUndefined(std::monostate &value) +size_t TLVObject::CountHead() { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - if (!LoadBufferFormFile(head.len)) { - return false; - } - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } - return true; + total_ += sizeof(TLVHead); + return sizeof(TLVHead); } -bool TLVObject::WriteNull(const void *value) +bool TLVObject::WriteHead(uint16_t tag, uint32_t len) { - PrepareBuffer(sizeof(TLVHead)); if (!HasExpectBuffer(sizeof(TLVHead))) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write head. tag=%{public}hu", tag); return false; } - auto *tlvHead = reinterpret_cast(buffer_->data() + cursor_); - tlvHead->tag = HostToNet(static_cast(TAG::TAG_NULL)); - tlvHead->len = HostToNet((uint32_t)0); - if (!SaveBufferToFile()) { - return false; - } + PrepareBufferForFile(sizeof(TLVHead)); + auto tlvHead = reinterpret_cast(GetStartCursor()); + tlvHead->tag = HostToNet(tag); + tlvHead->len = HostToNet(len); cursor_ += sizeof(TLVHead); - return true; + return SaveBufferToFile(); } -bool TLVObject::ReadNull(void *value) +bool TLVObject::WriteBackHead(uint16_t tag, size_t tagCursor, uint32_t len) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } - if (!HasExpectBuffer(head.len)) { - return false; - } - if (!LoadBufferFormFile(head.len)) { - return false; - } - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); + auto startCursor = buffer_->data(); + if (file_ == nullptr) { + startCursor += tagCursor; } - value = nullptr; - return true; + auto tlvHead = reinterpret_cast(startCursor); + tlvHead->tag = HostToNet(tag); + tlvHead->len = HostToNet(len); + return SaveBufferToFileFront(tagCursor, sizeof(TLVHead)); } bool TLVObject::ReadHead(TLVHead &head) { - if (!LoadBufferFormFile(sizeof(TLVHead))) { - return false; - } if (!HasExpectBuffer(sizeof(TLVHead))) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read head. tag=%{public}hu", head.tag); return false; } - const auto *pHead = reinterpret_cast(buffer_->data() + cursor_); - if (!HasExpectBuffer(NetToHost(pHead->len)) && - !HasExpectBuffer(NetToHost(pHead->len) + sizeof(TLVHead))) { + if (!LoadBufferFormFile(sizeof(TLVHead))) { + LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read head. tag=%{public}hu", head.tag); return false; } + auto startCursor = GetStartCursor(); + const auto *pHead = reinterpret_cast(startCursor); + auto len = NetToHost(pHead->len); + if (file_ == nullptr) { + if (!HasExpectBuffer(len + sizeof(TLVHead))) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read head and len. tag=%{public}hu", head.tag); + return false; + } + } + head.tag = NetToHost(pHead->tag); - head.len = NetToHost(pHead->len); + head.len = len; cursor_ += sizeof(TLVHead); return true; } -void TLVObject::WriteHead(uint16_t type, size_t tagCursor, uint32_t len) +bool TLVObject::Skip(TLVHead &head) { - auto *tlvHead = reinterpret_cast(buffer_->data() + tagCursor); - tlvHead->tag = HostToNet(type); - tlvHead->len = HostToNet(len); + if (file_ != nullptr) { + cursor_ += head.len; + return fseek(file_, head.len * sizeof(uint8_t), SEEK_CUR) == 0; + } + if (total_ < head.len || total_ - head.len < cursor_) { + LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv skip. tag=%{public}hu", head.tag); + return false; + } + cursor_ += head.len; + return true; } bool TLVObject::HasExpectBuffer(const uint32_t expectLen) const { + if (buffer_ == nullptr) { + return false; + } if (file_ != nullptr) { + buffer_->resize(expectLen); return true; } - if (buffer_== nullptr) { - return false; - } return buffer_->size() >= cursor_ && buffer_->size() - cursor_ >= expectLen; } -bool TLVObject::PrepareHeader(size_t size, size_t &tagCursor, size_t &valueCursor) +void TLVObject::PrepareBufferForFile(size_t size) { - if (file_ != nullptr) { - cursor_ = size; - if (cursor_ > static_cast(std::numeric_limits::max()) || - sizeof(TLVHead) > static_cast(std::numeric_limits::max()) || - cursor_ > static_cast(std::numeric_limits::max()) - sizeof(TLVHead)) { - LOG_ERROR(TlvObject, "Values are out of range, cursor_:%{public}zu, TLVHead:%{public}zu", - cursor_, sizeof(TLVHead)); - return false; - } - if (fseek(file_, -static_cast(cursor_) - static_cast(sizeof(TLVHead)), SEEK_CUR) != 0) { - LOG_ERROR(TlvObject, "fseek failed, error: %{public}d", errno); - return false; - } - buffer_->resize(sizeof(TLVHead)); - tagCursor = 0; - valueCursor = 0; + if (file_ == nullptr) { + return; } - return true; + buffer_->resize(size); } -void TLVObject::PrepareBuffer(size_t size) +std::uint8_t *TLVObject::GetStartCursor() { + auto startCursor = buffer_->data(); if (file_ == nullptr) { - return; + startCursor += cursor_; } - buffer_->resize(size); - cursor_ = 0; + return startCursor; } bool TLVObject::SaveBufferToFile() @@ -1126,6 +392,32 @@ bool TLVObject::SaveBufferToFile() } auto count = fwrite(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_); if (count != buffer_->size()) { + LOG_ERROR(UDMF_FRAMEWORK, "fwrite error!"); + return false; + } + return true; +} + +bool TLVObject::SaveBufferToFileFront(size_t tagCursor, uint32_t len) +{ + if (file_ == nullptr) { + return true; + } + int32_t leftOffset = + -((static_cast(cursor_) - static_cast(tagCursor))) * static_cast(sizeof(uint8_t)); + if (fseek(file_, leftOffset * sizeof(uint8_t), SEEK_CUR) != 0) { + LOG_ERROR(UDMF_FRAMEWORK, "file fseek left error!"); + return false; + } + auto count = fwrite(buffer_->data(), sizeof(uint8_t), sizeof(TLVHead), file_); + if (count != sizeof(TLVHead)) { + LOG_ERROR(UDMF_FRAMEWORK, "file write error!"); + return false; + } + int32_t rightOffset = + static_cast(cursor_) - static_cast(tagCursor) - static_cast(sizeof(TLVHead)); + if (fseek(file_, rightOffset * sizeof(uint8_t), SEEK_CUR) != 0) { + LOG_ERROR(UDMF_FRAMEWORK, "file fseek right error!"); return false; } return true; @@ -1136,13 +428,11 @@ bool TLVObject::LoadBufferFormFile(size_t size) if (file_ == nullptr) { return true; } - buffer_->resize(size); auto count = fread(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_); if (count != buffer_->size()) { return false; } - cursor_ = 0; return true; } } // namespace UDMF -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/udmf/framework/common/tlv_object.h b/udmf/framework/common/tlv_object.h index ca27d128..8a0f6f9b 100644 --- a/udmf/framework/common/tlv_object.h +++ b/udmf/framework/common/tlv_object.h @@ -4,7 +4,7 @@ * 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 + * 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, @@ -15,34 +15,15 @@ #ifndef UDMF_TLV_OBJECT_H #define UDMF_TLV_OBJECT_H - -#include +#include +#include #include "securec.h" -#include "error_code.h" #include "unified_meta.h" -#include "unified_types.h" #include "endian_converter.h" -#include "visibility.h" +#include "tlv_tag.h" + namespace OHOS { namespace UDMF { -enum class TAG { - TAG_INT32 = 0x0000, - TAG_INT64, - TAG_UINT32, - TAG_UINT64, - TAG_BOOL, - TAG_DOUBLE, - TAG_STRING, - TAG_VECTOR, - TAG_MAP, - TAG_WANT, - TAG_PIXELMAP, - TAG_OBJECT, - TAG_NULL, - TAG_UNDEFINED, - TAG_BUTT, -}; - #pragma pack(1) struct TLVHead { uint16_t tag; @@ -59,98 +40,83 @@ public: void SetFile(std::FILE *file); void UpdateSize(); std::vector GetBuffer(); - void Count(const uint32_t value); - void Count(const uint64_t value); - void Count(const int32_t value); - void Count(const int64_t value); - void Count(const float value); - void Count(const double value); - void Count(const std::string &value); - void Count(const std::vector &value); - void Count(const UDVariant &value); - void Count(const ValueType &value); - void Count(const UDDetails &value); - void Count(const UnifiedKey &value); - void Count(const Privilege &value); - void Count(const std::shared_ptr &value); - void Count(const std::shared_ptr &value); - void Count(const std::shared_ptr &value); - void Count(const std::monostate &value); - void Count(const void *value); + size_t GetTotal(); + size_t GetCursor(); + size_t OffsetHead(); + void ResetCursor(); - template bool WriteBasic(TAG type, const T &value); - template bool ReadBasic(T &value); - bool WriteString(const std::string &value); - bool ReadString(std::string &value); - bool WriteVector(const std::vector &value); - bool ReadVector(std::vector &value); - bool WriteVariant(const UDVariant &value); - bool ReadVariant(UDVariant &value); - bool WriteVariant(const ValueType &value); - bool ReadVariant(ValueType &value); - bool WriteMap(const UDDetails &value); - bool ReadMap(UDDetails &value); - bool WriteObject(const std::shared_ptr &value); - bool ReadObject(std::shared_ptr &value); - bool WriteWant(const std::shared_ptr &value); - bool ReadWant(std::shared_ptr &value); - bool WritePixelMap(const std::shared_ptr &value); - bool ReadPixelMap(std::shared_ptr &value); - bool WriteUndefined(const std::monostate &value); - bool ReadUndefined(std::monostate &value); - bool WriteNull(const void *value); - bool ReadNull(void *value); + size_t Count(const std::string &value); + size_t Count(const std::vector &value); + size_t Count(const OHOS::AAFwk::Want &value); + size_t Count(const std::monostate &value); + size_t Count(const void *value); -private: - bool WriteVariantInner(TAG &tag, const UDVariant &value); - bool ReadVariantInner(uint16_t tag, UDVariant &value); - bool WriteVariantInner(TAG &tag, const ValueType &value); - bool ReadVariantInner(uint16_t tag, ValueType &value); + bool Write(TAG tag, const std::string &value); + bool Write(TAG tag, const std::vector &value); + bool Write(TAG tag, const OHOS::AAFwk::Want &value); + bool Write(TAG tag, const std::monostate &value); + bool Write(TAG tag, const void *value); + + bool Read(std::string &value, const TLVHead &head); + bool Read(std::vector &value, const TLVHead &head); + bool Read(OHOS::AAFwk::Want &value, const TLVHead &head); + bool Read(std::monostate &value, const TLVHead &head); + bool Read(void *value, const TLVHead &head); + + template size_t CountBasic(const T &value); + template bool WriteBasic(TAG type, const T &value); + template bool ReadBasic(T &value, const TLVHead &head); + + size_t CountHead(); + bool WriteHead(uint16_t tag, uint32_t len); + bool WriteBackHead(uint16_t tag, size_t tagCursor, uint32_t len); bool ReadHead(TLVHead &head); - void WriteHead(uint16_t type, size_t tagCursor, uint32_t len); + + bool Skip(TLVHead &head); bool HasExpectBuffer(const uint32_t expectLen) const; - bool PrepareHeader(size_t size, size_t &tagCursor, size_t &valueCursor); - void PrepareBuffer(size_t size); bool SaveBufferToFile(); + bool SaveBufferToFileFront(size_t tagCursor, uint32_t len); bool LoadBufferFormFile(size_t size); + private: + void PrepareBufferForFile(size_t size); + std::uint8_t *GetStartCursor(); + std::size_t total_ = 0; std::size_t cursor_ = 0; std::vector *buffer_; std::FILE *file_ = nullptr; }; -template -bool TLVObject::WriteBasic(TAG type, const T &value) +template size_t TLVObject::CountBasic(const T &value) { - PrepareBuffer(sizeof(TLVHead) + sizeof(value)); + static_assert(std::is_fundamental::value, "T must be a fundamental type."); + auto size = sizeof(value) + sizeof(TLVHead); + total_ += size; + return size; +} + +template bool TLVObject::WriteBasic(TAG type, const T &value) +{ + static_assert(std::is_fundamental::value, "T must be a fundamental type."); if (!HasExpectBuffer(sizeof(TLVHead) + sizeof(value))) { return false; } - auto *tlvHead = reinterpret_cast(buffer_->data() + cursor_); + auto tlvHead = reinterpret_cast(GetStartCursor()); tlvHead->tag = HostToNet(static_cast(type)); tlvHead->len = HostToNet((uint32_t)sizeof(value)); auto valueBuff = HostToNet(value); - size_t maxSize = sizeof(value) + 1; - auto ret = memcpy_s(tlvHead->value, maxSize, &valueBuff, sizeof(value)); - if (ret != EOK) { - return false; - } - if (!SaveBufferToFile()) { + if (memcpy_s(tlvHead->value, sizeof(value), &valueBuff, sizeof(value)) != EOK) { return false; } cursor_ += sizeof(TLVHead) + sizeof(value); - return true; + return SaveBufferToFile(); } -template -bool TLVObject::ReadBasic(T &value) +template bool TLVObject::ReadBasic(T &value, const TLVHead &head) { - TLVHead head {}; - if (!ReadHead(head)) { - return false; - } + static_assert(std::is_fundamental::value, "T must be a fundamental type."); if (head.len == 0 || head.len != sizeof(T)) { return false; } @@ -160,18 +126,15 @@ bool TLVObject::ReadBasic(T &value) if (!LoadBufferFormFile(head.len)) { return false; } - auto ret = memcpy_s(&value, sizeof(T), buffer_->data() + cursor_, sizeof(T)); + auto startCursor = GetStartCursor(); + auto ret = memcpy_s(&value, sizeof(T), startCursor, sizeof(T)); if (ret != EOK) { return false; } value = NetToHost(value); cursor_ += sizeof(T); - if (file_ != nullptr) { - cursor_ += sizeof(TLVHead); - } return true; } - } // namespace UDMF } // namespace OHOS -#endif // UDMF_TLV_OBJECT_H \ No newline at end of file +#endif // UDMF_TLV_OBJECT_H diff --git a/udmf/framework/common/tlv_tag.h b/udmf/framework/common/tlv_tag.h new file mode 100644 index 00000000..2f2428fd --- /dev/null +++ b/udmf/framework/common/tlv_tag.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_TLV_TAG_H +#define UDMF_TLV_TAG_H + +#include + +namespace OHOS::UDMF { +enum class TAG : uint16_t { + TAG_NULL = 0x0000, + TAG_MONOSTATE, + TAG_UNDEFINED, + TAG_INT8, + TAG_INT16, + TAG_INT32, + TAG_INT64, + TAG_UINT8, + TAG_UINT16, + TAG_UINT32, + TAG_UINT64, + TAG_FLOAT, + TAG_DOUBLE, + TAG_BOOL, + TAG_STRING, + TAG_VECTOR, + TAG_VECTOR_SIZE, + TAG_VECTOR_ITEM, + TAG_MAP, + TAG_MAP_PAIR, + TAG_MAP_KEY, + TAG_MAP_VALUE, + TAG_VARIANT, + TAG_VARIANT_INDEX, + TAG_VARIANT_ITEM, + TAG_BUTT = 0x1000, + TAG_UNIFIED_DATA, + TAG_UNIFIED_RECORD, + TAG_VERSION, + TAG_UD_TYPE, + TAG_UID, + TAG_RECORD_VALUE, + TAG_KEY, + TAG_INTENTION, + TAG_BUNDLE_NAME, + TAG_GROUP_ID, + TAG_TOKEN_ID, + TAG_READPERMISSION, + TAG_WRITEPERMISSION, + TAG_IS_PRIVATE, + TAG_PRIVILEGE, + TAG_CREATE_TIME, + TAG_SOURCE_PACKAGE, + TAG_DATA_STATUS, + TAG_DATA_VERSION, + TAG_LAST_MODIFIED_TIME, + TAG_CREATE_PACKAGE, + TAG_DEVICE_ID, + TAG_RECORD_TOTAL_NUM, + TAG_WANT, + TAG_PIXELMAP, + TAG_OBJECT_VALUE, + TAG_RUNTIME +}; +} +#endif //UDMF_TLV_TAG_H diff --git a/udmf/framework/common/tlv_util.cpp b/udmf/framework/common/tlv_util.cpp index c1843325..6d137754 100644 --- a/udmf/framework/common/tlv_util.cpp +++ b/udmf/framework/common/tlv_util.cpp @@ -4,7 +4,7 @@ * 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 + * 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, @@ -12,405 +12,97 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "TlvUtil" -#include "tlv_util.h" +#include "tlv_util.h" +#include "udmf_utils.h" #include "logger.h" +#include "tlv_object.h" namespace OHOS { namespace TLVUtil { -template<> -bool CountBufferSize(const std::shared_ptr &input, TLVObject &data) -{ - if (input == nullptr) { - return false; - } - data.Count(input->GetType()); - data.Count(input->GetUid()); - auto type = input->GetType(); - switch (type) { - case UDType::TEXT: { - auto text = static_cast(input.get()); - if (text == nullptr) { - return false; - } - data.Count(text->GetDetails()); - break; - } - case UDType::PLAIN_TEXT: { - auto plainText = static_cast(input.get()); - if (plainText == nullptr) { - return false; - } - data.Count(plainText->GetContent()); - data.Count(plainText->GetAbstract()); - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - data.Count(text->GetDetails()); - break; - } - case UDType::HTML: { - auto html = static_cast<Html *>(input.get()); - if (html == nullptr) { - return false; - } - data.Count(html->GetHtmlContent()); - data.Count(html->GetPlainContent()); - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - data.Count(text->GetDetails()); - break; - } - case UDType::HYPERLINK: { - auto link = static_cast<Link *>(input.get()); - if (link == nullptr) { - return false; - } - data.Count(link->GetUrl()); - data.Count(link->GetDescription()); - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - data.Count(text->GetDetails()); - break; - } - case UDType::FILE: { - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - data.Count(file->GetUri()); - data.Count(file->GetRemoteUri()); - data.Count(file->GetDetails()); - break; - } - case UDType::IMAGE: { - auto image = static_cast<Image *>(input.get()); - if (image == nullptr) { - return false; - } - data.Count(image->GetUri()); - data.Count(image->GetRemoteUri()); - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - data.Count(file->GetDetails()); - break; - } - case UDType::VIDEO: { - auto video = static_cast<Video *>(input.get()); - if (video == nullptr) { - return false; - } - data.Count(video->GetUri()); - data.Count(video->GetRemoteUri()); - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - data.Count(file->GetDetails()); - break; - } - case UDType::AUDIO: { - auto audio = static_cast<Audio *>(input.get()); - if (audio == nullptr) { - return false; - } - data.Count(audio->GetUri()); - data.Count(audio->GetRemoteUri()); - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - data.Count(file->GetDetails()); - break; - } - case UDType::FOLDER: { - auto folder = static_cast<Folder *>(input.get()); - if (folder == nullptr) { - return false; - } - data.Count(folder->GetUri()); - data.Count(folder->GetRemoteUri()); - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - data.Count(file->GetDetails()); - break; - } - case UDType::SYSTEM_DEFINED_RECORD: { - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - data.Count(sdRecord->GetDetails()); - break; - } - case UDType::SYSTEM_DEFINED_FORM: { - auto form = static_cast<SystemDefinedForm *>(input.get()); - if (form == nullptr) { - return false; - } - data.Count(form->GetFormId()); - data.Count(form->GetFormName()); - data.Count(form->GetBundleName()); - data.Count(form->GetAbilityName()); - data.Count(form->GetModule()); - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - data.Count(sdRecord->GetDetails()); - break; - } - case UDType::SYSTEM_DEFINED_APP_ITEM: { - auto appItem = static_cast<SystemDefinedAppItem *>(input.get()); - if (appItem == nullptr) { - return false; - } - data.Count(appItem->GetAppId()); - data.Count(appItem->GetAppName()); - data.Count(appItem->GetAppIconId()); - data.Count(appItem->GetAppLabelId()); - data.Count(appItem->GetBundleName()); - data.Count(appItem->GetAbilityName()); - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - data.Count(sdRecord->GetDetails()); - break; - } - case UDType::SYSTEM_DEFINED_PIXEL_MAP: { - auto pixelMap = static_cast<SystemDefinedPixelMap *>(input.get()); - if (pixelMap == nullptr) { - return false; - } - data.Count(pixelMap->GetRawData()); - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - data.Count(sdRecord->GetDetails()); - break; - } - case UDType::APPLICATION_DEFINED_RECORD: { - auto record = static_cast<ApplicationDefinedRecord *>(input.get()); - if (record == nullptr) { - return false; - } - data.Count(record->GetApplicationDefinedType()); - data.Count(record->GetRawData()); - break; - } - case UDType::FILE_URI: { - if (input == nullptr) { - return false; - } - data.Count(input->GetValue()); - break; - } - default: { - return false; - } - } - data.Count(input->GetOriginValue()); - return true; -} - -template<> -bool CountBufferSize(const Runtime &input, TLVObject &data) -{ - data.Count(input.key); - data.Count(input.isPrivate); - uint32_t size = static_cast<uint32_t>(input.privileges.size()); - data.Count(size); - for (uint32_t i = 0; i < size; ++i) { - data.Count(input.privileges[i]); - } - data.Count(static_cast<int64_t>(input.createTime)); - data.Count(static_cast<int64_t>(input.lastModifiedTime)); - data.Count(input.sourcePackage); - data.Count(static_cast<int32_t>(input.dataStatus)); - data.Count(input.dataVersion); - data.Count(input.createPackage); - data.Count(input.deviceId); - data.Count(input.recordTotalNum); - data.Count(input.tokenId); - return true; -} - -template<> -bool CountBufferSize(const UnifiedData &input, TLVObject &data) -{ - int32_t size = static_cast<int32_t>(input.GetRecords().size()); - data.Count(size); - for (auto record : input.GetRecords()) { - if (!CountBufferSize(record, data)) { - return false; - } - } - return true; -} - -template<> -bool CountBufferSize(const std::vector<UnifiedData> &input, TLVObject &data) -{ - int32_t size = static_cast<int32_t>(input.size()); - data.Count(size); - for (auto unifiedData : input) { - if (!CountBufferSize(unifiedData, data)) { - return false; - } - } - return true; -} - -template<typename T> -bool Writing(const T &input, TLVObject &data); - -template<typename T> -bool Reading(T &output, TLVObject &data); - -template<> -bool Writing(const int32_t &input, TLVObject &data) -{ - return data.WriteBasic(TAG::TAG_INT32, input); -} - -template<> -bool Reading(int32_t &output, TLVObject &data) -{ - return data.ReadBasic(output); -} - -template<> -bool Writing(const int64_t &input, TLVObject &data) -{ - return data.WriteBasic(TAG::TAG_INT64, input); -} - -template<> -bool Reading(int64_t &output, TLVObject &data) -{ - return data.ReadBasic(output); -} - -template<> -bool Reading(uint32_t &output, TLVObject &data) -{ - return data.ReadBasic(output); -} - -template<> -bool Writing(const uint32_t &input, TLVObject &data) -{ - return data.WriteBasic(TAG::TAG_UINT32, input); -} - -template<> -bool Reading(uint64_t &output, TLVObject &data) +template <> size_t CountBufferSize(const std::nullptr_t &input, TLVObject &data) { - return data.ReadBasic(output); + return data.CountHead(); } -template<> -bool Writing(const uint64_t &input, TLVObject &data) +template <> bool Writing(const std::nullptr_t &input, TLVObject &data, TAG tag) { - return data.WriteBasic(TAG::TAG_UINT64, input); + InitWhenFirst(input, data); + return data.WriteHead(static_cast<uint16_t>(tag), 0); } -template<> -bool Writing(const bool &input, TLVObject &data) +template <> bool Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head) { - return data.WriteBasic(TAG::TAG_BOOL, input); + return data.Read(output, head); } -template<> -bool Reading(bool &output, TLVObject &data) +template <> size_t CountBufferSize(const std::monostate &input, TLVObject &data) { - return data.ReadBasic(output); + return data.Count(input); } -template<> -bool Writing(const std::string &input, TLVObject &data) +template <> bool Writing(const std::monostate &input, TLVObject &data, TAG tag) { - return data.WriteString(input); + InitWhenFirst(input, data); + return data.Write(tag, input); } -template<> -bool Reading(std::string &output, TLVObject &data) +template <> bool Reading(std::monostate &output, TLVObject &data, const TLVHead &head) { - return data.ReadString(output); + return data.Read(output, head); } -template<> -bool Writing(const std::vector<uint8_t> &input, TLVObject &data) +template <> size_t CountBufferSize(const std::string &input, TLVObject &data) { - return data.WriteVector(input); + return data.Count(input); } -template<> -bool Reading(std::vector<uint8_t> &output, TLVObject &data) +template <> bool Writing(const std::string &input, TLVObject &data, TAG tag) { - return data.ReadVector(output); + InitWhenFirst(input, data); + return data.Write(tag, input); } -template<> -bool Writing(const UDVariant &input, TLVObject &data) +template <> bool Reading(std::string &output, TLVObject &data, const TLVHead &head) { - return data.WriteVariant(input); + return data.Read(output, head); } -template<> -bool Reading(UDVariant &output, TLVObject &data) +template <> size_t CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data) { - return data.ReadVariant(output); + return data.Count(input); } -template<> -bool Writing(const ValueType &input, TLVObject &data) +template <> bool Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag) { - return data.WriteVariant(input); + InitWhenFirst(input, data); + return data.Write(tag, input); } -template<> -bool Reading(ValueType &output, TLVObject &data) +template <> bool Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head) { - return data.ReadVariant(output); + return data.Read(output, head); } -template<> -bool Writing(const UDDetails &input, TLVObject &data) +template <> size_t CountBufferSize(const UDType &input, TLVObject &data) { - return data.WriteMap(input); -} - -template<> -bool Reading(UDDetails &output, TLVObject &data) -{ - return data.ReadMap(output); + int32_t type = input; + return data.CountBasic(type); } -template<> -bool Writing(const UDType &input, TLVObject &data) +template <> bool Writing(const UDType &input, TLVObject &data, TAG tag) { + InitWhenFirst(input, data); int32_t type = input; - return Writing(type, data); + return data.WriteBasic(tag, type); } -template<> -bool Reading(UDType &output, TLVObject &data) +template <> bool Reading(UDType &output, TLVObject &data, const TLVHead &head) { int32_t type; - if (!Reading(type, data)) { + if (!Reading(type, data, head)) { return false; } if (type < UDType::ENTITY || type >= UDType::UD_BUTT) { @@ -420,1151 +112,510 @@ bool Reading(UDType &output, TLVObject &data) return true; } -template<> -bool Writing(const Text &input, TLVObject &data) +template <> size_t CountBufferSize(const DataStatus &input, TLVObject &data) { - return Writing(input.GetDetails(), data); + int32_t status = input; + return data.CountBasic(status); } -template<> -bool Reading(Text &output, TLVObject &data) +template <> bool Writing(const DataStatus &input, TLVObject &data, TAG tag) { - UDDetails details; - if (!Reading(details, data)) { - return false; - } - output.SetDetails(details); - return true; + InitWhenFirst(input, data); + int32_t status = input; + return data.WriteBasic(tag, status); } -template<> -bool Writing(const PlainText &input, TLVObject &data) +template <> bool Reading(DataStatus &output, TLVObject &data, const TLVHead &head) { - if (!Writing(input.GetContent(), data)) { + int32_t status; + if (!data.ReadBasic(status, head)) { return false; } - if (!Writing(input.GetAbstract(), data)) { + if (status < DataStatus::WORKING || status >= DataStatus::FADE) { return false; } + output = static_cast<DataStatus>(status); return true; } -template<> -bool Reading(PlainText &output, TLVObject &data) +template <> size_t CountBufferSize(const Object &input, TLVObject &data) { - std::string content; - std::string abstract; - UDDetails details; - if (!Reading(content, data)) { - return false; - } - if (!Reading(abstract, data)) { - return false; - } - if (!Reading(details, data)) { - return false; - } - output.SetContent(content); - output.SetAbstract(abstract); - output.SetDetails(details); - return true; + return data.CountHead() + CountBufferSize(input.value_, data); } -template<> -bool Writing(const Html &input, TLVObject &data) +template <> bool Writing(const Object &input, TLVObject &data, TAG tag) { - if (!Writing(input.GetHtmlContent(), data)) { - return false; - } - if (!Writing(input.GetPlainContent(), data)) { + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + if (!Writing(input.value_, data, TAG::TAG_OBJECT_VALUE)) { return false; } - return true; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); } - -template<> -bool Reading(Html &output, TLVObject &data) +template <> bool Reading(Object &output, TLVObject &data, const TLVHead &head) { - std::string htmlContent; - std::string plainContent; - UDDetails details; - if (!Reading(htmlContent, data)) { + TLVHead headValue{}; + if (!data.ReadHead(headValue)) { return false; } - if (!Reading(plainContent, data)) { + if (headValue.tag != static_cast<uint16_t>(TAG::TAG_OBJECT_VALUE)) { return false; } - if (!Reading(details, data)) { + if (!Reading(output.value_, data, headValue)) { return false; } - output.SetHtmlContent(htmlContent); - output.SetPlainContent(plainContent); - output.SetDetails(details); return true; } -template<> -bool Writing(const Link &input, TLVObject &data) +template <> size_t CountBufferSize(const UnifiedKey &input, TLVObject &data) { - if (!Writing(input.GetUrl(), data)) { - return false; - } - if (!Writing(input.GetDescription(), data)) { - return false; - } - return true; + return data.CountHead() + data.Count(input.key) + data.Count(input.intention) + data.Count(input.bundleName) + + data.Count(input.groupId); } - -template<> -bool Reading(Link &output, TLVObject &data) +template <> bool Writing(const UnifiedKey &input, TLVObject &data, TAG tag) { - std::string url; - std::string description; - UDDetails details; - if (!Reading(url, data)) { - return false; - } - if (!Reading(description, data)) { - return false; - } - if (!Reading(details, data)) { + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + if (!data.Write(TAG::TAG_KEY, input.key)) { return false; } - output.SetUrl(url); - output.SetDescription(description); - output.SetDetails(details); - return true; -} - -template<> -bool Writing(const File &input, TLVObject &data) -{ - if (!Writing(input.GetUri(), data)) { + if (!data.Write(TAG::TAG_INTENTION, input.intention)) { return false; } - if (!Writing(input.GetRemoteUri(), data)) { + if (!data.Write(TAG::TAG_BUNDLE_NAME, input.bundleName)) { return false; } - if (!Writing(input.GetDetails(), data)) { + if (!data.Write(TAG::TAG_GROUP_ID, input.groupId)) { return false; } - return true; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); } -template<> -bool Reading(File &output, TLVObject &data) +template <> bool Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head) { - std::string uri; - std::string remoteUri; - UDDetails details; - if (!Reading(uri, data)) { - return false; - } - if (!Reading(remoteUri, data)) { - return false; - } - if (!Reading(details, data)) { - return false; + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + switch (headItem.tag) { + case static_cast<uint16_t>(TAG::TAG_KEY): + if (!data.Read(output.key, headItem)) { + return false; + } + break; + case static_cast<uint16_t>(TAG::TAG_INTENTION): + if (!data.Read(output.intention, headItem)) { + return false; + } + break; + case static_cast<uint16_t>(TAG::TAG_BUNDLE_NAME): + if (!data.Read(output.bundleName, headItem)) { + return false; + } + break; + case static_cast<uint16_t>(TAG::TAG_GROUP_ID): + if (!data.Read(output.groupId, headItem)) { + return false; + } + break; + default: + data.Skip(headItem); + } } - output.SetUri(uri); - output.SetRemoteUri(remoteUri); - output.SetDetails(details); return true; } -template<> -bool Writing(const Image &input, TLVObject &data) +template <> size_t CountBufferSize(const UnifiedData &input, TLVObject &data) { - return true; + std::string version = UTILS::GetCurrentSdkVersion(); + return data.CountHead() + data.Count(version) + TLVUtil::CountBufferSize(input.GetRecords(), data); } -template<> -bool Reading(Image &output, TLVObject &data) +template <> bool Writing(const UnifiedData &input, TLVObject &data, TAG tag) { - std::string uri; - std::string remoteUri; - UDDetails details; - if (!Reading(uri, data)) { - return false; - } - if (!Reading(remoteUri, data)) { + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + std::string version = UTILS::GetCurrentSdkVersion(); + if (!data.Write(TAG::TAG_VERSION, version)) { return false; } - if (!Reading(details, data)) { + if (!TLVUtil::Writing(input.GetRecords(), data, TAG::TAG_UNIFIED_RECORD)) { return false; } - output.SetUri(uri); - output.SetRemoteUri(remoteUri); - output.SetDetails(details); - return true; -} - -template<> -bool Writing(const Video &input, TLVObject &data) -{ - return true; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); } -template<> -bool Reading(Video &output, TLVObject &data) +template <> bool Reading(UnifiedData &output, TLVObject &data, const TLVHead &head) { - std::string uri; - std::string remoteUri; - UDDetails details; - if (!Reading(uri, data)) { - return false; - } - if (!Reading(remoteUri, data)) { - return false; - } - if (!Reading(details, data)) { - return false; + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VERSION)) { + data.Skip(headItem); + continue; + } + if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_RECORD)) { + auto records = output.GetRecords(); + if (!Reading(records, data, headItem)) { + return false; + } + output.SetRecords(records); + continue; + } + data.Skip(headItem); } - output.SetUri(uri); - output.SetRemoteUri(remoteUri); - output.SetDetails(details); return true; } -template<> -bool Writing(const Audio &input, TLVObject &data) +template <> size_t CountBufferSize(const UnifiedRecord &input, TLVObject &data) { - return true; + std::string version = UTILS::GetCurrentSdkVersion(); + return data.CountHead() + data.Count(version) + data.CountBasic(static_cast<int32_t>(input.GetType())) + + data.Count(input.GetUid()) + CountBufferSize(input.GetOriginValue(), data); } -template<> -bool Reading(Audio &output, TLVObject &data) +template <> bool Writing(const UnifiedRecord &input, TLVObject &data, TAG tag) { - std::string uri; - std::string remoteUri; - UDDetails details; - if (!Reading(uri, data)) { - return false; - } - if (!Reading(remoteUri, data)) { + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + std::string version = UTILS::GetCurrentSdkVersion(); + if (!data.Write(TAG::TAG_VERSION, version)) { return false; } - if (!Reading(details, data)) { - return false; - } - output.SetUri(uri); - output.SetRemoteUri(remoteUri); - output.SetDetails(details); - return true; -} - -template<> -bool Writing(const Folder &input, TLVObject &data) -{ - return true; -} - -template<> -bool Reading(Folder &output, TLVObject &data) -{ - std::string uri; - std::string remoteUri; - UDDetails details; - if (!Reading(uri, data)) { + if (!data.WriteBasic(TAG::TAG_UD_TYPE, static_cast<int32_t>(input.GetType()))) { return false; } - if (!Reading(remoteUri, data)) { + if (!data.Write(TAG::TAG_UID, input.GetUid())) { return false; } - if (!Reading(details, data)) { + if (!TLVUtil::Writing(input.GetOriginValue(), data, TAG::TAG_RECORD_VALUE)) { return false; } - output.SetUri(uri); - output.SetRemoteUri(remoteUri); - output.SetDetails(details); - return true; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); } -template<> -bool Writing(const SystemDefinedRecord &input, TLVObject &data) +template <> bool Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head) { - if (!Writing(input.GetDetails(), data)) { - return false; + auto endCursor = data.GetCursor() + head.len; + UDType dataType; + std::string uid; + ValueType value; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + switch (headItem.tag) { + case static_cast<uint16_t>(TAG::TAG_VERSION): + data.Skip(headItem); + break; + case static_cast<uint16_t>(TAG::TAG_UD_TYPE): + if (!TLVUtil::Reading(dataType, data, headItem)) { + return false; + } + output.SetType(dataType); + break; + case static_cast<uint16_t>(TAG::TAG_UID): + if (!data.Read(uid, headItem)) { + return false; + } + output.SetUid(uid); + break; + case static_cast<uint16_t>(TAG::TAG_RECORD_VALUE): + if (!TLVUtil::Reading(value, data, headItem)) { + return false; + } + output.SetValue(value); + break; + default: + data.Skip(headItem); + } } return true; } -template<> -bool Reading(SystemDefinedRecord &output, TLVObject &data) +template <> size_t CountBufferSize(const Runtime &input, TLVObject &data) { - UDDetails details; - if (!Reading(details, data)) { - return false; - } - output.SetDetails(details); - return true; + std::string version = UTILS::GetCurrentSdkVersion(); + return data.CountHead() + data.CountBasic(input.isPrivate) + data.CountBasic(input.dataVersion) + + data.CountBasic(input.recordTotalNum) + data.CountBasic(input.tokenId) + + data.CountBasic(static_cast<int64_t>(input.createTime)) + + data.CountBasic(static_cast<int64_t>(input.lastModifiedTime)) + + data.CountBasic(static_cast<int32_t>(input.dataStatus)) + data.Count(input.sourcePackage) + + data.Count(input.createPackage) + data.Count(input.deviceId) + TLVUtil::CountBufferSize(input.key, data) + + data.Count(version) + TLVUtil::CountBufferSize(input.privileges, data); } -template<> -bool Writing(const SystemDefinedForm &input, TLVObject &data) +template <> bool Writing(const Runtime &input, TLVObject &data, TAG tag) { - if (!Writing(input.GetFormId(), data)) { - return false; - } - if (!Writing(input.GetFormName(), data)) { - return false; - } - if (!Writing(input.GetBundleName(), data)) { + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + std::string version = UTILS::GetCurrentSdkVersion(); + if (!TLVUtil::Writing(version, data, TAG::TAG_VERSION)) { return false; } - if (!Writing(input.GetAbilityName(), data)) { + if (!TLVUtil::Writing(input.key, data, TAG::TAG_KEY)) { return false; } - if (!Writing(input.GetModule(), data)) { + if (!data.WriteBasic(TAG::TAG_IS_PRIVATE, input.isPrivate)) { return false; } - return true; -} - -template<> -bool Reading(SystemDefinedForm &output, TLVObject &data) -{ - int32_t formId; - std::string formName; - std::string bundleName; - std::string abilityName; - std::string module; - UDDetails details; - if (!Reading(formId, data)) { + if (!TLVUtil::Writing(input.privileges, data, TAG::TAG_PRIVILEGE)) { return false; } - if (!Reading(formName, data)) { + if (!data.WriteBasic(TAG::TAG_CREATE_TIME, static_cast<int64_t>(input.createTime))) { return false; } - if (!Reading(bundleName, data)) { + if (!data.Write(TAG::TAG_SOURCE_PACKAGE, input.sourcePackage)) { return false; } - if (!Reading(abilityName, data)) { + if (!data.WriteBasic(TAG::TAG_DATA_STATUS, static_cast<int32_t>(input.dataStatus))) { return false; } - if (!Reading(module, data)) { + if (!data.WriteBasic(TAG::TAG_DATA_VERSION, input.dataVersion)) { return false; } - if (!Reading(details, data)) { - return false; - } - output.SetFormId(formId); - output.SetFormName(formName); - output.SetBundleName(bundleName); - output.SetAbilityName(abilityName); - output.SetModule(module); - output.SetDetails(details); - return true; -} - -template<> -bool Writing(const SystemDefinedAppItem &input, TLVObject &data) -{ - if (!Writing(input.GetAppId(), data)) { + if (!data.WriteBasic(TAG::TAG_LAST_MODIFIED_TIME, static_cast<int64_t>(input.lastModifiedTime))) { return false; } - if (!Writing(input.GetAppName(), data)) { + if (!data.Write(TAG::TAG_CREATE_PACKAGE, input.createPackage)) { return false; } - if (!Writing(input.GetAppIconId(), data)) { + if (!data.Write(TAG::TAG_DEVICE_ID, input.deviceId)) { return false; } - if (!Writing(input.GetAppLabelId(), data)) { + if (!data.WriteBasic(TAG::TAG_RECORD_TOTAL_NUM, input.recordTotalNum)) { return false; } - if (!Writing(input.GetBundleName(), data)) { + if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) { return false; } - if (!Writing(input.GetAbilityName(), data)) { - return false; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); +} + +template <> bool Reading(Runtime &output, TLVObject &data, const TLVHead &head) +{ + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + bool result = true; + int64_t createTime = 0; + int64_t lastModifiedTime = 0; + switch (headItem.tag) { + case static_cast<uint16_t>(TAG::TAG_KEY): + result = TLVUtil::Reading(output.key, data, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_IS_PRIVATE): + result = data.ReadBasic(output.isPrivate, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_PRIVILEGE): + result = TLVUtil::Reading(output.privileges, data, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_CREATE_TIME): + result = data.ReadBasic(createTime, headItem); + output.createTime = static_cast<time_t>(createTime); + break; + case static_cast<uint16_t>(TAG::TAG_SOURCE_PACKAGE): + result = data.Read(output.sourcePackage, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_DATA_STATUS): + result = TLVUtil::Reading(output.dataStatus, data, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_DATA_VERSION): + result = data.ReadBasic(output.dataVersion, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_LAST_MODIFIED_TIME): + result = data.ReadBasic(lastModifiedTime, headItem); + output.lastModifiedTime = static_cast<time_t>(lastModifiedTime); + break; + case static_cast<uint16_t>(TAG::TAG_CREATE_PACKAGE): + result = data.Read(output.createPackage, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_DEVICE_ID): + result = data.Read(output.deviceId, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_RECORD_TOTAL_NUM): + result = data.ReadBasic(output.recordTotalNum, headItem); + break; + case static_cast<uint16_t>(TAG::TAG_TOKEN_ID): + result = data.ReadBasic(output.tokenId, headItem); + break; + default: + result = data.Skip(headItem); + } + if (!result) { + return false; + } } return true; } -template<> -bool Reading(SystemDefinedAppItem &output, TLVObject &data) +template <> size_t CountBufferSize(const Privilege &input, TLVObject &data) { - std::string appId; - std::string appName; - std::string appIconId; - std::string appLabelId; - std::string bundleName; - std::string abilityName; - UDDetails details; - if (!Reading(appId, data)) { - return false; - } - if (!Reading(appName, data)) { - return false; - } - if (!Reading(appIconId, data)) { - return false; - } - if (!Reading(appLabelId, data)) { - return false; - } - if (!Reading(bundleName, data)) { + return data.CountHead() + data.CountBasic(input.tokenId) + data.Count(input.readPermission) + + data.Count(input.writePermission); +} + +template <> bool Writing(const Privilege &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) { return false; } - if (!Reading(abilityName, data)) { + if (!data.Write(TAG::TAG_READPERMISSION, input.readPermission)) { return false; } - if (!Reading(details, data)) { + if (!data.Write(TAG::TAG_WRITEPERMISSION, input.writePermission)) { return false; } - output.SetAppId(appId); - output.SetAppName(appName); - output.SetAppIconId(appIconId); - output.SetAppLabelId(appLabelId); - output.SetBundleName(bundleName); - output.SetAbilityName(abilityName); - output.SetDetails(details); - return true; + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); } -template<> -bool Writing(const SystemDefinedPixelMap &input, TLVObject &data) +template <> bool Reading(Privilege &output, TLVObject &data, const TLVHead &head) { - if (!Writing(input.GetRawData(), data)) { - return false; + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + switch (headItem.tag) { + case static_cast<uint16_t>(TAG::TAG_TOKEN_ID): + if (!data.ReadBasic(output.tokenId, headItem)) { + return false; + } + break; + case static_cast<uint16_t>(TAG::TAG_READPERMISSION): + if (!data.Read(output.readPermission, headItem)) { + return false; + } + break; + case static_cast<uint16_t>(TAG::TAG_WRITEPERMISSION): + if (!data.Read(output.writePermission, headItem)) { + return false; + } + break; + default: + data.Skip(headItem); + } } return true; } -template<> -bool Reading(SystemDefinedPixelMap &output, TLVObject &data) +template <> size_t CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data) { - std::vector<uint8_t> rawData; - UDDetails details; - if (!Reading(rawData, data)) { - return false; + std::vector<std::uint8_t> val; + if (!input->EncodeTlv(val)) { + LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when CountBufferSize"); + return 0; } - if (!Reading(details, data)) { + return CountBufferSize(val, data); +} + +template <> bool Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + std::vector<std::uint8_t> val; + if (!input->EncodeTlv(val)) { + LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when Writing"); return false; } - output.SetRawData(rawData); - output.SetDetails(details); - return true; + return data.Write(tag, val); } -template<> -bool Writing(const ApplicationDefinedRecord &input, TLVObject &data) +template <> bool Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head) { - if (!Writing(input.GetApplicationDefinedType(), data)) { + std::vector<std::uint8_t> val; + if (!data.Read(val, head)) { + LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error."); return false; } - if (!Writing(input.GetRawData(), data)) { + output = std::shared_ptr<OHOS::Media::PixelMap>(OHOS::Media::PixelMap::DecodeTlv(val)); + if (output == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "DecodeTlv pixelMap error when Reading."); return false; } return true; } -template<> -bool Reading(ApplicationDefinedRecord &output, TLVObject &data) +template <> size_t CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data) { - std::string type; - std::vector<uint8_t> rawData; - if (!Reading(type, data)) { - return false; + Parcel parcel; + if (!input->Marshalling(parcel)) { + LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count"); + return 0; } - if (!Reading(rawData, data)) { - return false; - } - output.SetApplicationDefinedType(type); - output.SetRawData(rawData); - return true; + auto size = parcel.GetDataSize(); + std::vector<std::uint8_t> val(size); + return CountBufferSize(val, data); } -template<> -bool Writing(const std::shared_ptr<UnifiedRecord> &input, TLVObject &data) +template <> bool Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag) { - if (data.GetBuffer().size() == 0) { - if (!CountBufferSize(input, data)) { + InitWhenFirst(input, data); + Parcel parcel; + if (!input->Marshalling(parcel)) { + LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag); + return false; + } + auto size = parcel.GetDataSize(); + auto buffer = parcel.GetData(); + std::vector<std::uint8_t> val(size); + if (size != 0) { + auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size); + if (err != EOK) { + LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag); return false; } - data.UpdateSize(); } + return data.Write(tag, val); +} - if (!Writing(input->GetType(), data)) { +template <> bool Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head) +{ + std::vector<std::uint8_t> val; + if (!data.Read(val, head)) { + LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error."); return false; } - if (!Writing(input->GetUid(), data)) { + + std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>(); + auto buffer = malloc(val.size()); + if (buffer == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag); return false; } - auto type = input->GetType(); - switch (type) { - case UDType::TEXT: { - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - if (!Writing(*text, data)) { - return false; - } - break; - } - case UDType::PLAIN_TEXT: { - auto plainText = static_cast<PlainText *>(input.get()); - if (plainText == nullptr) { - return false; - } - if (!Writing(*plainText, data)) { - return false; - } - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - if (!Writing(*text, data)) { - return false; - } - break; - } - case UDType::HTML: { - auto html = static_cast<Html *>(input.get()); - if (html == nullptr) { - return false; - } - if (!Writing(*html, data)) { - return false; - } - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - if (!Writing(*text, data)) { - return false; - } - break; - } - case UDType::HYPERLINK: { - auto link = static_cast<Link *>(input.get()); - if (link == nullptr) { - return false; - } - if (!Writing(*link, data)) { - return false; - } - auto text = static_cast<Text *>(input.get()); - if (text == nullptr) { - return false; - } - if (!Writing(*text, data)) { - return false; - } - break; - } - case UDType::FILE: { - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - if (!Writing(*file, data)) { - return false; - } - break; - } - case UDType::IMAGE: { - auto image = static_cast<Image *>(input.get()); - if (image == nullptr) { - return false; - } - if (!Writing(*image, data)) { - return false; - } - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - if (!Writing(*file, data)) { - return false; - } - break; - } - case UDType::VIDEO: { - auto video = static_cast<Video *>(input.get()); - if (video == nullptr) { - return false; - } - if (!Writing(*video, data)) { - return false; - } - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - if (!Writing(*file, data)) { - return false; - } - break; - } - case UDType::AUDIO: { - auto audio = static_cast<Audio *>(input.get()); - if (audio == nullptr) { - return false; - } - if (!Writing(*audio, data)) { - return false; - } - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - if (!Writing(*file, data)) { - return false; - } - break; - } - case UDType::FOLDER: { - auto folder = static_cast<Folder *>(input.get()); - if (folder == nullptr) { - return false; - } - if (!Writing(*folder, data)) { - return false; - } - auto file = static_cast<File *>(input.get()); - if (file == nullptr) { - return false; - } - if (!Writing(*file, data)) { - return false; - } - break; - } - case UDType::SYSTEM_DEFINED_RECORD: { - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - if (!Writing(*sdRecord, data)) { - return false; - } - break; - } - case UDType::SYSTEM_DEFINED_FORM: { - auto form = static_cast<SystemDefinedForm *>(input.get()); - if (form == nullptr) { - return false; - } - if (!Writing(*form, data)) { - return false; - } - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - if (!Writing(*sdRecord, data)) { - return false; - } - break; - } - case UDType::SYSTEM_DEFINED_APP_ITEM: { - auto appItem = static_cast<SystemDefinedAppItem *>(input.get()); - if (appItem == nullptr) { - return false; - } - if (!Writing(*appItem, data)) { - return false; - } - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - if (!Writing(*sdRecord, data)) { - return false; - } - break; - } - case UDType::SYSTEM_DEFINED_PIXEL_MAP: { - auto pixelMap = static_cast<SystemDefinedPixelMap *>(input.get()); - if (pixelMap == nullptr) { - return false; - } - if (!Writing(*pixelMap, data)) { - return false; - } - auto sdRecord = static_cast<SystemDefinedRecord *>(input.get()); - if (sdRecord == nullptr) { - return false; - } - if (!Writing(*sdRecord, data)) { - return false; - } - break; - } - case UDType::APPLICATION_DEFINED_RECORD: { - auto record = static_cast<ApplicationDefinedRecord *>(input.get()); - if (record == nullptr) { - return false; - } - if (!Writing(*record, data)) { - return false; - } - break; - } - case UDType::FILE_URI: { - if (input == nullptr) { - return false; - } - if (!Writing(input->GetValue(), data)) { - return false; - } - break; - } - default: { - return false; - } - } - if (!Writing(input->GetOriginValue(), data)) { - return false; - } - return true; -} - -template<> -bool Reading(std::shared_ptr<UnifiedRecord> &output, TLVObject &data) -{ - UDType type ; - if (!Reading(type, data)) { - return false; - } - std::string uid; - if (!Reading(uid, data)) { - return false; - } - switch (type) { - case UDType::TEXT: { - std::shared_ptr<Text> text = std::make_shared<Text>(); - if (!Reading(*text, data)) { - return false; - } - output = text; - break; - } - case UDType::PLAIN_TEXT: { - std::shared_ptr<PlainText> plainText = std::make_shared<PlainText>(); - if (!Reading(*plainText, data)) { - return false; - } - output = plainText; - break; - } - case UDType::HTML: { - std::shared_ptr<Html> html = std::make_shared<Html>(); - if (!Reading(*html, data)) { - return false; - } - output = html; - break; - } - case UDType::HYPERLINK: { - std::shared_ptr<Link> link = std::make_shared<Link>(); - if (!Reading(*link, data)) { - return false; - } - output = link; - break; - } - case UDType::FILE: { - std::shared_ptr<File> file = std::make_shared<File>(); - if (!Reading(*file, data)) { - return false; - } - output = file; - break; - } - case UDType::IMAGE: { - std::shared_ptr<Image> image = std::make_shared<Image>(); - if (!Reading(*image, data)) { - return false; - } - output = image; - break; - } - case UDType::VIDEO: { - std::shared_ptr<Video> video = std::make_shared<Video>(); - if (!Reading(*video, data)) { - return false; - } - output = video; - break; - } - case UDType::AUDIO: { - std::shared_ptr<Audio> audio = std::make_shared<Audio>(); - if (!Reading(*audio, data)) { - return false; - } - output = audio; - break; - } - case UDType::FOLDER: { - std::shared_ptr<Folder> folder = std::make_shared<Folder>(); - if (!Reading(*folder, data)) { - return false; - } - output = folder; - break; - } - case UDType::SYSTEM_DEFINED_RECORD: { - std::shared_ptr<SystemDefinedRecord> sdRecord = std::make_shared<SystemDefinedRecord>(); - if (!Reading(*sdRecord, data)) { - return false; - } - output = sdRecord; - break; - } - case UDType::SYSTEM_DEFINED_FORM: { - std::shared_ptr<SystemDefinedForm> form = std::make_shared<SystemDefinedForm>(); - if (!Reading(*form, data)) { - return false; - } - output = form; - break; - } - case UDType::SYSTEM_DEFINED_APP_ITEM: { - std::shared_ptr<SystemDefinedAppItem> appItem = std::make_shared<SystemDefinedAppItem>(); - if (!Reading(*appItem, data)) { - return false; - } - output = appItem; - break; - } - case UDType::SYSTEM_DEFINED_PIXEL_MAP: { - std::shared_ptr<SystemDefinedPixelMap> pixelMap = std::make_shared<SystemDefinedPixelMap>(); - if (!Reading(*pixelMap, data)) { - return false; - } - output = pixelMap; - break; - } - case UDType::APPLICATION_DEFINED_RECORD: { - std::shared_ptr<ApplicationDefinedRecord> record = std::make_shared<ApplicationDefinedRecord>(); - if (!Reading(*record, data)) { - return false; - } - output = record; - break; - } - case UDType::FILE_URI: { - output = std::make_shared<UnifiedRecord>(); - break; - } - default: { - return false; - } - } - ValueType value; - if (!Reading(value, data)) { - LOG_WARN(UDMF_CLIENT, "Reading value empty."); - } - output->SetUid(uid); - output->SetType(type); - output->SetValue(value); - return true; -} - -template<> -bool Writing(const UnifiedData &input, TLVObject &data) -{ - if (data.GetBuffer().size() == 0) { - if (!CountBufferSize(input, data)) { - return false; - } - data.UpdateSize(); - } - - int32_t size = static_cast<int32_t>(input.GetRecords().size()); - if (!Writing(size, data)) { - return false; - } - - for (auto record : input.GetRecords()) { - if (!Writing(record, data)) { - return false; - } - } - return true; -} - -template<> -bool Reading(UnifiedData &output, TLVObject &data) -{ - int32_t size; - if (!Reading(size, data)) { - return false; - } - while (size-- > 0) { - std::shared_ptr<UnifiedRecord> record; - if (!Reading(record, data)) { - return false; - } - output.AddRecord(record); - } - return true; -} - -template<> -bool Writing(const std::vector<UnifiedData> &input, TLVObject &data) -{ - if (!CountBufferSize(input, data)) { - return false; - } - data.UpdateSize(); - - int32_t size = static_cast<int32_t>(input.size()); - if (!Writing(size, data)) { - return false; - } - - for (auto unifiedData : input) { - if (!Writing(unifiedData, data)) { - return false; - } - } - return true; -} - -template<> -bool Reading(std::vector<UnifiedData> &output, TLVObject &data) -{ - int32_t size; - if (!Reading(size, data)) { - return false; - } - while (size-- > 0) { - UnifiedData unifiedData; - if (!Reading(unifiedData, data)) { - return false; - } - output.push_back(unifiedData); - } - return true; -} - -template<> -bool Writing(const UnifiedKey &input, TLVObject &data) -{ - if (!Writing(input.key, data)) { - return false; - } - if (!Writing(input.intention, data)) { - return false; - } - if (!Writing(input.bundleName, data)) { - return false; - } - if (!Writing(input.groupId, data)) { - return false; - } - return true; -} - -template<> -bool Reading(UnifiedKey &output, TLVObject &data) -{ - std::string key; - std::string intention; - std::string bundleName; - std::string groupId; - if (!Reading(key, data)) { - return false; - } - if (!Reading(intention, data)) { - return false; - } - if (!Reading(bundleName, data)) { - return false; - } - if (!Reading(groupId, data)) { - return false; - } - output.key = key; - output.intention = intention; - output.bundleName = bundleName; - output.groupId = groupId; - return true; -} - -template<> -bool Writing(const Privilege &input, TLVObject &data) -{ - if (!Writing(input.tokenId, data)) { - return false; - } - if (!Writing(input.readPermission, data)) { + auto err = memcpy_s(buffer, val.size(), val.data(), val.size()); + if (err != EOK) { + LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read want. tag=%{public}hu", head.tag); return false; } - if (!Writing(input.writePermission, data)) { + if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) { + LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag); return false; } - return true; -} - -template<> -bool Reading(Privilege &output, TLVObject &data) -{ - uint32_t tokenId; - std::string readPermission; - std::string writePermission; - if (!Reading(tokenId, data)) { - return false; - } - if (!Reading(readPermission, data)) { - return false; - } - if (!Reading(writePermission, data)) { - return false; - } - output.tokenId = tokenId; - output.readPermission = readPermission; - output.writePermission = writePermission; - return true; -} - -template<> -bool Writing(const DataStatus &input, TLVObject &data) -{ - int32_t status = input; - return Writing(status, data); -} - -template<> -bool Reading(DataStatus &output, TLVObject &data) -{ - int32_t status; - if (!Reading(status, data)) { - return false; - } - if (status < DataStatus::WORKING || status >= DataStatus::FADE) { - return false; - } - output = static_cast<DataStatus>(status); - return true; -} - -template<> -bool Writing(const Runtime &input, TLVObject &data) -{ - (void)CountBufferSize(input, data); - data.UpdateSize(); - if (!Writing(input.key, data)) { - return false; - } - if (!Writing(input.isPrivate, data)) { - return false; - } - uint32_t size = static_cast<uint32_t>(input.privileges.size()); - if (!Writing(size, data)) { - return false; - } - for (uint32_t i = 0; i < size; ++i) { - if (!Writing(input.privileges[i], data)) { - return false; - } - } - if (!Writing(static_cast<int64_t>(input.createTime), data)) { - return false; - } - if (!Writing(input.sourcePackage, data)) { - return false; - } - if (!Writing(input.dataStatus, data)) { + auto want = AAFwk::Want::Unmarshalling(*parcel); + if (want == nullptr) { + LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag); return false; } - if (!Writing(input.dataVersion, data)) { - return false; - } - if (!Writing(static_cast<int64_t>(input.lastModifiedTime), data)) { - return false; - } - if (!Writing(input.createPackage, data)) { - return false; - } - if (!Writing(input.deviceId, data)) { - return false; - } - if (!Writing(input.recordTotalNum, data)) { - return false; - } - if (!Writing(input.tokenId, data)) { - return false; - } - return true; -} - -template<> -bool Reading(Runtime &output, TLVObject &data) -{ - UnifiedKey key; - bool isPrivate; - uint32_t size; - std::vector<Privilege> privileges; - int64_t createTime; - std::string sourcePackage; - DataStatus dataStatus; - int32_t dataVersion; - int64_t lastModifiedTime; - std::string createPackage; - std::string deviceId; - uint32_t recordTotalNum; - uint32_t tokenId = 0; - if (!Reading(key, data)) { - return false; - } - if (!Reading(isPrivate, data)) { - return false; - } - if (!Reading(size, data)) { - return false; - } - for (uint32_t i = 0; i < size; ++i) { - Privilege privilege; - if (!Reading(privilege, data)) { - return false; - } - privileges.emplace_back(privilege); - } - if (!Reading(createTime, data)) { - return false; - } - if (!Reading(sourcePackage, data)) { - return false; - } - if (!Reading(dataStatus, data)) { - return false; - } - if (!Reading(dataVersion, data)) { - return false; - } - if (!Reading(lastModifiedTime, data)) { - return false; - } - if (!Reading(createPackage, data)) { - return false; - } - if (!Reading(deviceId, data)) { - return false; - } - if (!Reading(recordTotalNum, data)) { - return false; - } - if (!Reading(tokenId, data)) { - LOG_WARN(UDMF_CLIENT, "Reading tokenId empty."); - } - output.key = key; - output.isPrivate = isPrivate; - output.privileges = privileges; - output.createTime = createTime; - output.sourcePackage = sourcePackage; - output.dataStatus = dataStatus; - output.dataVersion = dataVersion; - output.lastModifiedTime = lastModifiedTime; - output.createPackage = createPackage; - output.deviceId = deviceId; - output.recordTotalNum = recordTotalNum; - output.tokenId = tokenId; + output = std::shared_ptr<OHOS::AAFwk::Want>(want); return true; } } // namespace TLVUtil -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/udmf/framework/common/tlv_util.h b/udmf/framework/common/tlv_util.h index 30b46ada..309d96c3 100644 --- a/udmf/framework/common/tlv_util.h +++ b/udmf/framework/common/tlv_util.h @@ -4,7 +4,7 @@ * 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 + * 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, @@ -16,213 +16,371 @@ #ifndef UDMF_TLV_UTIL_H #define UDMF_TLV_UTIL_H -#include <type_traits> -#include "visibility.h" -#include "application_defined_record.h" -#include "audio.h" -#include "file.h" -#include "folder.h" -#include "html.h" -#include "image.h" -#include "link.h" -#include "plain_text.h" -#include "system_defined_appitem.h" -#include "system_defined_form.h" -#include "system_defined_pixelmap.h" -#include "system_defined_record.h" -#include "text.h" -#include "tlv_object.h" + +#include <utility> +#include <vector> +#include "unified_types.h" #include "unified_data.h" #include "unified_key.h" -#include "unified_meta.h" +#include "tlv_object.h" #include "unified_record.h" -#include "unified_types.h" -#include "video.h" + namespace OHOS { namespace TLVUtil { using namespace OHOS::UDMF; -template<typename T> -bool API_EXPORT CountBufferSize(const T &input, TLVObject &data); - -template<> -bool API_EXPORT CountBufferSize(const std::shared_ptr<UnifiedRecord> &input, TLVObject &data); - -template<> -bool API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data); - -template<> -bool API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data); - -template<> -bool API_EXPORT CountBufferSize(const std::vector<UnifiedData> &input, TLVObject &data); - -template<typename T> -bool API_EXPORT Writing(const T &input, TLVObject &data); -template<typename T> -bool API_EXPORT Reading(T &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const int32_t &input, TLVObject &data); -template<> -bool API_EXPORT Reading(int32_t &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const int64_t &input, TLVObject &data); -template<> -bool API_EXPORT Reading(int64_t &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const bool &input, TLVObject &data); -template<> -bool API_EXPORT Reading(bool &output, TLVObject &data); - -template<> -bool API_EXPORT Reading(uint32_t &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const uint32_t &input, TLVObject &data); - -template<> -bool API_EXPORT Reading(uint64_t &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const uint64_t &input, TLVObject &data); - -template<> -bool API_EXPORT Writing(const std::string &input, TLVObject &data); -template<> -bool API_EXPORT Reading(std::string &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const std::vector<uint8_t> &input, TLVObject &data); -template<> -bool API_EXPORT Reading(std::vector<uint8_t> &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const UDVariant &input, TLVObject &data); -template<> -bool API_EXPORT Reading(UDVariant &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const ValueType &input, TLVObject &data); -template<> -bool API_EXPORT Reading(ValueType &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const UDDetails &input, TLVObject &data); -template<> -bool API_EXPORT Reading(UDDetails &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const UDType &input, TLVObject &data); -template<> -bool API_EXPORT Reading(UDType &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Text &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Text &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const PlainText &input, TLVObject &data); -template<> -bool API_EXPORT Reading(PlainText &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Html &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Html &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Link &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Link &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const File &input, TLVObject &data); -template<> -bool API_EXPORT Reading(File &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Image &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Image &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Video &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Video &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Audio &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Audio &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Folder &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Folder &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const SystemDefinedRecord &input, TLVObject &data); -template<> -bool API_EXPORT Reading(SystemDefinedRecord &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const SystemDefinedForm &input, TLVObject &data); -template<> -bool API_EXPORT Reading(SystemDefinedForm &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const SystemDefinedAppItem &input, TLVObject &data); -template<> -bool API_EXPORT Reading(SystemDefinedAppItem &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const SystemDefinedPixelMap &input, TLVObject &data); -template<> -bool API_EXPORT Reading(SystemDefinedPixelMap &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const ApplicationDefinedRecord &input, TLVObject &data); -template<> -bool API_EXPORT Reading(ApplicationDefinedRecord &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const std::shared_ptr<UnifiedRecord> &input, TLVObject &data); -template<> -bool API_EXPORT Reading(std::shared_ptr<UnifiedRecord> &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data); -template<> -bool API_EXPORT Reading(UnifiedData &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const std::vector<UnifiedData> &input, TLVObject &data); -template<> -bool API_EXPORT Reading(std::vector<UnifiedData> &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data); -template<> -bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Privilege &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Privilege &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const DataStatus &input, TLVObject &data); -template<> -bool API_EXPORT Reading(DataStatus &output, TLVObject &data); - -template<> -bool API_EXPORT Writing(const Runtime &input, TLVObject &data); -template<> -bool API_EXPORT Reading(Runtime &output, TLVObject &data); + +template <typename T> bool API_EXPORT ReadTlv(T &output, TLVObject &data, TAG tag); + +template <typename T> size_t API_EXPORT CountBufferSize(const T &input, TLVObject &data); +template <typename T> bool API_EXPORT Writing(const T &input, TLVObject &data, TAG tag); +template <typename T> bool API_EXPORT Reading(T &output, TLVObject &data, const TLVHead &head); + +template <typename... _Types> size_t API_EXPORT CountBufferSize(const std::variant<_Types...> &input, TLVObject &data); +template <typename... _Types> bool API_EXPORT Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag); +template <typename... _Types> +bool API_EXPORT Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head); + +template <typename T> size_t API_EXPORT CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data); +template <typename T> bool API_EXPORT Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag); +template <typename T> bool API_EXPORT Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head); + +template <typename T> size_t API_EXPORT CountBufferSize(const std::vector<T> &input, TLVObject &data); +template <typename T> bool API_EXPORT Writing(const std::vector<T> &input, TLVObject &data, TAG tag); +template <typename T> bool API_EXPORT Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head); + +template <typename T, typename R> size_t API_EXPORT CountBufferSize(const std::map<T, R> &input, TLVObject &data); +template <typename T, typename R> bool API_EXPORT Writing(const std::map<T, R> &input, TLVObject &data, TAG tag); +template <typename T, typename R> bool API_EXPORT Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::nullptr_t &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::nullptr_t &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::monostate &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::monostate &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(std::monostate &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::string &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::string &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(std::string &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const UDType &input, TLVObject &data); +template <> bool API_EXPORT Writing(const UDType &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(UDType &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const DataStatus &input, TLVObject &data); +template <> bool API_EXPORT Writing(const DataStatus &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(DataStatus &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const Object &input, TLVObject &data); +template <> bool API_EXPORT Writing(const Object &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(Object &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const UnifiedKey &input, TLVObject &data); +template <> bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data); +template <> bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(UnifiedData &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const UnifiedRecord &input, TLVObject &data); +template <> bool API_EXPORT Writing(const UnifiedRecord &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data); +template <> bool API_EXPORT Writing(const Runtime &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(Runtime &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const Privilege &input, TLVObject &data); +template <> bool API_EXPORT Writing(const Privilege &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(Privilege &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag); +template <> +bool API_EXPORT Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head); + +template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data); +template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag); +template <> bool API_EXPORT Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head); + +template <typename T> bool ReadTlv(T &output, TLVObject &data, TAG tag) +{ + while (data.GetCursor() < data.GetTotal()) { + TLVHead head{}; + if (!data.ReadHead(head)) { + return false; + } + if (head.tag != static_cast<uint16_t>(tag)) { + data.Skip(head); + continue; + } + if (!Reading(output, data, head)) { + return false; + } + } + return true; +} + +template <typename T> void InitWhenFirst(T input, TLVObject &data) +{ + if (data.GetCursor() == data.GetTotal()) { + CountBufferSize(input, data); + data.UpdateSize(); + } +} + +template <typename T> size_t CountBufferSize(const T &input, TLVObject &data) +{ + return data.CountBasic(input); +} + +template <typename T> bool Writing(const T &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + return data.WriteBasic(tag, input); +} + +template <typename T> bool Reading(T &output, TLVObject &data, const TLVHead &head) +{ + return data.ReadBasic(output, head); +} + +template <typename T> size_t CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data) +{ + if (input == nullptr) { + return data.CountHead(); + } + return CountBufferSize(*input, data); +} + +template <typename T> bool Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag) +{ + if (input == nullptr) { + return false; + } + InitWhenFirst(input, data); + return Writing(*input, data, tag); +} + +template <typename T> bool Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head) +{ + if (output == nullptr) { + output = std::make_shared<T>(); + } + return Reading(*output, data, head); +} + +template <typename T> size_t CountBufferSize(const std::vector<T> &input, TLVObject &data) +{ + auto size = data.CountHead() + data.CountBasic(input.size()); + for (auto item : input) { + size += CountBufferSize(item, data); + } + return size; +} + +template <typename T> bool Writing(const std::vector<T> &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + if (!data.WriteBasic(TAG::TAG_VECTOR_SIZE, input.size())) { + return false; + } + if (!input.empty()) { + for (auto item : input) { + if (!Writing(item, data, TAG::TAG_VECTOR_ITEM)) { + return false; + } + } + } + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); +} + +template <typename T> bool Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head) +{ + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead itemHead{}; + if (!data.ReadHead(itemHead)) { + return false; + } + if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_VECTOR_ITEM)) { + T item{}; + if (!Reading(item, data, itemHead)) { + return false; + } + output.push_back(std::move(item)); + continue; + } + if (!data.Skip(itemHead)) { + return false; + } + } + return true; +} + +template <typename T, typename R> size_t CountBufferSize(const std::map<T, R> &input, TLVObject &data) +{ + auto size = data.CountHead(); + for (auto item : input) { + size += data.CountHead() + CountBufferSize(item.first, data) + CountBufferSize(item.second, data); + } + return size; +} + +template <typename T, typename R> bool Writing(const std::map<T, R> &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + if (!input.empty()) { + for (auto item : input) { + auto pairCursor = data.GetCursor(); + data.OffsetHead(); + if (!TLVUtil::Writing(item.first, data, TAG::TAG_MAP_KEY)) { + return false; + } + if (!TLVUtil::Writing(item.second, data, TAG::TAG_MAP_VALUE)) { + return false; + } + if (!data.WriteBackHead(static_cast<uint16_t>(TAG::TAG_MAP_PAIR), pairCursor, + data.GetCursor() - pairCursor - sizeof(TLVHead))) { + return false; + } + } + } + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); +} + +template <typename T, typename R> bool Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head) +{ + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headPair{}; + if (!data.ReadHead(headPair)) { + return false; + } + if (headPair.tag != static_cast<uint16_t>(TAG::TAG_MAP_PAIR)) { + return false; + } + TLVHead headKey{}; + if (!data.ReadHead(headKey) || headKey.tag != static_cast<uint16_t>(TAG::TAG_MAP_KEY)) { + return false; + } + T itemKey{}; + if (!Reading(itemKey, data, headKey)) { + return false; + } + TLVHead headValue{}; + if (!data.ReadHead(headValue) || headValue.tag != static_cast<uint16_t>(TAG::TAG_MAP_VALUE)) { + return false; + } + R itemValue{}; + if (!Reading(itemValue, data, headValue)) { + return false; + } + output.emplace(std::move(itemKey), std::move(itemValue)); + } + return true; +} + +template <typename _InTp> size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &intput) +{ + return 0; +} + +template <typename _InTp, typename _First, typename... _Rest> +size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input) +{ + if (step == input.index()) { + return CountBufferSize(std::get<_First>(input), data); + } + return CountVariant<_InTp, _Rest...>(data, step + 1, input); +} + +template <typename... _Types> size_t CountBufferSize(const std::variant<_Types...> &input, TLVObject &data) +{ + if (input.index() > size_t(std::numeric_limits<uint32_t>::max())) { + return 0; + } + uint32_t index = static_cast<uint32_t>(input.index()); + return data.CountHead() + data.CountBasic(index) + CountVariant<decltype(input), _Types...>(data, 0, input); +} + +template <typename _InTp> bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag) +{ + return true; +} + +template <typename _InTp, typename _First, typename... _Rest> +bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag) +{ + if (step == input.index()) { + auto val = std::get<_First>(input); + return Writing(val, data, tag); + } + return WriteVariant<_InTp, _Rest...>(data, step + 1, input, tag); +} + +template <typename... _Types> bool Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag) +{ + InitWhenFirst(input, data); + auto tagCursor = data.GetCursor(); + data.OffsetHead(); + uint32_t index = input.index(); + if (!data.WriteBasic(TAG::TAG_VARIANT_INDEX, index)) { + return false; + } + if (!WriteVariant<decltype(input), _Types...>(data, 0, input, TAG::TAG_VARIANT_ITEM)) { + return false; + } + return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead)); +} + +template <typename _OutTp> bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head) +{ + return true; +} + +template <typename _OutTp, typename _First, typename... _Rest> +bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head) +{ + if (step == index) { + _First output{}; + auto success = Reading(output, data, head); + value = output; + return success; + } + return ReadVariant<_OutTp, _Rest...>(data, step + 1, index, value, head); +} + +template <typename... _Types> bool Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head) +{ + uint32_t index = 0; + auto endCursor = data.GetCursor() + head.len; + while (data.GetCursor() < endCursor) { + TLVHead headItem{}; + if (!data.ReadHead(headItem)) { + return false; + } + if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VARIANT_INDEX)) { + if (!Reading(index, data, headItem)) { + return false; + } + } else { + return ReadVariant<decltype(output), _Types...>(data, 0, index, output, headItem); + } + } + return true; +} } // namespace TLVUtil } // namespace OHOS -#endif // UDMF_TLV_UTIL_H \ No newline at end of file +#endif // UDMF_TLV_UTIL_H diff --git a/udmf/framework/common/udmf_types_util.cpp b/udmf/framework/common/udmf_types_util.cpp index 6e4de8bf..ad2d5723 100644 --- a/udmf/framework/common/udmf_types_util.cpp +++ b/udmf/framework/common/udmf_types_util.cpp @@ -17,6 +17,7 @@ #include "logger.h" #include "tlv_util.h" +#include "udmf_conversion.h" namespace OHOS { namespace ITypesUtil { @@ -26,7 +27,7 @@ bool Marshalling(const UnifiedData &input, MessageParcel &parcel) { std::vector<uint8_t> dataBytes; auto recordTlv = TLVObject(dataBytes); - if (!TLVUtil::Writing(input, recordTlv)) { + if (!TLVUtil::Writing(input, recordTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_SERVICE, "TLV writing failed!"); return false; } @@ -53,11 +54,12 @@ bool Unmarshalling(UnifiedData &output, MessageParcel &parcel) } const uint8_t *data = reinterpret_cast<const uint8_t *>(rawData); std::vector<uint8_t> dataBytes(data, data + size); - auto recordTlv = TLVObject(dataBytes); - if (!TLVUtil::Reading(output, recordTlv)) { + auto dataTlv = TLVObject(dataBytes); + if (!TLVUtil::ReadTlv(output, dataTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_SERVICE, "Unmarshall unified data failed!"); return false; } + UdmfConversion::ConvertRecordToSubclass(output); return true; } @@ -66,7 +68,7 @@ bool Marshalling(const std::vector<UnifiedData> &input, MessageParcel &parcel) { std::vector<uint8_t> dataSetBytes; auto recordTlv = TLVObject(dataSetBytes); - if (!TLVUtil::Writing(input, recordTlv)) { + if (!TLVUtil::Writing(input, recordTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_SERVICE, "TLV writing failed!"); return false; } @@ -92,11 +94,12 @@ bool Unmarshalling(std::vector<UnifiedData> &output, MessageParcel &parcel) return false; } std::vector<uint8_t> dataSetBytes(rawData, rawData + size); - auto recordTlv = TLVObject(dataSetBytes); - if (!TLVUtil::Reading(output, recordTlv)) { + auto dataTlv = TLVObject(dataSetBytes); + if (!TLVUtil::ReadTlv(output, dataTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_SERVICE, "Unmarshall unified data set failed!"); return false; } + UdmfConversion::ConvertRecordToSubclass(output); return true; } diff --git a/udmf/framework/common/udmf_utils.cpp b/udmf/framework/common/udmf_utils.cpp index 2c0c1b17..0561c64a 100644 --- a/udmf/framework/common/udmf_utils.cpp +++ b/udmf/framework/common/udmf_utils.cpp @@ -15,6 +15,8 @@ #include "udmf_utils.h" #include <random> #include <sstream> +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" namespace OHOS { namespace UDMF { @@ -60,6 +62,25 @@ std::string GenerateId() } return idStr.str(); } + +std::string GetSdkVersionByToken(uint32_t tokenId) +{ + if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) != + Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) { + return ""; + } + Security::AccessToken::HapTokenInfo hapTokenInfo; + auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo); + if (ret != 0) { + return ""; + } + return std::to_string(hapTokenInfo.apiVersion); +} + +std::string GetCurrentSdkVersion() +{ + return GetSdkVersionByToken(IPCSkeleton::GetSelfTokenID()); +} } // namespace UTILS } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/common/udmf_utils.h b/udmf/framework/common/udmf_utils.h index 7f5c7934..f17a08d2 100644 --- a/udmf/framework/common/udmf_utils.h +++ b/udmf/framework/common/udmf_utils.h @@ -27,6 +27,10 @@ std::vector<uint8_t> Random(int32_t len, int32_t minimum = 0, int32_t maximum = std::numeric_limits<uint8_t>::max()); std::string GenerateId(); +std::string GetSdkVersionByToken(uint32_t tokenId); + +std::string GetCurrentSdkVersion(); + } // namespace UTILS } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/common/unittest/BUILD.gn b/udmf/framework/common/unittest/BUILD.gn index 86c36282..4afce7f0 100644 --- a/udmf/framework/common/unittest/BUILD.gn +++ b/udmf/framework/common/unittest/BUILD.gn @@ -19,10 +19,13 @@ module_output_path = "udmf/common" config("module_private_config") { include_dirs = [ "${udmf_interfaces_path}/innerkits/common", + "${udmf_interfaces_path}/innerkits/convert", "${udmf_framework_path}/innerkitsimpl/data", "${udmf_framework_path}/common", "${kv_store_path}/frameworks/common", "${udmf_interfaces_path}/innerkits/data", + "${udmf_framework_path}/common/unittest/mock/include", + "${udmf_framework_path}/innerkitsimpl/client/", ] } @@ -30,10 +33,25 @@ common_deps = [ "${udmf_interfaces_path}/innerkits:udmf_client" ] common_external_deps = [ "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "bundle_framework:appexecfwk_core", "c_utils:utils", + "ffmpeg:libohosffmpeg", "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", "image_framework:image", + "image_framework:image", + "image_framework:image_native", + "image_framework:pixelmap", "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "libexif:libexif", + "samgr:samgr_proxy", ] ohos_unittest("UtdCfgsCheckerTest") { @@ -70,11 +88,75 @@ ohos_unittest("UdmfTypesUtilTest") { ] } +ohos_unittest("UdmfTypesUtilAbnormalTest") { + module_out_path = module_output_path + + sources = [ + "${udmf_framework_path}/common/tlv_object.cpp", + "${udmf_framework_path}/common/udmf_types_util.cpp", + "${udmf_framework_path}/common/unittest/mock/tlv_util_mock.cpp", + "${udmf_framework_path}/innerkitsimpl/common/unified_meta.cpp", + "${udmf_framework_path}/innerkitsimpl/convert/udmf_conversion.cpp", + "${udmf_framework_path}/innerkitsimpl/data/application_defined_record.cpp", + "${udmf_framework_path}/innerkitsimpl/data/file.cpp", + "${udmf_framework_path}/innerkitsimpl/data/image.cpp", + "${udmf_framework_path}/innerkitsimpl/data/plain_text.cpp", + "${udmf_framework_path}/innerkitsimpl/data/system_defined_form.cpp", + "${udmf_framework_path}/innerkitsimpl/data/system_defined_record.cpp", + "${udmf_framework_path}/innerkitsimpl/data/text.cpp", + "${udmf_framework_path}/innerkitsimpl/data/unified_data.cpp", + "${udmf_framework_path}/innerkitsimpl/data/unified_record.cpp", + "udmf_types_util_abnormal_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "${udmf_interfaces_path}/innerkits:udmf_client", + "${udmf_interfaces_path}/innerkits:utd_client", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = common_external_deps + + defines = [ + "private=public", + "protected=public", + ] +} + +ohos_unittest("TlvUtilTest") { + module_out_path = module_output_path + + sources = [ "tlv_util_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = common_deps + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "image_framework:image", + "image_framework:image_native", + "image_framework:pixelmap", + ] + + defines = [ + "private=public", + "protected=public", + ] +} + ############################################################################### group("unittest") { testonly = true deps = [ + ":TlvUtilTest", + ":UdmfTypesUtilAbnormalTest", ":UdmfTypesUtilTest", ":UtdCfgsCheckerTest", ] diff --git a/udmf/framework/common/unittest/mock/tlv_util_mock.cpp b/udmf/framework/common/unittest/mock/tlv_util_mock.cpp new file mode 100644 index 00000000..801a1016 --- /dev/null +++ b/udmf/framework/common/unittest/mock/tlv_util_mock.cpp @@ -0,0 +1,232 @@ +/* + * 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 "tlv_util.h" + +#include "logger.h" + +namespace OHOS { +namespace TLVUtil { +template <> size_t CountBufferSize(const std::nullptr_t &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::nullptr_t &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const std::monostate &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::monostate &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(std::monostate &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const std::string &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::string &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(std::string &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const UDType &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const UDType &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(UDType &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const DataStatus &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const DataStatus &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(DataStatus &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const Object &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const Object &input, TLVObject &data, TAG tag) +{ + return true; +} +template <> bool Reading(Object &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const UnifiedKey &input, TLVObject &data) +{ + return sizeof(TLVHead); +} +template <> bool Writing(const UnifiedKey &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const UnifiedData &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const UnifiedData &input, TLVObject &data, TAG tag) +{ + return false; +} + +template <> bool Reading(UnifiedData &output, TLVObject &data, const TLVHead &head) +{ + return false; +} + +template <> size_t CountBufferSize(const UnifiedRecord &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const UnifiedRecord &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const Runtime &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const Runtime &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(Runtime &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const Privilege &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const Privilege &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(Privilege &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag) +{ + return true; +} + +template <> bool Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + +template <> size_t CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data) +{ + return sizeof(TLVHead); +} + +template <> bool Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag) +{ + return true; +} + + +template <> bool Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head) +{ + return true; +} + + +} // namespace TLVUtil +} // namespace OHOS diff --git a/udmf/framework/common/unittest/tlv_util_test.cpp b/udmf/framework/common/unittest/tlv_util_test.cpp new file mode 100644 index 00000000..174663f5 --- /dev/null +++ b/udmf/framework/common/unittest/tlv_util_test.cpp @@ -0,0 +1,654 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#define LOG_TAG "TlvUtilTest" + +#include "tlv_util.h" +#include <gtest/gtest.h> +#include "unified_data.h" +#include "logger.h" +#include "plain_text.h" +#include "html.h" +#include "link.h" +#include "system_defined_appitem.h" +#include "application_defined_record.h" +#include "file.h" +#include "system_defined_form.h" +#include "system_defined_pixelmap.h" +#include "system_defined_record.h" +#include "udmf_conversion.h" +#include "unified_meta.h" +#include "unified_record.h" +#include "unified_types.h" + +using namespace testing::ext; +using namespace OHOS::UDMF; +using namespace OHOS; + +namespace OHOS::Test { +class TlvUtilTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void TlvUtilTest::SetUpTestCase(void) {} +void TlvUtilTest::TearDownTestCase(void) {} +void TlvUtilTest::SetUp(void) {} +void TlvUtilTest::TearDown(void) {} + +/* * + * @tc.name: CountBufferSize_001 + * @tc.desc: test fundamental for countBufferSize + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, CountBufferSize_001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "CountBufferSize_001 begin."); + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + uint8_t num1 = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(num1), TLVUtil::CountBufferSize(num1, tlvObject)); // 7 + uint16_t num2 = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(num2), TLVUtil::CountBufferSize(num2, tlvObject)); // 8 + uint32_t num3 = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(num3), TLVUtil::CountBufferSize(num3, tlvObject)); // 10 + int16_t num4 = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(num4), TLVUtil::CountBufferSize(num4, tlvObject)); // 8 + int32_t num5 = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(num5), TLVUtil::CountBufferSize(num5, tlvObject)); // 10 + bool boolean = true; + EXPECT_EQ(sizeof(TLVHead) + sizeof(boolean), TLVUtil::CountBufferSize(boolean, tlvObject)); // 7 + double doubleNum = 1; + EXPECT_EQ(sizeof(TLVHead) + sizeof(doubleNum), TLVUtil::CountBufferSize(doubleNum, tlvObject)); // 14 + EXPECT_EQ(sizeof(TLVHead), TLVUtil::CountBufferSize(std::nullptr_t(), tlvObject)); // 6 + std::monostate monostate; + EXPECT_EQ(sizeof(TLVHead), TLVUtil::CountBufferSize(monostate, tlvObject)); // 6 + std::string str = "abc"; + EXPECT_EQ(sizeof(TLVHead) + str.size(), TLVUtil::CountBufferSize(str, tlvObject)); // 9 + UDType type = XML; + EXPECT_EQ(sizeof(TLVHead) + sizeof(type), TLVUtil::CountBufferSize(type, tlvObject)); // 10 + DataStatus status = HISTORY; + EXPECT_EQ(sizeof(TLVHead) + sizeof(status), TLVUtil::CountBufferSize(status, tlvObject)); // 10 + std::vector<uint8_t> u8Vector = { 1, 1, 1 }; + EXPECT_EQ(sizeof(TLVHead) + u8Vector.size(), TLVUtil::CountBufferSize(u8Vector, tlvObject)); // 9 + std::shared_ptr<uint8_t> ptr; + EXPECT_EQ(sizeof(TLVHead), TLVUtil::CountBufferSize(ptr, tlvObject)); // 6 + ptr = std::make_shared<uint8_t>(1); + EXPECT_EQ(sizeof(TLVHead) + 1, TLVUtil::CountBufferSize(ptr, tlvObject)); // 7 + LOG_INFO(UDMF_TEST, "CountBufferSize_001 end."); +} + +/* * + * @tc.name: CountBufferSize_002 + * @tc.desc: test STL for countBufferSize + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, CountBufferSize_002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "CountBufferSize_002 begin."); + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + Privilege privilege1; + privilege1.readPermission = "111"; + Privilege privilege2; + privilege2.readPermission = "111"; + privilege2.writePermission = "xx"; + std::vector<Privilege> privilegeVector{ privilege1, privilege2 }; + EXPECT_EQ(10 * sizeof(TLVHead) + 2 * sizeof(uint32_t) + sizeof(size_t) + 8, + TLVUtil::CountBufferSize(privilegeVector, tlvObject)); // 80 + + Object object; + std::map<std::string, ValueType> map; + map["keyString"] = "value"; + double key = 12; + map["keyNum"] = key; + object.value_ = map; + EXPECT_EQ(12 * sizeof(TLVHead) + 36, TLVUtil::CountBufferSize(object, tlvObject)); // 108 + auto total = tlvObject.GetTotal(); + EXPECT_EQ(188, total); + LOG_INFO(UDMF_TEST, "CountBufferSize_002 end."); +} + +/* * + * @tc.name: CountBufferSize_003 + * @tc.desc: test udmf for countBufferSize + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, CountBufferSize_003, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "CountBufferSize_003 begin."); + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + std::shared_ptr<Object> object = std::make_shared<Object>(); + std::map<std::string, ValueType> map; + map["uniformDataType"] = UtdUtils::GetUtdIdFromUtdEnum(UDType::PLAIN_TEXT); + map["textContent"] = "content"; + map["abstract"] = "abstract"; + object->value_ = map; + std::shared_ptr<UnifiedRecord> record = std::make_shared<PlainText>(PLAIN_TEXT, object); + + std::vector<std::shared_ptr<UnifiedRecord>> vector = { record }; + UnifiedData data; + data.SetRecords(vector); + std::vector<UnifiedData> unifiedData = { data }; + auto size = TLVUtil::CountBufferSize(unifiedData, tlvObject); + EXPECT_EQ(tlvObject.GetTotal(), size); // 269 + LOG_INFO(UDMF_TEST, "CountBufferSize_003 end."); +} + +/* * + * @tc.name: CountBufferSize_004 + * @tc.desc: test other for countBufferSize + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, CountBufferSize_004, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "CountBufferSize_004 begin."); + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + UnifiedKey key; + key.key = "123456"; + key.intention = "DRAG"; + key.bundleName = "com.xxx"; + EXPECT_EQ(5 * sizeof(TLVHead) + 17, TLVUtil::CountBufferSize(key, tlvObject)); + + Privilege privilege; + EXPECT_EQ(4 * sizeof(TLVHead) + sizeof(int32_t), TLVUtil::CountBufferSize(privilege, tlvObject)); + + Runtime runtime; + EXPECT_EQ(19 * sizeof(TLVHead) + sizeof(bool) + sizeof(size_t) + 2 * sizeof(int64_t) + 2 * sizeof(int32_t) + + 2 * sizeof(uint32_t), + TLVUtil::CountBufferSize(runtime, tlvObject)); + LOG_INFO(UDMF_TEST, "CountBufferSize_004 end."); +} + +/* * + * @tc.name: WritingAndReading_001 + * @tc.desc: test fundamental for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReading_001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReading_001 begin."); + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + uint16_t num1 = 1; + auto result = TLVUtil::Writing(num1, tlvObject, TAG::TAG_UINT16); + int8_t num2 = 2; + result = TLVUtil::Writing(num2, tlvObject, TAG::TAG_INT8) && result; + uint32_t num3 = 3; + result = TLVUtil::Writing(num3, tlvObject, TAG::TAG_UINT32) && result; + int16_t num4 = 4; + result = TLVUtil::Writing(num4, tlvObject, TAG::TAG_INT16) && result; + int32_t num5 = 5; + result = result = TLVUtil::Writing(num5, tlvObject, TAG::TAG_INT32) && result; + bool boolean = true; + result = TLVUtil::Writing(boolean, tlvObject, TAG::TAG_BOOL) && result; + result = TLVUtil::Writing(std::nullptr_t(), tlvObject, TAG::TAG_NULL); + std::monostate monostate; + result = TLVUtil::Writing(monostate, tlvObject, TAG::TAG_MONOSTATE) && result; + std::string str = "abc"; + result = TLVUtil::Writing(str, tlvObject, TAG::TAG_STRING) && result; + UDType type = XML; + result = TLVUtil::Writing(type, tlvObject, TAG::TAG_UD_TYPE) && result; + DataStatus status = HISTORY; + result = TLVUtil::Writing(status, tlvObject, TAG::TAG_DATA_STATUS) && result; + std::vector<uint8_t> u8Vector = { 1, 2, 3 }; + result = TLVUtil::Writing(u8Vector, tlvObject, TAG::TAG_UINT8) && result; + EXPECT_TRUE(result); + + uint16_t num1Result; + int8_t num2Result; + uint32_t num3Result; + int16_t num4Result; + int32_t num5Result; + bool booleanResult; + std::string strResult; + UDType typeResult; + DataStatus statusResult; + std::vector<uint8_t> u8VectorResult; + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(statusResult, tlvObject, TAG::TAG_DATA_STATUS); + tlvObject.ResetCursor(); + EXPECT_EQ(status, statusResult); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(typeResult, tlvObject, TAG::TAG_UD_TYPE); + EXPECT_EQ(type, typeResult); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(strResult, tlvObject, TAG::TAG_STRING); + EXPECT_EQ(str, strResult); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(booleanResult, tlvObject, TAG::TAG_BOOL); + EXPECT_EQ(boolean, booleanResult); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(num5Result, tlvObject, TAG::TAG_INT32); + EXPECT_EQ(num5, num5Result); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(num4Result, tlvObject, TAG::TAG_INT16); + EXPECT_EQ(num4, num4Result); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(num3Result, tlvObject, TAG::TAG_UINT32); + EXPECT_EQ(num3, num3Result); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(num2Result, tlvObject, TAG::TAG_INT8); + EXPECT_EQ(num2, num2Result); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(num1Result, tlvObject, TAG::TAG_UINT16); + EXPECT_EQ(num1, num1Result); + + tlvObject.ResetCursor(); + TLVUtil::ReadTlv(u8VectorResult, tlvObject, TAG::TAG_UINT8); + for (int i = 0; i < 3; i++) { + EXPECT_EQ(u8Vector[i], u8VectorResult[i]); + } + LOG_INFO(UDMF_TEST, "WritingAndReading_001 end."); +} + +/* * + * @tc.name: WritingAndReading_002 + * @tc.desc: test Runtime for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReading_002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReading_002 begin."); + UnifiedKey key; + key.key = "123456"; + Privilege privilege; + privilege.readPermission = "read"; + privilege.tokenId = 333; + Privilege privilege2; + privilege2.writePermission = "read"; + privilege2.tokenId = 444; + Runtime runtime; + runtime.dataStatus = DELETED; + runtime.key = key; + runtime.privileges.push_back(privilege); + runtime.privileges.push_back(privilege2); + runtime.createTime = 1; + runtime.dataVersion = 3; + runtime.createPackage = "package"; + runtime.isPrivate = true; + + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + EXPECT_TRUE(TLVUtil::Writing(runtime, tlvObject, TAG::TAG_RUNTIME)); + + tlvObject.ResetCursor(); + Runtime runtimeResult; + EXPECT_TRUE(TLVUtil::ReadTlv(runtimeResult, tlvObject, TAG::TAG_RUNTIME)); + EXPECT_EQ(runtime.key.key, runtimeResult.key.key); + EXPECT_EQ(runtime.key.key, runtimeResult.key.key); + EXPECT_EQ(runtime.dataStatus, runtimeResult.dataStatus); + EXPECT_EQ(runtime.createTime, runtimeResult.createTime); + EXPECT_EQ(runtime.dataVersion, runtimeResult.dataVersion); + EXPECT_EQ(runtime.createPackage, runtimeResult.createPackage); + EXPECT_EQ(runtime.isPrivate, runtimeResult.isPrivate); + EXPECT_EQ(runtime.privileges[0].readPermission, runtimeResult.privileges[0].readPermission); + EXPECT_EQ(runtime.privileges[0].tokenId, runtimeResult.privileges[0].tokenId); + EXPECT_EQ(runtime.privileges[1].writePermission, runtimeResult.privileges[1].writePermission); + EXPECT_EQ(runtime.privileges[1].tokenId, runtimeResult.privileges[1].tokenId); + + LOG_INFO(UDMF_TEST, "WritingAndReading_002 end."); +} + +/* * + * @tc.name: WritingAndReading_003 + * @tc.desc: test UnifiedData for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReading_003, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReading_003 begin."); + + std::map<std::string, ValueType> value; + value["fileType"] = "File Type"; + value["fileUri"] = "File Uri"; + std::shared_ptr<Object> obj = std::make_shared<Object>(); + obj->value_ = value; + std::shared_ptr<UnifiedRecord> fileUri = std::make_shared<UnifiedRecord>(UDType::FILE_URI, obj); + + std::shared_ptr<UnifiedRecord> plainText = std::make_shared<PlainText>(UDType::PLAIN_TEXT, "this is a content"); + std::shared_ptr<UnifiedRecord> html = std::make_shared<Html>(UDType::HTML, "this is a HTML content"); + + std::vector<std::shared_ptr<UnifiedRecord>> records = { fileUri, plainText, html }; + + UnifiedData data1; + data1.SetRecords(records); + + std::shared_ptr<SystemDefinedAppItem> appItem = + std::make_shared<SystemDefinedAppItem>(UDType::SYSTEM_DEFINED_APP_ITEM, "OTHER param"); + appItem->SetAppId("com.demo"); + std::shared_ptr<ApplicationDefinedRecord> defineRecord = + std::make_shared<ApplicationDefinedRecord>(UDType::APPLICATION_DEFINED_RECORD, "OTHER param"); + std::vector<uint8_t> u8Vector = { 1, 2, 3, 4 }; + defineRecord->SetRawData(u8Vector); + std::shared_ptr<UnifiedRecord> file = std::make_shared<File>(UDType::FILE, "this is a oriUri"); + + std::vector<std::shared_ptr<UnifiedRecord>> records2 = { appItem, defineRecord, file }; + + UnifiedData data2; + data2.SetRecords(records2); + + std::vector<UnifiedData> datas = { data1, data2 }; + + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + UdmfConversion::InitValueObject(datas); + EXPECT_TRUE(TLVUtil::Writing(datas, tlvObject, TAG::TAG_UNIFIED_DATA)); + + tlvObject.ResetCursor(); + std::vector<UnifiedData> datasResult; + + EXPECT_TRUE(TLVUtil::ReadTlv(datasResult, tlvObject, TAG::TAG_UNIFIED_DATA)); + EXPECT_EQ(2, datasResult.size()); + UdmfConversion::ConvertRecordToSubclass(datasResult); + + auto recordsResult = datasResult[0].GetRecords(); + EXPECT_EQ(3, recordsResult.size()); + + auto fileUriResult = recordsResult[0]; + EXPECT_EQ(UDType::FILE_URI, fileUriResult->GetType()); + auto fileUriValue = fileUriResult->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::shared_ptr<Object>>(fileUriValue)); + auto fileUriObj = std::get<std::shared_ptr<Object>>(fileUriValue); + EXPECT_EQ("File Uri", std::get<std::string>(fileUriObj->value_["fileUri"])); + EXPECT_EQ("File Type", std::get<std::string>(fileUriObj->value_["fileType"])); + + auto plainTextResult = recordsResult[1]; + EXPECT_EQ(UDType::PLAIN_TEXT, plainTextResult->GetType()); + auto plainTextSubclass = std::static_pointer_cast<PlainText>(plainTextResult); + EXPECT_EQ("this is a content", plainTextSubclass->GetContent()); + auto plainTextValue = plainTextSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(plainTextValue)); + + auto htmlResult = recordsResult[2]; + EXPECT_EQ(UDType::HTML, htmlResult->GetType()); + auto htmlSubclass = std::static_pointer_cast<Html>(htmlResult); + EXPECT_EQ("this is a HTML content", htmlSubclass->GetHtmlContent()); + auto htmlValue = htmlSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(htmlValue)); + + auto recordsResult2 = datasResult[1].GetRecords(); + EXPECT_EQ(3, recordsResult2.size()); + auto appItemResult = recordsResult2[0]; + EXPECT_EQ(UDType::SYSTEM_DEFINED_APP_ITEM, appItemResult->GetType()); + auto appItemSubclass = std::static_pointer_cast<SystemDefinedAppItem>(appItemResult); + EXPECT_EQ("com.demo", appItemSubclass->GetAppId()); + auto appItemValue = appItemSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(appItemValue)); + + auto defineRecordResult = recordsResult2[1]; + EXPECT_EQ(UDType::APPLICATION_DEFINED_RECORD, defineRecordResult->GetType()); + auto adefineRecordSubclass = std::static_pointer_cast<ApplicationDefinedRecord>(defineRecordResult); + auto u8VectorResult = adefineRecordSubclass->GetRawData(); + EXPECT_EQ(4, u8VectorResult.size()); + auto adefineRecordValue = adefineRecordSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(adefineRecordValue)); + + auto fileResult = recordsResult2[2]; + EXPECT_EQ(UDType::FILE, fileResult->GetType()); + auto fileSubclass = std::static_pointer_cast<File>(fileResult); + EXPECT_EQ(16, fileSubclass->GetSize()); + auto fileValue = fileSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(fileValue)); + + LOG_INFO(UDMF_TEST, "WritingAndReading_003 end."); +} + +/* * + * @tc.name: WritingAndReading_004 + * @tc.desc: test UnifiedData for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReading_004, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReading_004 begin."); + + uint32_t color[100] = { 3, 7, 9, 9, 7, 6 }; + OHOS::Media::InitializationOptions opts = { { 5, 7 }, + Media::PixelFormat::ARGB_8888, + Media::PixelFormat::ARGB_8888 }; + std::unique_ptr<OHOS::Media::PixelMap> pixelMap = + OHOS::Media::PixelMap::Create(color, sizeof(color) / sizeof(color[0]), opts); + std::shared_ptr<OHOS::Media::PixelMap> pixelMapIn = move(pixelMap); + std::map<std::string, ValueType> value; + value["pixelMap"] = pixelMapIn; + std::shared_ptr<Object> obj = std::make_shared<Object>(); + obj->value_ = value; + std::shared_ptr<UnifiedRecord> pixelMapRecord = + std::make_shared<SystemDefinedPixelMap>(UDType::SYSTEM_DEFINED_PIXEL_MAP, obj); + + std::shared_ptr<SystemDefinedForm> form = + std::make_shared<SystemDefinedForm>(UDType::SYSTEM_DEFINED_FORM, "Other parm"); + form->SetFormName("HAPPY DAY"); + + UDDetails details; + details.emplace("name", "ZhangSan"); + details.emplace("age", 30); + details.emplace("isFemal", true); + std::shared_ptr<SystemDefinedRecord> definedRecord = + std::make_shared<SystemDefinedRecord>(UDType::SYSTEM_DEFINED_RECORD, "Other parm"); + definedRecord->SetDetails(details); + std::vector<std::shared_ptr<UnifiedRecord>> records = { pixelMapRecord, form, definedRecord }; + + UnifiedData data; + data.SetRecords(records); + + std::vector<UnifiedData> datas = { data }; + + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + UdmfConversion::InitValueObject(datas); + EXPECT_TRUE(TLVUtil::Writing(datas, tlvObject, TAG::TAG_UNIFIED_DATA)); + + tlvObject.ResetCursor(); + std::vector<UnifiedData> datasResult; + + EXPECT_TRUE(TLVUtil::ReadTlv(datasResult, tlvObject, TAG::TAG_UNIFIED_DATA)); + EXPECT_EQ(1, datasResult.size()); + UdmfConversion::ConvertRecordToSubclass(datasResult); + + auto recordsResult = datasResult[0].GetRecords(); + EXPECT_EQ(3, recordsResult.size()); + + auto pixelMapRecordResult = recordsResult[0]; + EXPECT_EQ(UDType::SYSTEM_DEFINED_PIXEL_MAP, pixelMapRecordResult->GetType()); + auto pixelMapValue = pixelMapRecordResult->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::shared_ptr<Object>>(pixelMapValue)); + auto pixelMapObj = std::get<std::shared_ptr<Object>>(pixelMapValue); + EXPECT_TRUE(std::holds_alternative<std::shared_ptr<OHOS::Media::PixelMap>>(pixelMapObj->value_["pixelMap"])); + auto piexelMapResult = std::get<std::shared_ptr<OHOS::Media::PixelMap>>(pixelMapObj->value_["pixelMap"]); + EXPECT_EQ(7, piexelMapResult->GetHeight()); + + auto formResult = recordsResult[1]; + EXPECT_EQ(UDType::SYSTEM_DEFINED_FORM, formResult->GetType()); + auto formSubclass = std::static_pointer_cast<SystemDefinedForm>(formResult); + EXPECT_EQ("HAPPY DAY", formSubclass->GetFormName()); + auto formValue = formSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(formValue)); + + auto definedRecordResult = recordsResult[2]; + EXPECT_EQ(UDType::SYSTEM_DEFINED_RECORD, definedRecordResult->GetType()); + auto definedRecordSubclass = std::static_pointer_cast<SystemDefinedRecord>(definedRecordResult); + auto detailsRecord = definedRecordSubclass->GetDetails(); + EXPECT_EQ("ZhangSan", std::get<std::string>(detailsRecord["name"])); + EXPECT_EQ(30, std::get<int32_t>(detailsRecord["age"])); + EXPECT_TRUE(std::get<bool>(detailsRecord["isFemal"])); + auto definedRecordValue = definedRecordSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(definedRecordValue)); + + LOG_INFO(UDMF_TEST, "WritingAndReading_004 end."); +} + +/* * + * @tc.name: WritingAndReading_005 + * @tc.desc: test Want for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReading_005, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReading_005 begin."); + std::shared_ptr<OHOS::AAFwk::Want> want = std::make_shared<OHOS::AAFwk::Want>(); + std::string idKey = "id"; + int32_t idValue = 123; + want->SetParam(idKey, idValue); + std::map<std::string, ValueType> value; + value["want"] = want; + std::shared_ptr<Object> obj = std::make_shared<Object>(); + obj->value_ = value; + + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + EXPECT_TRUE(TLVUtil::Writing(obj, tlvObject, TAG::TAG_OBJECT_VALUE)); + tlvObject.ResetCursor(); + std::shared_ptr<Object> objResult = std::make_shared<Object>(); + EXPECT_TRUE(TLVUtil::ReadTlv(objResult, tlvObject, TAG::TAG_OBJECT_VALUE)); + auto valueResult = objResult->value_; + EXPECT_TRUE(std::holds_alternative<std::shared_ptr<OHOS::AAFwk::Want>>(valueResult["want"])); + auto wantResult = std::get<std::shared_ptr<OHOS::AAFwk::Want>>(valueResult["want"]); + EXPECT_EQ(idValue, wantResult->GetIntParam(idKey, 0)); + LOG_INFO(UDMF_TEST, "WritingAndReading_005 end."); +} + +/* * + * @tc.name: WritingAndReadingFile_001 + * @tc.desc: test Unified Data for Writing And Reading + * @tc.type: FUNC + */ +HWTEST_F(TlvUtilTest, WritingAndReadingFile_001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "WritingAndReadingFile_001 begin."); + std::map<std::string, ValueType> value; + value["fileType"] = "File Type"; + value["fileUri"] = "File Uri"; + std::shared_ptr<Object> obj = std::make_shared<Object>(); + obj->value_ = value; + std::shared_ptr<UnifiedRecord> fileUri = std::make_shared<UnifiedRecord>(UDType::FILE_URI, obj); + + std::shared_ptr<UnifiedRecord> plainText = std::make_shared<PlainText>(UDType::PLAIN_TEXT, "this is a content"); + std::shared_ptr<UnifiedRecord> html = std::make_shared<Html>(UDType::HTML, "this is a HTML content"); + + std::vector<std::shared_ptr<UnifiedRecord>> records = { fileUri, plainText, html }; + + UnifiedData data1; + data1.SetRecords(records); + + std::shared_ptr<SystemDefinedAppItem> appItem = + std::make_shared<SystemDefinedAppItem>(UDType::SYSTEM_DEFINED_APP_ITEM, "OTHER param"); + appItem->SetAppId("com.demo"); + std::shared_ptr<ApplicationDefinedRecord> defineRecord = + std::make_shared<ApplicationDefinedRecord>(UDType::APPLICATION_DEFINED_RECORD, "OTHER param"); + std::vector<uint8_t> u8Vector = { 1, 2, 3, 4 }; + defineRecord->SetRawData(u8Vector); + std::shared_ptr<UnifiedRecord> fileRecord = std::make_shared<File>(UDType::FILE, "this is a oriUri"); + + std::vector<std::shared_ptr<UnifiedRecord>> records2 = { appItem, defineRecord, fileRecord }; + + UnifiedData data2; + data2.SetRecords(records2); + + std::vector<UnifiedData> datas = { data1, data2 }; + + std::string dataFile = "demo1"; + std::vector<uint8_t> dataBytes; + auto tlvObject = TLVObject(dataBytes); + + std::FILE *file = fopen(dataFile.c_str(), "w+"); + tlvObject.SetFile(file); + UdmfConversion::InitValueObject(datas); + EXPECT_TRUE(TLVUtil::Writing(datas, tlvObject, TAG::TAG_UNIFIED_DATA)); + + tlvObject.ResetCursor(); + std::vector<UnifiedData> datasResult; + + EXPECT_TRUE(TLVUtil::ReadTlv(datasResult, tlvObject, TAG::TAG_UNIFIED_DATA)); + EXPECT_EQ(2, datasResult.size()); + UdmfConversion::ConvertRecordToSubclass(datasResult); + + auto recordsResult = datasResult[0].GetRecords(); + EXPECT_EQ(3, recordsResult.size()); + + auto fileUriResult = recordsResult[0]; + EXPECT_EQ(UDType::FILE_URI, fileUriResult->GetType()); + auto fileUriValue = fileUriResult->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::shared_ptr<Object>>(fileUriValue)); + auto fileUriObj = std::get<std::shared_ptr<Object>>(fileUriValue); + EXPECT_EQ("File Uri", std::get<std::string>(fileUriObj->value_["fileUri"])); + EXPECT_EQ("File Type", std::get<std::string>(fileUriObj->value_["fileType"])); + + auto plainTextResult = recordsResult[1]; + EXPECT_EQ(UDType::PLAIN_TEXT, plainTextResult->GetType()); + auto plainTextSubclass = std::static_pointer_cast<PlainText>(plainTextResult); + EXPECT_EQ("this is a content", plainTextSubclass->GetContent()); + auto plainTextValue = plainTextSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(plainTextValue)); + + auto htmlResult = recordsResult[2]; + EXPECT_EQ(UDType::HTML, htmlResult->GetType()); + auto htmlSubclass = std::static_pointer_cast<Html>(htmlResult); + EXPECT_EQ("this is a HTML content", htmlSubclass->GetHtmlContent()); + auto htmlValue = htmlSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(htmlValue)); + + auto recordsResult2 = datasResult[1].GetRecords(); + EXPECT_EQ(3, recordsResult2.size()); + auto appItemResult = recordsResult2[0]; + EXPECT_EQ(UDType::SYSTEM_DEFINED_APP_ITEM, appItemResult->GetType()); + auto appItemSubclass = std::static_pointer_cast<SystemDefinedAppItem>(appItemResult); + EXPECT_EQ("com.demo", appItemSubclass->GetAppId()); + auto appItemValue = appItemSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(appItemValue)); + + auto defineRecordResult = recordsResult2[1]; + EXPECT_EQ(UDType::APPLICATION_DEFINED_RECORD, defineRecordResult->GetType()); + auto adefineRecordSubclass = std::static_pointer_cast<ApplicationDefinedRecord>(defineRecordResult); + auto u8VectorResult = adefineRecordSubclass->GetRawData(); + EXPECT_EQ(4, u8VectorResult.size()); + auto adefineRecordValue = adefineRecordSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(adefineRecordValue)); + + auto fileResult = recordsResult2[2]; + EXPECT_EQ(UDType::FILE, fileResult->GetType()); + auto fileSubclass = std::static_pointer_cast<File>(fileResult); + EXPECT_EQ(16, fileSubclass->GetSize()); + auto fileValue = fileSubclass->GetValue(); + EXPECT_TRUE(std::holds_alternative<std::string>(fileValue)); + + fclose(file); + LOG_INFO(UDMF_TEST, "WritingAndReadingFile_001 end."); +} +} diff --git a/udmf/framework/common/unittest/udmf_types_util_abnormal_test.cpp b/udmf/framework/common/unittest/udmf_types_util_abnormal_test.cpp new file mode 100644 index 00000000..f0082134 --- /dev/null +++ b/udmf/framework/common/unittest/udmf_types_util_abnormal_test.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "UdmfTypesUtilAbnormalTest" + +#include <unistd.h> +#include <string> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "logger.h" +#include "udmf_types_util.h" +#include "unified_meta.h" +#include "text.h" +#include "plain_text.h" +#include "file.h" +#include "image.h" +#include "system_defined_record.h" +#include "system_defined_form.h" +#include "application_defined_record.h" +#include "unified_types.h" +#include "udmf_client.h" + +using namespace testing::ext; +using namespace OHOS::UDMF; +using namespace OHOS; +namespace OHOS::Test { +using namespace std; +using namespace testing; + +class UdmfTypesUtilAbnormalTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +void UdmfTypesUtilAbnormalTest::SetUpTestCase() +{ +} + +void UdmfTypesUtilAbnormalTest::TearDownTestCase() +{ +} + +void UdmfTypesUtilAbnormalTest::SetUp() +{ +} + +void UdmfTypesUtilAbnormalTest::TearDown() +{ +} + +/** +* @tc.name: Marshalling001 +* @tc.desc: Abnrmal testcase of Marshalling, the return value of Writing() is nullptr +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilAbnormalTest, Marshalling001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Marshalling001 begin."); + UnifiedData input; + std::vector<std::shared_ptr<UnifiedRecord>> inputRecords = { + std::make_shared<Text>(), + std::make_shared<PlainText>(), + std::make_shared<File>(), + std::make_shared<Image>(), + std::make_shared<SystemDefinedRecord>(), + std::make_shared<SystemDefinedForm>(), + std::make_shared<ApplicationDefinedRecord>() + }; + input.SetRecords(inputRecords); + MessageParcel parcel; + bool ret = ITypesUtil::Marshalling(input, parcel); + EXPECT_FALSE(ret); + LOG_INFO(UDMF_TEST, "Marshalling001 end."); +} + +/** +* @tc.name: Marshalling002 +* @tc.desc: Abnrmal testcase of Marshalling, the return value of Writing() is nullptr +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilAbnormalTest, Marshalling002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Marshalling002 begin."); + UnifiedData unifiedData; + std::vector<UnifiedData> input = {unifiedData}; + MessageParcel parcel; + bool ret = ITypesUtil::Marshalling(input, parcel); + EXPECT_FALSE(ret); + LOG_INFO(UDMF_TEST, "Marshalling002 end."); +} + +/** +* @tc.name: Marshalling003 +* @tc.desc: Abnrmal testcase of Marshalling, the return value of Reading() is nullptr +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilAbnormalTest, Marshalling003, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Marshalling003 begin."); + UnifiedData unifiedData; + std::vector<UnifiedData> input = {unifiedData}; + MessageParcel parcel; + bool ret = ITypesUtil::Marshalling(input, parcel); + EXPECT_FALSE(ret); + LOG_INFO(UDMF_TEST, "Marshalling003 end."); +} + +/** +* @tc.name: Unmarshalling001 +* @tc.desc: Abnrmal testcase of Unmarshalling, the return value of Reading() is nullptr +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilAbnormalTest, Unmarshalling001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Unmarshalling001 begin."); + UnifiedData unifiedData; + std::vector<UnifiedData> output = {unifiedData}; + MessageParcel parcel; + bool ret = ITypesUtil::Unmarshalling(output, parcel); + EXPECT_FALSE(ret); + LOG_INFO(UDMF_TEST, "Unmarshalling001 end."); +} +} // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/common/unittest/udmf_types_util_test.cpp b/udmf/framework/common/unittest/udmf_types_util_test.cpp index e7db0b1a..c59c22ec 100644 --- a/udmf/framework/common/unittest/udmf_types_util_test.cpp +++ b/udmf/framework/common/unittest/udmf_types_util_test.cpp @@ -21,6 +21,15 @@ #include "logger.h" #include "udmf_types_util.h" #include "unified_meta.h" +#include "text.h" +#include "plain_text.h" +#include "file.h" +#include "image.h" +#include "system_defined_record.h" +#include "system_defined_form.h" +#include "application_defined_record.h" +#include "unified_types.h" +#include "udmf_client.h" using namespace testing::ext; using namespace OHOS::UDMF; @@ -60,7 +69,18 @@ void UdmfTypesUtilTest::TearDown() HWTEST_F(UdmfTypesUtilTest, Unmarshalling001, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Unmarshalling001 begin."); + UnifiedData input; + std::vector<std::shared_ptr<UnifiedRecord>> inputRecords = { + std::make_shared<Text>(), + std::make_shared<PlainText>(), + std::make_shared<File>(), + std::make_shared<Image>(), + std::make_shared<SystemDefinedRecord>(), + std::make_shared<SystemDefinedForm>(), + std::make_shared<ApplicationDefinedRecord>() + }; + input.SetRecords(inputRecords); MessageParcel parcel; bool ret = ITypesUtil::Unmarshalling(input, parcel); EXPECT_FALSE(ret); @@ -75,7 +95,8 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling001, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Unmarshalling002, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Unmarshalling002 begin."); - std::vector<UnifiedData> output = std::vector<UnifiedData>(); + UnifiedData unifiedData; + std::vector<UnifiedData> output = {unifiedData}; MessageParcel parcel; bool ret = ITypesUtil::Unmarshalling(output, parcel); EXPECT_FALSE(ret); @@ -90,7 +111,9 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling002, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Marshalling001, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Marshalling001 begin."); - const Summary input{}; + Summary input; + input.summary.insert({"summary", 10}); + input.totalSize = 20; MessageParcel parcel; bool ret = ITypesUtil::Marshalling(input, parcel); EXPECT_EQ(ret, ITypesUtil::Marshal(parcel, input.summary, input.totalSize)); @@ -105,10 +128,13 @@ HWTEST_F(UdmfTypesUtilTest, Marshalling001, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Unmarshalling003, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Unmarshalling003 begin."); - const Privilege input{}; + Privilege output; + output.tokenId = 5; + output.readPermission = "readPermission"; + output.writePermission = "writePermission"; MessageParcel parcel; - bool ret = ITypesUtil::Marshalling(input, parcel); - EXPECT_EQ(ret, ITypesUtil::Marshal(parcel, input.tokenId, input.readPermission, input.writePermission)); + bool ret = ITypesUtil::Unmarshalling(output, parcel); + EXPECT_EQ(ret, ITypesUtil::Unmarshal(parcel, output.tokenId, output.readPermission, output.writePermission)); LOG_INFO(UDMF_TEST, "Unmarshalling003 end."); } @@ -122,7 +148,7 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling004, TestSize.Level1) LOG_INFO(UDMF_TEST, "Unmarshalling004 begin."); CustomOption output; MessageParcel parcel; - bool ret = ITypesUtil::Marshalling(output, parcel); + bool ret = ITypesUtil::Unmarshalling(output, parcel); EXPECT_EQ(ret, ITypesUtil::Unmarshal(parcel, output.intention)); LOG_INFO(UDMF_TEST, "Unmarshalling004 end."); } @@ -137,7 +163,7 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling005, TestSize.Level1) LOG_INFO(UDMF_TEST, "Unmarshalling005 begin."); QueryOption output; MessageParcel parcel; - bool ret = ITypesUtil::Marshalling(output, parcel); + bool ret = ITypesUtil::Unmarshalling(output, parcel); EXPECT_EQ(ret, ITypesUtil::Unmarshal(parcel, output.key, output.intention)); LOG_INFO(UDMF_TEST, "Unmarshalling005 end."); } @@ -150,7 +176,7 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling005, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Marshalling002, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Marshalling002 begin."); - const UDType input{}; + const UDType input = UDType::ENTITY; MessageParcel parcel; bool ret = ITypesUtil::Marshalling(input, parcel); EXPECT_EQ(ret, ITypesUtil::Marshal(parcel, input)); @@ -165,7 +191,7 @@ HWTEST_F(UdmfTypesUtilTest, Marshalling002, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Unmarshalling006, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Unmarshalling006 begin."); - UDType output{}; + UDType output = UDType::ENTITY; MessageParcel parcel; bool ret = ITypesUtil::Unmarshalling(output, parcel); EXPECT_FALSE(ret); @@ -180,7 +206,7 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling006, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Unmarshalling007, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Unmarshalling007 begin."); - Intention output; + Intention output = Intention::UD_INTENTION_DRAG; MessageParcel parcel; bool ret = ITypesUtil::Unmarshalling(output, parcel); EXPECT_FALSE(ret); @@ -195,10 +221,79 @@ HWTEST_F(UdmfTypesUtilTest, Unmarshalling007, TestSize.Level1) HWTEST_F(UdmfTypesUtilTest, Marshalling003, TestSize.Level1) { LOG_INFO(UDMF_TEST, "Marshalling003 begin."); - const AsyncProcessInfo input{}; + AsyncProcessInfo input; + input.srcDevName = "srcDevName"; + input.syncFinished = 0; + input.syncTotal = 1; + input.syncId = 2; + input.permFnished = 3; + input.permTotal = 4; MessageParcel parcel; bool ret = ITypesUtil::Marshalling(input, parcel); - EXPECT_NE(ret, false); + EXPECT_TRUE(ret); LOG_INFO(UDMF_TEST, "Marshalling003 end."); } + +/** +* @tc.name: Marshalling004 +* @tc.desc: Normal testcase of Marshalling +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilTest, Marshalling004, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Marshalling004 begin."); + UnifiedData unifiedData; + std::vector<UnifiedData> input = {unifiedData}; + MessageParcel parcel; + bool ret = ITypesUtil::Marshalling(input, parcel); + EXPECT_TRUE(ret); + LOG_INFO(UDMF_TEST, "Marshalling004 end."); +} + +/** +* @tc.name: Marshalling005 +* @tc.desc: Normal testcase of Marshalling +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilTest, Marshalling005, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Marshalling005 begin."); + UDType input = UDType::ENTITY; + MessageParcel parcel; + bool ret = ITypesUtil::Marshalling(input, parcel); + EXPECT_TRUE(ret); + LOG_INFO(UDMF_TEST, "Marshalling005 end."); +} + +/** +* @tc.name: Unmarshalling008 +* @tc.desc: Normal testcase of Unmarshalling +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilTest, Unmarshalling008, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Unmarshalling008 begin."); + UDType output = UDType::ENTITY; + MessageParcel parcel; + ITypesUtil::Marshalling(output, parcel); + bool ret = ITypesUtil::Unmarshalling(output, parcel); + EXPECT_TRUE(ret); + LOG_INFO(UDMF_TEST, "Unmarshalling008 end."); +} + +/** +* @tc.name: Unmarshalling009 +* @tc.desc: Normal testcase of Unmarshalling +* @tc.type: FUNC +*/ +HWTEST_F(UdmfTypesUtilTest, Unmarshalling009, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "Unmarshalling009 begin."); + Intention output = Intention::UD_INTENTION_DRAG; + MessageParcel parcel; + ITypesUtil::Marshalling(output, parcel); + bool ret = ITypesUtil::Unmarshalling(output, parcel); + EXPECT_TRUE(ret); + LOG_INFO(UDMF_TEST, "Unmarshalling009 end."); +} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/client/utd_client.cpp b/udmf/framework/innerkitsimpl/client/utd_client.cpp index f4fa0dcc..51926b9f 100644 --- a/udmf/framework/innerkitsimpl/client/utd_client.cpp +++ b/udmf/framework/innerkitsimpl/client/utd_client.cpp @@ -18,29 +18,28 @@ #include <mutex> #include <regex> #include <thread> - -#include "accesstoken_kit.h" #include "common_event_manager.h" #include "common_event_subscriber.h" #include "common_event_support.h" +#include "utd_client.h" +#include "logger.h" +#include "utd_graph.h" #include "custom_utd_store.h" +#include "accesstoken_kit.h" #include "ipc_skeleton.h" -#include "logger.h" #include "os_account_manager.h" -#include "utd_graph.h" namespace OHOS { namespace UDMF { -constexpr const char *CUSTOM_UTD_HAP_DIR = "/data/utd/utd-adt.json"; -constexpr const char *CUSTOM_UTD_SA_DIR = "/data/service/el1/"; -constexpr const char *CUSTOM_UTD_SA_SUB_DIR = "/distributeddata/utd/utd-adt.json"; +constexpr const char* CUSTOM_UTD_HAP_DIR = "/data/utd/utd-adt.json"; +constexpr const char* CUSTOM_UTD_SA_DIR = "/data/service/el1/"; +constexpr const char* CUSTOM_UTD_SA_SUB_DIR = "/distributeddata/utd/utd-adt.json"; class UtdChangeSubscriber final : public EventFwk::CommonEventSubscriber { public: explicit UtdChangeSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo, - const std::function<void()> &callback); + const std::function<void()> &callback); virtual ~UtdChangeSubscriber() = default; void OnReceiveEvent(const EventFwk::CommonEventData &data) override; - private: std::function<void()> callback_; }; @@ -52,7 +51,9 @@ UtdClient::UtdClient() LOG_INFO(UDMF_CLIENT, "construct UtdClient sucess."); } -UtdClient::~UtdClient() {} +UtdClient::~UtdClient() +{ +} UtdClient &UtdClient::GetInstance() { @@ -66,9 +67,10 @@ void UtdClient::Init() descriptorCfgs_ = PresetTypeDescriptors::GetInstance().GetPresetTypes(); std::string customUtdPath = GetCustomUtdPath(); if (!customUtdPath.empty()) { - std::vector<TypeDescriptorCfg> customTypes = CustomUtdStore::GetInstance().GetTypeCfgs(customUtdPath); - LOG_INFO(UDMF_CLIENT, "get customUtd. path:%{public}s, size:%{public}zu", customUtdPath.c_str(), - customTypes.size()); + std::vector<TypeDescriptorCfg> customTypes = + CustomUtdStore::GetInstance().GetTypeCfgs(customUtdPath); + LOG_INFO(UDMF_CLIENT, "get customUtd. path:%{public}s, size:%{public}zu", + customUtdPath.c_str(), customTypes.size()); if (!customTypes.empty()) { descriptorCfgs_.insert(descriptorCfgs_.end(), customTypes.begin(), customTypes.end()); } @@ -103,7 +105,7 @@ bool UtdClient::IsValidFileExtension(const std::string &fileExtension) if (fileExtension[0] != '.' || fileExtension.find("?") != fileExtension.npos || fileExtension.find(":") != fileExtension.npos || fileExtension.find("=") != fileExtension.npos || fileExtension.find("\\") != fileExtension.npos) { - return false; + return false; } return true; @@ -115,8 +117,8 @@ bool UtdClient::IsValidMimeType(const std::string &mimeType) return false; } if (mimeType.find("?") != mimeType.npos || mimeType.find(":") != mimeType.npos || - mimeType.find("=") != mimeType.npos || mimeType.find("\\") != mimeType.npos) { - return false; + mimeType.find("=") != mimeType.npos ||mimeType.find("\\") != mimeType.npos) { + return false; } return true; } @@ -133,13 +135,13 @@ Status UtdClient::GetFlexibleTypeDescriptor(const std::string &typeId, std::shar } Status UtdClient::GetUniformDataTypeByFilenameExtension(const std::string &fileExtension, std::string &typeId, - std::string belongsTo) + std::string belongsTo) { std::string lowerFileExtension = fileExtension; std::transform(lowerFileExtension.begin(), lowerFileExtension.end(), lowerFileExtension.begin(), ::tolower); if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) { LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. fileExtension:%{public}s, belongsTo:%{public}s ", - fileExtension.c_str(), belongsTo.c_str()); + fileExtension.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } { @@ -162,7 +164,7 @@ Status UtdClient::GetUniformDataTypeByFilenameExtension(const std::string &fileE if (typeId.empty()) { if (!IsValidFileExtension(lowerFileExtension)) { LOG_ERROR(UDMF_CLIENT, "invalid fileExtension. fileExtension:%{public}s, belongsTo:%{public}s ", - fileExtension.c_str(), belongsTo.c_str()); + fileExtension.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } typeId = FlexibleType::GenFlexibleUtd("", lowerFileExtension, belongsTo); @@ -211,13 +213,14 @@ Status UtdClient::GetUniformDataTypesByFilenameExtension(const std::string &file return Status::E_OK; } -Status UtdClient::GetUniformDataTypeByMIMEType(const std::string &mimeType, std::string &typeId, std::string belongsTo) +Status UtdClient::GetUniformDataTypeByMIMEType(const std::string &mimeType, std::string &typeId, + std::string belongsTo) { std::string lowerMimeType = mimeType; std::transform(lowerMimeType.begin(), lowerMimeType.end(), lowerMimeType.begin(), ::tolower); if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) { - LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ", mimeType.c_str(), - belongsTo.c_str()); + LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ", + mimeType.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } typeId = GetTypeIdFromCfg(lowerMimeType); @@ -228,8 +231,8 @@ Status UtdClient::GetUniformDataTypeByMIMEType(const std::string &mimeType, std: } if (typeId.empty()) { if (!IsValidMimeType(mimeType)) { - LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ", mimeType.c_str(), - belongsTo.c_str()); + LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ", + mimeType.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } typeId = FlexibleType::GenFlexibleUtd(lowerMimeType, "", belongsTo); @@ -267,13 +270,13 @@ Status UtdClient::GetUniformDataTypesByMIMEType(const std::string &mimeType, std const std::string &belongsTo) { if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) { - LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ", mimeType.c_str(), - belongsTo.c_str()); + LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ", + mimeType.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } if (!IsValidMimeType(mimeType)) { - LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ", mimeType.c_str(), - belongsTo.c_str()); + LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ", + mimeType.c_str(), belongsTo.c_str()); return Status::E_INVALID_PARAMETERS; } @@ -371,12 +374,12 @@ std::string UtdClient::GetCustomUtdPath() if (GetCurrentActiveUserId(userId) != Status::E_OK) { return ""; } - std::string customUtdSaPath = - std::string(CUSTOM_UTD_SA_DIR) + std::to_string(userId) + std::string(CUSTOM_UTD_SA_SUB_DIR); + std::string customUtdSaPath = std::string(CUSTOM_UTD_SA_DIR) + + std::to_string(userId) + std::string(CUSTOM_UTD_SA_SUB_DIR); return customUtdSaPath; } -Status UtdClient::GetCurrentActiveUserId(int32_t &userId) +Status UtdClient::GetCurrentActiveUserId(int32_t& userId) { std::vector<int32_t> localIds; int32_t status = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(localIds); diff --git a/udmf/framework/innerkitsimpl/common/unified_meta.cpp b/udmf/framework/innerkitsimpl/common/unified_meta.cpp index d02a1ad0..5df2fd9c 100644 --- a/udmf/framework/innerkitsimpl/common/unified_meta.cpp +++ b/udmf/framework/innerkitsimpl/common/unified_meta.cpp @@ -456,7 +456,9 @@ static constexpr UtdType UTD_TYPES[] = { { EXCEL_DIF, "EXCEL_DIF", "com.microsoft.excel.dif" }, { OPENHARMONY_APP, "OPENHARMONY_APP", "openharmony.app" }, { HMOS_WIFI, "HMOS_WIFI", "com.huawei.hmos.settings.wifi" }, - { TEL, "TEL", "general.tel" } + { TEL, "TEL", "general.tel" }, + { ETS, "ETS", "general.ets" }, + { JSON5, "JSON5", "general.json5" } }; namespace UtdUtils { @@ -616,26 +618,6 @@ bool UnifiedDataUtils::IsValidOptions(const std::string &key, std::string &inten return false; } -bool Object::GetValue(const std::string &key, std::string &value) -{ - auto it = value_.find(key); - if (it != value_.end() && std::holds_alternative<std::string>(it->second)) { - value = std::get<std::string>(it->second); - return true; - } - return false; -} - -bool Object::GetValue(const std::string &key, std::shared_ptr<Object> &value) -{ - auto it = value_.find(key); - if (it != value_.end() && std::holds_alternative<std::shared_ptr<Object>>(it->second)) { - value = std::get<std::shared_ptr<Object>>(it->second); - return true; - } - return false; -} - std::shared_ptr<Object> ObjectUtils::ConvertToObject(UDDetails &details) { Object object; diff --git a/udmf/framework/innerkitsimpl/convert/udmf_conversion.cpp b/udmf/framework/innerkitsimpl/convert/udmf_conversion.cpp new file mode 100644 index 00000000..ad831f34 --- /dev/null +++ b/udmf/framework/innerkitsimpl/convert/udmf_conversion.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "udmf_conversion.h" +#include "unified_data.h" +#include "application_defined_record.h" +#include "audio.h" +#include "file.h" +#include "folder.h" +#include "html.h" +#include "image.h" +#include "link.h" +#include "plain_text.h" +#include "system_defined_appitem.h" +#include "system_defined_form.h" +#include "system_defined_pixelmap.h" +#include "system_defined_record.h" +#include "text.h" +#include "unified_record.h" +#include "video.h" +#include <memory> +#include <utility> + +namespace OHOS::UDMF { + +void UdmfConversion::SetValueWhenNotUds(std::shared_ptr<UnifiedRecord> record) +{ + if (!std::holds_alternative<std::shared_ptr<Object>>(record->GetValue())) { + return; + } + auto object = std::get<std::shared_ptr<Object>>(record->GetValue()); + auto it = object->value_.find("VALUE_TYPE"); + if (it == object->value_.end()) { + return; + } + if (std::holds_alternative<std::shared_ptr<Object>>(it->second)) { + return; + } + record->SetValue(it->second); +} + +void UdmfConversion::ConvertRecordToSubclass(std::shared_ptr<UnifiedRecord> &record) +{ + auto type = record->GetType(); + auto value = record->GetOriginValue(); + auto uid = record->GetUid(); + switch (type) { + case UDType::TEXT: { + record = std::make_shared<Text>(type, value); + break; + } + case UDType::PLAIN_TEXT: { + record = std::make_shared<PlainText>(type, value); + break; + } + case UDType::HTML: { + record = std::make_shared<Html>(type, value); + break; + } + case UDType::HYPERLINK: { + record = std::make_shared<Link>(type, value); + break; + } + case UDType::FILE: { + record = std::make_shared<File>(type, value); + break; + } + case UDType::IMAGE: { + record = std::make_shared<Image>(type, value); + break; + } + case UDType::VIDEO: { + record = std::make_shared<Video>(type, value); + break; + } + case UDType::AUDIO: { + record = std::make_shared<Audio>(type, value); + break; + } + case UDType::FOLDER: { + record = std::make_shared<Folder>(type, value); + break; + } + case UDType::SYSTEM_DEFINED_RECORD: { + record = std::make_shared<SystemDefinedRecord>(type, value); + break; + } + case UDType::SYSTEM_DEFINED_FORM: { + record = std::make_shared<SystemDefinedForm>(type, value); + break; + } + case UDType::SYSTEM_DEFINED_APP_ITEM: { + record = std::make_shared<SystemDefinedAppItem>(type, value); + break; + } + case UDType::SYSTEM_DEFINED_PIXEL_MAP: { + record = std::make_shared<SystemDefinedPixelMap>(type, value); + break; + } + case UDType::APPLICATION_DEFINED_RECORD: { + record = std::make_shared<ApplicationDefinedRecord>(type, value); + break; + } + default: { + record = std::make_shared<UnifiedRecord>(type, value); + } + } + record->SetUid(uid); + SetValueWhenNotUds(record); +} + +void UdmfConversion::ConvertRecordToSubclass(UnifiedData &data) +{ + std::vector<std::shared_ptr<UnifiedRecord>> records; + for (auto &record : data.GetRecords()) { + ConvertRecordToSubclass(record); + records.push_back(std::move(record)); + } + data.SetRecords(records); +} + +void UdmfConversion::ConvertRecordToSubclass(std::vector<UnifiedData> &datas) +{ + for (auto &data : datas) { + ConvertRecordToSubclass(data); + } +} + +void UdmfConversion::InitValueObject(UnifiedData &data) +{ + for (auto &record : data.GetRecords()) { + record->InitObject(); + } +} + +void UdmfConversion::InitValueObject(std::vector<UnifiedData> &datas) +{ + for (auto &data : datas) { + InitValueObject(data); + } +} +} diff --git a/udmf/framework/innerkitsimpl/data/application_defined_record.cpp b/udmf/framework/innerkitsimpl/data/application_defined_record.cpp index 121e9520..7336e901 100644 --- a/udmf/framework/innerkitsimpl/data/application_defined_record.cpp +++ b/udmf/framework/innerkitsimpl/data/application_defined_record.cpp @@ -39,6 +39,11 @@ ApplicationDefinedRecord::ApplicationDefinedRecord(UDType type, ValueType value) this->dataType_ = APPLICATION_DEFINED_RECORD; if (std::holds_alternative<std::vector<uint8_t>>(value)) { rawData_ = std::get<std::vector<uint8_t>>(value); + } else if (std::holds_alternative<std::shared_ptr<Object>>(value)) { + auto object = std::get<std::shared_ptr<Object>>(value); + object->GetValue(APPLICATION_DEFINED_TYPE, applicationDefinedType); + object->GetValue(RAW_DATA, rawData_); + hasObject_ = true; } } @@ -55,6 +60,10 @@ std::string ApplicationDefinedRecord::GetApplicationDefinedType() const void ApplicationDefinedRecord::SetApplicationDefinedType(const std::string &type) { this->applicationDefinedType = type; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[APPLICATION_DEFINED_TYPE] = applicationDefinedType; + } } std::vector<uint8_t> ApplicationDefinedRecord::GetRawData() const @@ -65,6 +74,24 @@ std::vector<uint8_t> ApplicationDefinedRecord::GetRawData() const void ApplicationDefinedRecord::SetRawData(const std::vector<uint8_t> &rawData) { this->rawData_ = rawData; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[RAW_DATA] = rawData_; + } } + +void ApplicationDefinedRecord::InitObject() +{ + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); + object->value_[APPLICATION_DEFINED_TYPE] = applicationDefinedType; + object->value_[RAW_DATA] = rawData_; + object->value_["VALUE_TYPE"] = value; + } +} + } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/data/file.cpp b/udmf/framework/innerkitsimpl/data/file.cpp index 7a713056..9ac6c1ca 100644 --- a/udmf/framework/innerkitsimpl/data/file.cpp +++ b/udmf/framework/innerkitsimpl/data/file.cpp @@ -31,6 +31,15 @@ File::File(UDType type, ValueType value) : UnifiedRecord(type, value) this->dataType_ = FILE; if (std::holds_alternative<std::string>(value)) { oriUri_ = std::get<std::string>(value); + } else if (std::holds_alternative<std::shared_ptr<Object>>(value)) { + auto object = std::get<std::shared_ptr<Object>>(value); + object->GetValue(ORI_URI, oriUri_); + object->GetValue(REMOTE_URI, remoteUri_); + std::shared_ptr<Object> detailObj = nullptr; + if (object->GetValue(DETAILS, detailObj)) { + details_ = ObjectUtils::ConvertToUDDetails(detailObj); + } + hasObject_ = true; } } @@ -47,6 +56,10 @@ std::string File::GetUri() const void File::SetUri(const std::string &uri) { this->oriUri_ = uri; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[ORI_URI] = oriUri_; + } } std::string File::GetRemoteUri() const @@ -57,16 +70,39 @@ std::string File::GetRemoteUri() const void File::SetRemoteUri(const std::string &uri) { this->remoteUri_ = uri; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[REMOTE_URI] = remoteUri_; + } } void File::SetDetails(UDDetails &variantMap) { this->details_ = variantMap; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + } } UDDetails File::GetDetails() const { return this->details_; } + +void File::InitObject() +{ + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); + object->value_[ORI_URI] = oriUri_; + object->value_[REMOTE_URI] = remoteUri_; + object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; + } +} + } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/data/html.cpp b/udmf/framework/innerkitsimpl/data/html.cpp index cc25b026..1b4fe767 100644 --- a/udmf/framework/innerkitsimpl/data/html.cpp +++ b/udmf/framework/innerkitsimpl/data/html.cpp @@ -45,6 +45,7 @@ Html::Html(UDType type, ValueType value) : Text(type, value) if (object->GetValue(DETAILS, detailObj)) { details_ = ObjectUtils::ConvertToUDDetails(detailObj); } + hasObject_ = true; } } @@ -64,7 +65,9 @@ void Html::SetHtmlContent(const std::string &htmlContent) return; } this->htmlContent_ = htmlContent; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[HTML_CONTENT] = htmlContent_; + } } std::string Html::GetPlainContent() const @@ -78,26 +81,23 @@ void Html::SetPlainContent(const std::string &plainContent) return; } this->plainContent_ = plainContent; - InitObject(); -} - -ValueType Html::GetValue() -{ - if (std::holds_alternative<std::monostate>(value_)) { - value_ = std::make_shared<Object>(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[PLAINT_CONTENT] = plainContent_; } - InitObject(); - return value_; } void Html::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); object->value_[HTML_CONTENT] = htmlContent_; object->value_[PLAINT_CONTENT] = plainContent_; object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/link.cpp b/udmf/framework/innerkitsimpl/data/link.cpp index eb41e2da..6861bf82 100644 --- a/udmf/framework/innerkitsimpl/data/link.cpp +++ b/udmf/framework/innerkitsimpl/data/link.cpp @@ -38,6 +38,7 @@ Link::Link(UDType type, ValueType value) : Text(type, value) if (object->GetValue(DETAILS, detailObj)) { details_ = ObjectUtils::ConvertToUDDetails(detailObj); } + hasObject_ = true; } } @@ -67,7 +68,9 @@ void Link::SetUrl(const std::string &url) return; } this->url_ = url; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[URL] = url_; + } } std::string Link::GetDescription() const @@ -81,26 +84,22 @@ void Link::SetDescription(const std::string &description) return; } this->description_ = description; - InitObject(); -} - -ValueType Link::GetValue() -{ - if (std::holds_alternative<std::monostate>(value_)) { - value_ = std::make_shared<Object>(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[DESCRIPTION] = description_; } - InitObject(); - return value_; } void Link::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); object->value_[URL] = url_; object->value_[DESCRIPTION] = description_; object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/plain_text.cpp b/udmf/framework/innerkitsimpl/data/plain_text.cpp index 718ccdf4..e1619189 100644 --- a/udmf/framework/innerkitsimpl/data/plain_text.cpp +++ b/udmf/framework/innerkitsimpl/data/plain_text.cpp @@ -44,6 +44,7 @@ PlainText::PlainText(UDType type, ValueType value) : Text(type, value) if (object->GetValue(DETAILS, detailObj)) { details_ = ObjectUtils::ConvertToUDDetails(detailObj); } + hasObject_ = true; } } @@ -63,7 +64,10 @@ void PlainText::SetContent(const std::string &text) return; } this->content_ = text; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[TEXT_CONTENT] = content_; + } } std::string PlainText::GetAbstract() const @@ -77,26 +81,23 @@ void PlainText::SetAbstract(const std::string &abstract) return; } this->abstract_ = abstract; - InitObject(); -} - -ValueType PlainText::GetValue() -{ - if (std::holds_alternative<std::monostate>(value_)) { - value_ = std::make_shared<Object>(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[ABSTRACT] = abstract_; } - InitObject(); - return value_; } void PlainText::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); object->value_[TEXT_CONTENT] = content_; object->value_[ABSTRACT] = abstract_; object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp index a4aaafcd..ac239d41 100644 --- a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp +++ b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp @@ -2981,6 +2981,20 @@ void PresetTypeDescriptors::InitDescriptors() "TEL schematic diagram file format", REFERENCE_URL, ""}, + {"general.ets", + {"general.script"}, + {".ets"}, + {}, + "Extended TypeScript source code", + REFERENCE_URL, + ""}, + {"general.json5", + {"general.script"}, + {".json5"}, + {}, + "JSON5 data interchange format", + REFERENCE_URL, + ""}, }; } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/system_defined_appitem.cpp b/udmf/framework/innerkitsimpl/data/system_defined_appitem.cpp index 39d67a9f..59ed1cd8 100644 --- a/udmf/framework/innerkitsimpl/data/system_defined_appitem.cpp +++ b/udmf/framework/innerkitsimpl/data/system_defined_appitem.cpp @@ -37,6 +37,7 @@ SystemDefinedAppItem::SystemDefinedAppItem(UDType type, ValueType value) : Syste if (object->GetValue(DETAILS, detailObj)) { details_ = ObjectUtils::ConvertToUDDetails(detailObj); } + hasObject_ = true; } } @@ -54,7 +55,9 @@ std::string SystemDefinedAppItem::GetAppId() const void SystemDefinedAppItem::SetAppId(const std::string &appId) { this->appId_ = appId; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[APPID] = appId_; + } } std::string SystemDefinedAppItem::GetAppName() const @@ -65,7 +68,9 @@ std::string SystemDefinedAppItem::GetAppName() const void SystemDefinedAppItem::SetAppName(const std::string &appName) { this->appName_ = appName; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[APPNAME] = appName_; + } } std::string SystemDefinedAppItem::GetAppIconId() const @@ -76,7 +81,9 @@ std::string SystemDefinedAppItem::GetAppIconId() const void SystemDefinedAppItem::SetAppIconId(const std::string &appIconId) { this->appIconId_ = appIconId; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[APPICONID] = appIconId_; + } } std::string SystemDefinedAppItem::GetAppLabelId() const @@ -87,7 +94,9 @@ std::string SystemDefinedAppItem::GetAppLabelId() const void SystemDefinedAppItem::SetAppLabelId(const std::string &appLabelId) { this->appLabelId_ = appLabelId; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[APPLABELID] = appLabelId_; + } } std::string SystemDefinedAppItem::GetBundleName() const @@ -98,7 +107,9 @@ std::string SystemDefinedAppItem::GetBundleName() const void SystemDefinedAppItem::SetBundleName(const std::string &bundleName) { this->bundleName_ = bundleName; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[BUNDLENAME] = bundleName_; + } } std::string SystemDefinedAppItem::GetAbilityName() const @@ -109,7 +120,9 @@ std::string SystemDefinedAppItem::GetAbilityName() const void SystemDefinedAppItem::SetAbilityName(const std::string &abilityName) { this->abilityName_ = abilityName; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[ABILITYNAME] = abilityName_; + } } void SystemDefinedAppItem::SetItems(UDDetails &details) @@ -138,7 +151,6 @@ void SystemDefinedAppItem::SetItems(UDDetails &details) SetAbilityName(*value); } } - InitObject(); } UDDetails SystemDefinedAppItem::GetItems() @@ -153,18 +165,11 @@ UDDetails SystemDefinedAppItem::GetItems() return items; } -ValueType SystemDefinedAppItem::GetValue() -{ - if (std::holds_alternative<std::monostate>(value_)) { - value_ = std::make_shared<Object>(); - } - InitObject(); - return value_; -} - void SystemDefinedAppItem::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); object->value_[APPID] = appId_; @@ -174,6 +179,7 @@ void SystemDefinedAppItem::InitObject() object->value_[BUNDLENAME] = bundleName_; object->value_[ABILITYNAME] = abilityName_; object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/system_defined_form.cpp b/udmf/framework/innerkitsimpl/data/system_defined_form.cpp index 64d52d0f..2d305bcb 100644 --- a/udmf/framework/innerkitsimpl/data/system_defined_form.cpp +++ b/udmf/framework/innerkitsimpl/data/system_defined_form.cpp @@ -25,6 +25,19 @@ SystemDefinedForm::SystemDefinedForm() SystemDefinedForm::SystemDefinedForm(UDType type, ValueType value) : SystemDefinedRecord(type, value) { this->dataType_ = SYSTEM_DEFINED_FORM; + if (std::holds_alternative<std::shared_ptr<Object>>(value)) { + auto object = std::get<std::shared_ptr<Object>>(value); + object->GetValue(FORMID, formId_); + object->GetValue(FORMNAME, formName_); + object->GetValue(BUNDLENAME, bundleName_); + object->GetValue(ABILITYNAME, abilityName_); + object->GetValue(MODULE, module_); + std::shared_ptr<Object> detailObj = nullptr; + if (object->GetValue(DETAILS, detailObj)) { + details_ = ObjectUtils::ConvertToUDDetails(detailObj); + } + hasObject_ = true; + } } int64_t SystemDefinedForm::GetSize() @@ -41,6 +54,9 @@ int32_t SystemDefinedForm::GetFormId() const void SystemDefinedForm::SetFormId(const int32_t &formId) { this->formId_ = formId; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[FORMID] = formId_; + } } std::string SystemDefinedForm::GetFormName() const @@ -51,6 +67,9 @@ std::string SystemDefinedForm::GetFormName() const void SystemDefinedForm::SetFormName(const std::string &formName) { this->formName_ = formName; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[FORMNAME] = formName_; + } } std::string SystemDefinedForm::GetBundleName() const @@ -61,6 +80,9 @@ std::string SystemDefinedForm::GetBundleName() const void SystemDefinedForm::SetBundleName(const std::string &bundleName) { this->bundleName_ = bundleName; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[BUNDLENAME] = bundleName_; + } } std::string SystemDefinedForm::GetAbilityName() const @@ -71,6 +93,9 @@ std::string SystemDefinedForm::GetAbilityName() const void SystemDefinedForm::SetAbilityName(const std::string &abilityName) { this->abilityName_ = abilityName; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[ABILITYNAME] = abilityName_; + } } std::string SystemDefinedForm::GetModule() const @@ -81,6 +106,9 @@ std::string SystemDefinedForm::GetModule() const void SystemDefinedForm::SetModule(const std::string &module) { this->module_ = module; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[MODULE] = module_; + } } void SystemDefinedForm::SetItems(UDDetails& details) @@ -123,5 +151,23 @@ UDDetails SystemDefinedForm::GetItems() items[ABILITYNAME] = GetAbilityName(); return items; } + +void SystemDefinedForm::InitObject() +{ + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_[UNIFORM_DATA_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(dataType_); + object->value_[FORMID] = formId_; + object->value_[FORMNAME] = formName_; + object->value_[BUNDLENAME] = bundleName_; + object->value_[ABILITYNAME] = abilityName_; + object->value_[MODULE] = module_; + object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; + } +} + } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/data/system_defined_pixelmap.cpp b/udmf/framework/innerkitsimpl/data/system_defined_pixelmap.cpp index f07664a4..06848ca0 100644 --- a/udmf/framework/innerkitsimpl/data/system_defined_pixelmap.cpp +++ b/udmf/framework/innerkitsimpl/data/system_defined_pixelmap.cpp @@ -41,11 +41,17 @@ SystemDefinedPixelMap::SystemDefinedPixelMap(UDType type, ValueType value) : Sys if (std::holds_alternative<std::shared_ptr<Object>>(value)) { auto object = std::get<std::shared_ptr<Object>>(value); auto it = object->value_.find(PIXEL_MAP); - if (it != object->value_.end() && std::holds_alternative<std::shared_ptr<OHOS::Media::PixelMap>>(it->second)) { + hasObject_ = true; + if (it == object->value_.end()) { + return; + } + if (std::holds_alternative<std::shared_ptr<OHOS::Media::PixelMap>>(it->second)) { auto pixelMap = std::get<std::shared_ptr<OHOS::Media::PixelMap>>(it->second); if (!pixelMap->EncodeTlv(rawData_)) { LOG_ERROR(UDMF_KITS_INNER, "pixelMap encode fail!"); } + } else if (std::holds_alternative<std::vector<uint8_t>>(it->second)) { + rawData_ = std::get<std::vector<uint8_t>>(it->second); } } } @@ -63,30 +69,33 @@ std::vector<uint8_t> SystemDefinedPixelMap::GetRawData() const void SystemDefinedPixelMap::SetRawData(const std::vector<uint8_t> &rawData) { this->rawData_ = rawData; - this->updateObjectFlag_ = true; -} - -ValueType SystemDefinedPixelMap::GetValue() -{ - if (std::holds_alternative<std::monostate>(value_)) { - value_ = std::make_shared<Object>(); - } - if (this->updateObjectFlag_) { - InitObject(); - this->updateObjectFlag_ = false; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto object = std::get<std::shared_ptr<Object>>(value_); + auto pixelMap = std::shared_ptr<OHOS::Media::PixelMap>(OHOS::Media::PixelMap::DecodeTlv(rawData_)); + if (pixelMap == nullptr) { + LOG_ERROR(UDMF_KITS_INNER, "pixelMap decode fail!"); + object->value_[PIXEL_MAP] = rawData; + return; + } + object->value_[PIXEL_MAP] = pixelMap; } - return value_; } void SystemDefinedPixelMap::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); auto pixelMap = std::shared_ptr<OHOS::Media::PixelMap>(OHOS::Media::PixelMap::DecodeTlv(rawData_)); if (pixelMap == nullptr) { - LOG_ERROR(UDMF_KITS_INNER, "pixelMap encode fail!"); + LOG_ERROR(UDMF_KITS_INNER, "pixelMap decode fail!"); + object->value_[PIXEL_MAP] = rawData_; + } else { + object->value_[PIXEL_MAP] = pixelMap; } - object->value_[PIXEL_MAP] = pixelMap; + object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } diff --git a/udmf/framework/innerkitsimpl/data/system_defined_record.cpp b/udmf/framework/innerkitsimpl/data/system_defined_record.cpp index 017a792d..e10b09d0 100644 --- a/udmf/framework/innerkitsimpl/data/system_defined_record.cpp +++ b/udmf/framework/innerkitsimpl/data/system_defined_record.cpp @@ -29,6 +29,14 @@ int64_t SystemDefinedRecord::GetSize() SystemDefinedRecord::SystemDefinedRecord(UDType type, ValueType value) : UnifiedRecord(type, value) { this->dataType_ = SYSTEM_DEFINED_RECORD; + if (std::holds_alternative<std::shared_ptr<Object>>(value)) { + auto object = std::get<std::shared_ptr<Object>>(value); + std::shared_ptr<Object> detailObj = nullptr; + if (object->GetValue(DETAILS, detailObj)) { + details_ = ObjectUtils::ConvertToUDDetails(detailObj); + } + hasObject_ = true; + } } void SystemDefinedRecord::AddProperty(const std::string &property, UDVariant &value) @@ -39,7 +47,9 @@ void SystemDefinedRecord::AddProperty(const std::string &property, UDVariant &va } else { details_[property] = value; } - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + } } UDVariant SystemDefinedRecord::GetPropertyByName(const std::string &property) const @@ -54,7 +64,9 @@ UDVariant SystemDefinedRecord::GetPropertyByName(const std::string &property) co void SystemDefinedRecord::SetDetails(UDDetails &details) { this->details_ = details; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + } } UDDetails SystemDefinedRecord::GetDetails() const @@ -64,9 +76,12 @@ UDDetails SystemDefinedRecord::GetDetails() const void SystemDefinedRecord::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/text.cpp b/udmf/framework/innerkitsimpl/data/text.cpp index aa298119..7bb42a2a 100644 --- a/udmf/framework/innerkitsimpl/data/text.cpp +++ b/udmf/framework/innerkitsimpl/data/text.cpp @@ -29,6 +29,14 @@ Text::Text(UDDetails &variantMap) : UnifiedRecord(TEXT) Text::Text(UDType type, ValueType value) : UnifiedRecord(type, value) { SetType(TEXT); + if (std::holds_alternative<std::shared_ptr<Object>>(value)) { + auto object = std::get<std::shared_ptr<Object>>(value); + std::shared_ptr<Object> detailObj = nullptr; + if (object->GetValue(DETAILS, detailObj)) { + details_ = ObjectUtils::ConvertToUDDetails(detailObj); + } + hasObject_ = true; + } } int64_t Text::GetSize() @@ -39,7 +47,9 @@ int64_t Text::GetSize() void Text::SetDetails(UDDetails &variantMap) { this->details_ = variantMap; - InitObject(); + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + std::get<std::shared_ptr<Object>>(value_)->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + } } UDDetails Text::GetDetails() const @@ -49,9 +59,12 @@ UDDetails Text::GetDetails() const void Text::InitObject() { - if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); auto object = std::get<std::shared_ptr<Object>>(value_); object->value_[DETAILS] = ObjectUtils::ConvertToObject(details_); + object->value_["VALUE_TYPE"] = value; } } } // namespace UDMF diff --git a/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp b/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp index 18b60dd1..9c415623 100644 --- a/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp @@ -19,10 +19,12 @@ #include <chrono> #include "common_func.h" #include "directory_ex.h" +#include "file.h" #include "file_ex.h" #include "file_uri.h" #include "logger.h" #include "tlv_util.h" +#include "udmf_conversion.h" namespace OHOS { namespace UDMF { @@ -171,8 +173,8 @@ bool UnifiedDataHelper::SaveUDataToFile(const std::string &dataFile, UnifiedData return false; } recordTlv.SetFile(file); - - if (!TLVUtil::Writing(data, recordTlv)) { + UdmfConversion::InitValueObject(data); + if (!TLVUtil::Writing(data, recordTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_FRAMEWORK, "TLV Writing failed!"); (void)fclose(file); return false; @@ -196,12 +198,13 @@ bool UnifiedDataHelper::LoadUDataFromFile(const std::string &dataFile, UnifiedDa return false; } recordTlv.SetFile(file); - - if (!TLVUtil::Reading(data, recordTlv)) { + + if (!TLVUtil::ReadTlv(data, recordTlv, TAG::TAG_UNIFIED_DATA)) { LOG_ERROR(UDMF_FRAMEWORK, "TLV Reading failed!"); (void)fclose(file); return false; } + UdmfConversion::ConvertRecordToSubclass(data); (void)fclose(file); return true; } diff --git a/udmf/framework/innerkitsimpl/data/unified_record.cpp b/udmf/framework/innerkitsimpl/data/unified_record.cpp index f90544f4..44408a2c 100644 --- a/udmf/framework/innerkitsimpl/data/unified_record.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_record.cpp @@ -35,6 +35,9 @@ UnifiedRecord::UnifiedRecord(UDType type, ValueType value) dataType_ = type; utdId_ = UtdUtils::GetUtdIdFromUtdEnum(type); value_ = value; + if (std::holds_alternative<std::shared_ptr<Object>>(value_)) { + hasObject_ = true; + } } UDType UnifiedRecord::GetType() const @@ -73,7 +76,7 @@ void UnifiedRecord::SetValue(const ValueType &value) value_ = value; } -ValueType UnifiedRecord::GetOriginValue() +ValueType UnifiedRecord::GetOriginValue() const { return value_; } @@ -188,5 +191,21 @@ void UnifiedRecord::SetChannelName(const std::string &channelName) { channelName_ = channelName; } + +void UnifiedRecord::InitObject() +{ + if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) { + auto value = value_; + value_ = std::make_shared<Object>(); + auto object = std::get<std::shared_ptr<Object>>(value_); + object->value_["VALUE_TYPE"] = value; + } +} + +bool UnifiedRecord::HasObject() +{ + return hasObject_; +} + } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp index e4acc7a1..f8b6c50b 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp +++ b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp @@ -17,6 +17,7 @@ #include "logger.h" #include "udmf_types_util.h" +#include "udmf_conversion.h" namespace OHOS { namespace UDMF { @@ -52,6 +53,7 @@ UdmfServiceProxy::UdmfServiceProxy(const sptr<IRemoteObject> &object) : IRemoteP int32_t UdmfServiceProxy::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { + UdmfConversion::InitValueObject(unifiedData); MessageParcel reply; int32_t status = IPC_SEND(UdmfServiceInterfaceCode::SET_DATA, reply, option, unifiedData); if (status != E_OK) { @@ -98,6 +100,7 @@ int32_t UdmfServiceProxy::GetBatchData(const QueryOption &query, std::vector<Uni int32_t UdmfServiceProxy::UpdateData(const QueryOption &query, UnifiedData &unifiedData) { + UdmfConversion::InitValueObject(unifiedData); MessageParcel reply; int32_t status = IPC_SEND(UdmfServiceInterfaceCode::UPDATE_DATA, reply, query, unifiedData); if (status != E_OK) { diff --git a/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn b/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn index 87df9da2..69b16c25 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn +++ b/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn @@ -21,10 +21,10 @@ config("module_private_config") { "${udmf_interfaces_path}/innerkits/client", "${udmf_interfaces_path}/innerkits/common", "${udmf_interfaces_path}/innerkits/data", + "${udmf_interfaces_path}/innerkits/convert", "${udmf_interfaces_path}/ndk/data", "${udmf_framework_path}/common", "${udmf_framework_path}/innerkits/service", - "${udmf_framework_path}/innerkits/convert", "${udmf_framework_path}/innerkitsimpl/client/", "${udmf_framework_path}/innerkitsimpl/test/unittest/mock/include", "${udmf_framework_path}/ndkimpl/data", @@ -50,6 +50,9 @@ common_external_deps = [ "hitrace:hitrace_meter", "hitrace:libhitracechain", "image_framework:image", + "image_framework:image", + "image_framework:image_native", + "image_framework:pixelmap", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", @@ -63,6 +66,7 @@ ohos_unittest("UdmfClientTest") { sources = [ "${udmf_framework_path}/common/graph.cpp", "${udmf_framework_path}/innerkitsimpl/client/async_obtain_data.cpp", + "${udmf_framework_path}/innerkitsimpl/convert/udmf_conversion.cpp", "${udmf_framework_path}/innerkitsimpl/service/udmf_service_proxy.cpp", "udmf_client_test.cpp", ] @@ -431,6 +435,7 @@ ohos_unittest("UdmfClientAbnormalTest") { "${udmf_framework_path}/innerkitsimpl/client/udmf_client.cpp", "${udmf_framework_path}/innerkitsimpl/common/unified_key.cpp", "${udmf_framework_path}/innerkitsimpl/common/unified_meta.cpp", + "${udmf_framework_path}/innerkitsimpl/convert/udmf_conversion.cpp", "${udmf_framework_path}/innerkitsimpl/data/application_defined_record.cpp", "${udmf_framework_path}/innerkitsimpl/data/audio.cpp", "${udmf_framework_path}/innerkitsimpl/data/file.cpp", diff --git a/udmf/framework/innerkitsimpl/test/unittest/html_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/html_test.cpp index 83e3507e..65350fb1 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/html_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/html_test.cpp @@ -164,26 +164,4 @@ HWTEST_F(HtmlTest, SetPlainContent002, TestSize.Level1) EXPECT_NE(html.plainContent_, plainContent); LOG_INFO(UDMF_TEST, "SetPlainContent002 end."); } - -/** -* @tc.name: GetValue001 -* @tc.desc: Normal testcase of GetValue -* @tc.type: FUNC -*/ -HWTEST_F(HtmlTest, GetValue001, TestSize.Level1) -{ - LOG_INFO(UDMF_TEST, "GetValue001 begin."); - Html html; - html.value_ = std::monostate{}; - html.htmlContent_ = "htmlContent"; - html.plainContent_ = "plainContent"; - html.GetValue(); - auto object = std::get<std::shared_ptr<Object>>(html.value_); - auto details_ = std::get<std::shared_ptr<Object>>(object->value_[Html::DETAILS]); - EXPECT_EQ(std::get<std::string>(object->value_[UNIFORM_DATA_TYPE]), "general.html"); - EXPECT_EQ(std::get<std::string>(object->value_[HTML_CONTENT]), html.htmlContent_); - EXPECT_EQ(std::get<std::string>(object->value_[Html::PLAINT_CONTENT]), html.plainContent_); - EXPECT_EQ(details_->value_.size(), 0); - LOG_INFO(UDMF_TEST, "GetValue001 end."); -} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/link_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/link_test.cpp index 62956c71..420152ee 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/link_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/link_test.cpp @@ -162,26 +162,4 @@ HWTEST_F(LinkTest, SetDescription002, TestSize.Level1) EXPECT_NE(link.description_, description); LOG_INFO(UDMF_TEST, "SetDescription002 end."); } - -/** -* @tc.name: GetValue001 -* @tc.desc: Abnormal testcase of GetValue,because description and MAX_TEXT_LEN are equal -* @tc.type: FUNC -*/ -HWTEST_F(LinkTest, GetValue001, TestSize.Level1) -{ - LOG_INFO(UDMF_TEST, "GetValue001 begin."); - Link link; - link.value_ = std::monostate{}; - link.url_ = "url_"; - link.description_ = "description_"; - link.GetValue(); - auto object = std::get<std::shared_ptr<Object>>(link.value_); - auto details_ = std::get<std::shared_ptr<Object>>(object->value_[Link::DETAILS]); - EXPECT_EQ(std::get<std::string>(object->value_[Link::UNIFORM_DATA_TYPE]), "general.hyperlink"); - EXPECT_EQ(std::get<std::string>(object->value_[Link::URL]), link.url_); - EXPECT_EQ(std::get<std::string>(object->value_[Link::DESCRIPTION]), link.description_); - EXPECT_EQ(details_->value_.size(), 0); - LOG_INFO(UDMF_TEST, "GetValue001 end."); -} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/mock/system_defined_pixelmap_mock.cpp b/udmf/framework/innerkitsimpl/test/unittest/mock/system_defined_pixelmap_mock.cpp index 5fe52c58..c916912c 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/mock/system_defined_pixelmap_mock.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/mock/system_defined_pixelmap_mock.cpp @@ -43,12 +43,6 @@ void SystemDefinedPixelMap::SetRawData(const std::vector<uint8_t> &rawData) { } -ValueType SystemDefinedPixelMap::GetValue() -{ - value_ = std::make_shared<Object>(); - return value_; -} - void SystemDefinedPixelMap::InitObject() { } diff --git a/udmf/framework/innerkitsimpl/test/unittest/mock/tlv_object_mock.cpp b/udmf/framework/innerkitsimpl/test/unittest/mock/tlv_object_mock.cpp index 561bbbed..2ce6fe83 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/mock/tlv_object_mock.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/mock/tlv_object_mock.cpp @@ -18,15 +18,23 @@ namespace OHOS { namespace UDMF { TLVObject::TLVObject(std::vector<std::uint8_t> &buffer) { + total_ += buffer.size(); buffer_ = &buffer; + cursor_ = 0; + file_ = nullptr; } void TLVObject::SetFile(std::FILE *file) { + file_ = file; } void TLVObject::UpdateSize() { + if (file_ != nullptr) { + return; + } + buffer_->resize(total_); } std::vector<std::uint8_t> TLVObject::GetBuffer() @@ -34,222 +42,153 @@ std::vector<std::uint8_t> TLVObject::GetBuffer() return *buffer_; } -void TLVObject::Count(const uint32_t value) +size_t TLVObject::GetTotal() { + return total_; } -void TLVObject::Count(const uint64_t value) +size_t TLVObject::GetCursor() { + return cursor_; } -void TLVObject::Count(const int32_t value) +size_t TLVObject::OffsetHead() { + if (file_ != nullptr) { + fseek(file_, sizeof(TLVHead), SEEK_CUR); + } + cursor_ += sizeof(TLVHead); + return cursor_; } -void TLVObject::Count(const int64_t value) +void TLVObject::ResetCursor() { + cursor_ = 0; + if (file_ != nullptr) { + fseek(file_, 0, SEEK_SET); + } } -void TLVObject::Count(const float value) +size_t TLVObject::Count(const std::string &value) { + return sizeof(TLVHead); } -void TLVObject::Count(const double value) +size_t TLVObject::Count(const std::vector<uint8_t> &value) { + return sizeof(TLVHead); } -void TLVObject::Count(const std::string &value) +size_t TLVObject::Count(const OHOS::AAFwk::Want &value) { + return sizeof(TLVHead); } -void TLVObject::Count(const std::vector<uint8_t> &value) +size_t TLVObject::Count(const std::monostate &value) { + return sizeof(TLVHead); } -void TLVObject::Count(const UDVariant &value) +size_t TLVObject::Count(const void *value) { + return sizeof(TLVHead); } -void TLVObject::Count(const ValueType &value) -{ -} - -void TLVObject::Count(const UDDetails &value) -{ -} - -void TLVObject::Count(const UnifiedKey &value) -{ -} - -void TLVObject::Count(const Privilege &value) -{ -} - -void TLVObject::Count(const std::shared_ptr<OHOS::AAFwk::Want> &value) -{ -} - -void TLVObject::Count(const std::shared_ptr<OHOS::Media::PixelMap> &value) -{ -} - -void TLVObject::Count(const std::shared_ptr<Object> &value) -{ -} - -void TLVObject::Count(const std::monostate &value) -{ -} - -void TLVObject::Count(const void *value) -{ -} - -bool TLVObject::WriteString(const std::string &value) -{ - return true; -} - -bool TLVObject::ReadString(std::string &value) -{ - return true; -} - -bool TLVObject::WriteVector(const std::vector<uint8_t> &value) -{ - return true; -} - -bool TLVObject::ReadVector(std::vector<uint8_t> &value) -{ - return true; -} - -bool TLVObject::WriteVariantInner(TAG &tag, const UDVariant &value) -{ - return true; -} - -bool TLVObject::WriteVariant(const UDVariant &value) +bool TLVObject::Write(TAG tag, const std::string &value) { return true; } -bool TLVObject::ReadVariantInner(uint16_t tag, UDVariant &value) +bool TLVObject::Read(std::string &value, const TLVHead &head) { return true; } -bool TLVObject::ReadVariant(UDVariant &value) +bool TLVObject::Write(TAG tag, const std::vector<uint8_t> &value) { return true; } -bool TLVObject::WriteVariantInner(TAG &tag, const ValueType &value) -{ - return true; -} - -bool TLVObject::WriteVariant(const ValueType &value) -{ - return true; -} -bool TLVObject::ReadVariantInner(uint16_t tag, ValueType &value) +bool TLVObject::Read(std::vector<uint8_t> &value, const TLVHead &head) { return true; } -bool TLVObject::ReadVariant(ValueType &value) +bool TLVObject::Write(TAG tag, const OHOS::AAFwk::Want &value) { return true; } -bool TLVObject::WriteMap(const UDDetails &value) +bool TLVObject::Read(OHOS::AAFwk::Want &value, const TLVHead &head) { return true; } -bool TLVObject::ReadMap(UDDetails &value) +bool TLVObject::Write(TAG tag, const std::monostate &value) { return true; } -bool TLVObject::WriteObject(const std::shared_ptr<Object> &value) +bool TLVObject::Read(std::monostate &value, const TLVHead &head) { return true; } -bool TLVObject::ReadObject(std::shared_ptr<Object> &value) +bool TLVObject::Write(TAG tag, const void *value) { return true; } -bool TLVObject::WriteWant(const std::shared_ptr<OHOS::AAFwk::Want> &value) -{ - return true; -} -bool TLVObject::ReadWant(std::shared_ptr<OHOS::AAFwk::Want> &value) +bool TLVObject::Read(void *value, const TLVHead &head) { return true; } -bool TLVObject::WritePixelMap(const std::shared_ptr<OHOS::Media::PixelMap> &value) +size_t TLVObject::CountHead() { return true; } -bool TLVObject::ReadPixelMap(std::shared_ptr<OHOS::Media::PixelMap> &value) -{ - return false; -} - -bool TLVObject::WriteUndefined(const std::monostate &value) +bool TLVObject::WriteHead(uint16_t type, uint32_t len) { return true; } -bool TLVObject::ReadUndefined(std::monostate &value) +bool TLVObject::WriteBackHead(uint16_t tag, size_t tagCursor, uint32_t len) { return true; } -bool TLVObject::WriteNull(const void *value) +bool TLVObject::ReadHead(TLVHead &head) { return true; } -bool TLVObject::ReadNull(void *value) +bool TLVObject::Skip(TLVHead &head) { return true; } -bool TLVObject::ReadHead(TLVHead &head) +bool TLVObject::HasExpectBuffer(const uint32_t expectLen) const { return true; } -void TLVObject::WriteHead(uint16_t type, size_t tagCursor, uint32_t len) -{ -} +void TLVObject::PrepareBufferForFile(size_t size) { } -bool TLVObject::HasExpectBuffer(const uint32_t expectLen) const +std::uint8_t *TLVObject::GetStartCursor() { - return true; + return 0; } -bool TLVObject::PrepareHeader(size_t size, size_t &tagCursor, size_t &valueCursor) +bool TLVObject::SaveBufferToFile() { return true; } -void TLVObject::PrepareBuffer(size_t size) -{ -} - -bool TLVObject::SaveBufferToFile() +bool TLVObject::SaveBufferToFileFront(size_t tagCursor, uint32_t len) { return true; } @@ -259,4 +198,4 @@ bool TLVObject::LoadBufferFormFile(size_t size) return true; } } // namespace UDMF -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/test/unittest/ndk_data_conversion_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/ndk_data_conversion_test.cpp new file mode 100644 index 00000000..7d8dc455 --- /dev/null +++ b/udmf/framework/innerkitsimpl/test/unittest/ndk_data_conversion_test.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "NdkDataConversionTest" + +#include "ndk_data_conversion.h" +#include <gtest/gtest.h> +#include <memory> +#include "token_setproc.h" +#include "accesstoken_kit.h" +#include "nativetoken_kit.h" +#include "logger.h" +#include "error_code.h" +#include "udmf.h" +#include "udmf_capi_common.h" +#include "uds.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; +using namespace OHOS::UDMF; +using namespace OHOS; + +namespace OHOS::Test { + class NdkDataConversionTest : public testing::Test { + public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + }; + + void NdkDataConversionTest::SetUpTestCase(void) {} + + void NdkDataConversionTest::TearDownTestCase(void) {} + + void NdkDataConversionTest::SetUp(void) {} + + void NdkDataConversionTest::TearDown(void) {} + + /** + * @tc.name: GetNativeUnifiedData_001 + * @tc.desc: Normal testcase of GetNativeUnifiedData + * @tc.type: FUNC + */ + HWTEST_F(NdkDataConversionTest, GetNativeUnifiedData_001, TestSize.Level1) { + LOG_INFO(UDMF_TEST, "GetNativeUnifiedData_001 begin."); + UnifiedRecord unifiedRecord; + const std::string uid("typeId"); + unifiedRecord.SetUid(uid); + OH_UdmfData* ndkData = OH_UdmfData_Create(); + const std::shared_ptr<UnifiedRecord> recordPtr = std::make_shared<UnifiedRecord>(unifiedRecord); + ndkData->unifiedData_->AddRecord(recordPtr); + auto data = std::make_shared<UnifiedData>(); + + Status status = NdkDataConversion::GetNativeUnifiedData(ndkData, data); + ASSERT_EQ(E_OK, status); + EXPECT_EQ("typeId", data->GetRecordAt(0)->GetUid()); + + OH_UdmfData* ndkDataNull = nullptr; + status = NdkDataConversion::GetNativeUnifiedData(ndkDataNull, data); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + + std::shared_ptr<UnifiedData> dataNull; + status = NdkDataConversion::GetNativeUnifiedData(ndkData, dataNull); + OH_UdmfData_Destroy(ndkData); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + LOG_INFO(UDMF_TEST, "GetNativeUnifiedData_001 end."); + } + + /** + * @tc.name: GetNativeUnifiedData_002 + * @tc.desc: Normal testcase of GetNativeUnifiedData + * @tc.type: FUNC + */ + HWTEST_F(NdkDataConversionTest, GetNativeUnifiedData_002, TestSize.Level1) { + LOG_INFO(UDMF_TEST, "GetNativeUnifiedData_002 begin."); + auto plainText = OH_UdsPlainText_Create(); + OH_UdmfData* fakeNdkData = reinterpret_cast<OH_UdmfData*>(plainText); + auto data = std::make_shared<UnifiedData>(); + Status status = NdkDataConversion::GetNativeUnifiedData(fakeNdkData, data); + OH_UdsPlainText_Destroy(plainText); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + LOG_INFO(UDMF_TEST, "GetNativeUnifiedData_002 end."); + } + + /** + * @tc.name: GetNdkUnifiedData_001 + * @tc.desc: Error testcase of GetNdkUnifiedData + * @tc.type: FUNC + */ + HWTEST_F(NdkDataConversionTest, GetNdkUnifiedData_001, TestSize.Level1) { + LOG_INFO(UDMF_TEST, "GetNdkUnifiedData_001 begin."); + UnifiedRecord unifiedRecord; + const std::string uid("typeId"); + unifiedRecord.SetUid(uid); + const std::shared_ptr<UnifiedRecord> recordPtr = std::make_shared<UnifiedRecord>(unifiedRecord); + auto data= std::make_shared<UnifiedData>(); + data->AddRecord(recordPtr); + OH_UdmfData* ndkData = OH_UdmfData_Create(); + Status status = NdkDataConversion::GetNdkUnifiedData(data, ndkData); + ASSERT_EQ(E_OK, status); + EXPECT_EQ("typeId", ndkData->unifiedData_->GetRecordAt(0)->GetUid()); + + OH_UdmfData* ndkDataNull = nullptr; + status = NdkDataConversion::GetNdkUnifiedData(data, ndkDataNull); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + + std::shared_ptr<UnifiedData> dataNull; + status = NdkDataConversion::GetNdkUnifiedData(dataNull, ndkData); + OH_UdmfData_Destroy(ndkData); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + LOG_INFO(UDMF_TEST, "GetNdkUnifiedData_001 end."); + } + + /** + * @tc.name: GetNdkUnifiedData_002 + * @tc.desc: Error testcase of GetNdkUnifiedData + * @tc.type: FUNC + */ + HWTEST_F(NdkDataConversionTest, GetNdkUnifiedData_002, TestSize.Level1) { + LOG_INFO(UDMF_TEST, "GetNdkUnifiedData_002 begin."); + auto plainText = OH_UdsPlainText_Create(); + OH_UdmfData* fakeNdkData = reinterpret_cast<OH_UdmfData*>(plainText); + auto data = std::make_shared<UnifiedData>(); + Status status = NdkDataConversion::GetNdkUnifiedData(data, fakeNdkData); + OH_UdsPlainText_Destroy(plainText); + ASSERT_EQ(E_INVALID_PARAMETERS, status); + LOG_INFO(UDMF_TEST, "GetNdkUnifiedData_002 end."); + } +} \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/plain_text_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/plain_text_test.cpp index a565355e..a49d6f76 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/plain_text_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/plain_text_test.cpp @@ -98,26 +98,4 @@ HWTEST_F(PlainTextTest, SetAbstract003, TestSize.Level1) EXPECT_NE(plainText.abstract_, abstract); LOG_INFO(UDMF_TEST, "SetAbstract003 end."); } - -/** -* @tc.name: GetValue004 -* @tc.desc: Normal testcase of GetValue -* @tc.type: FUNC -*/ -HWTEST_F(PlainTextTest, GetValue004, TestSize.Level1) -{ - LOG_INFO(UDMF_TEST, "GetValue004 begin."); - PlainText plainText; - plainText.value_ = std::monostate{}; - plainText.content_ = "content"; - plainText.abstract_ = "abstract"; - plainText.GetValue(); - auto object = std::get<std::shared_ptr<Object>>(plainText.value_); - auto details_ = std::get<std::shared_ptr<Object>>(object->value_[PlainText::DETAILS]); - EXPECT_EQ(std::get<std::string>(object->value_[UNIFORM_DATA_TYPE]), "general.plain-text"); - EXPECT_EQ(std::get<std::string>(object->value_[PlainText::TEXT_CONTENT]), plainText.content_); - EXPECT_EQ(std::get<std::string>(object->value_[ABSTRACT]), plainText.abstract_); - EXPECT_EQ(details_->value_.size(), 0); - LOG_INFO(UDMF_TEST, "GetValue004 end."); -} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/system_defined_appitem_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/system_defined_appitem_test.cpp index e8a0be27..9155a366 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/system_defined_appitem_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/system_defined_appitem_test.cpp @@ -61,10 +61,10 @@ HWTEST_F(SystemDefinedAppitemTest, SetItems001, TestSize.Level1) { LOG_INFO(UDMF_TEST, "SetItems001 begin."); SystemDefinedAppItem systemDefinedAppItem; - systemDefinedAppItem.value_ = std::make_shared<Object>(); UDDetails details; details.insert({ "string", "" }); systemDefinedAppItem.SetItems(details); + systemDefinedAppItem.InitObject(); auto object = std::get<std::shared_ptr<Object>>(systemDefinedAppItem.value_); EXPECT_EQ(std::get<std::string>(object->value_[UNIFORM_DATA_TYPE]), "openharmony.app-item"); LOG_INFO(UDMF_TEST, "SetItems001 end."); @@ -207,7 +207,7 @@ HWTEST_F(SystemDefinedAppitemTest, GetValue001, TestSize.Level1) valueType.appLabelId_ = "appLabelId"; valueType.bundleName_ = "bundleName"; valueType.abilityName_ = "abilityName"; - valueType.GetValue(); + valueType.InitObject(); auto object = std::get<std::shared_ptr<Object>>(valueType.value_); auto details = std::get<std::shared_ptr<Object>>(object->value_[SystemDefinedAppItem::DETAILS]); EXPECT_EQ(std::get<std::string>(object->value_[UNIFORM_DATA_TYPE]), "openharmony.app-item"); diff --git a/udmf/framework/innerkitsimpl/test/unittest/system_defined_record_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/system_defined_record_test.cpp index ff3f3d4e..74f664bd 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/system_defined_record_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/system_defined_record_test.cpp @@ -66,6 +66,7 @@ HWTEST_F(SystemDefinedRecordTest, AddProperty001, TestSize.Level1) systemDefinedRecord.AddProperty(property, value); auto object = std::get<std::shared_ptr<Object>>(systemDefinedRecord.value_); auto details = std::get<std::shared_ptr<Object>>(object->value_[SystemDefinedRecord::DETAILS]); + systemDefinedRecord.InitObject(); EXPECT_EQ(systemDefinedRecord.details_.size(), 1); EXPECT_NE(details->value_.size(), 0); LOG_INFO(UDMF_TEST, "AddProperty001 end."); @@ -118,7 +119,6 @@ HWTEST_F(SystemDefinedRecordTest, InitObject001, TestSize.Level1) LOG_INFO(UDMF_TEST, "InitObject001 begin."); SystemDefinedRecord systemDefinedRecord; systemDefinedRecord.details_.insert({ "first", "second" }); - systemDefinedRecord.value_ = std::make_shared<Object>(); systemDefinedRecord.InitObject(); auto object = std::get<std::shared_ptr<Object>>(systemDefinedRecord.value_); auto details = std::get<std::shared_ptr<Object>>(object->value_[SystemDefinedRecord::DETAILS]); diff --git a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp index 5e038cf8..bd3a3df7 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp @@ -847,7 +847,17 @@ HWTEST_F(UdmfClientTest, SetData014, TestSize.Level1) UDDetails details1; details1.insert({ "udmf_key", "udmf_value" }); systemDefinedPixelMap1.SetDetails(details1); - std::vector<uint8_t> rawData1 = { 1, 2, 3, 4, 5 }; + std::vector<uint8_t> rawData1; + + uint32_t color[100] = { 3, 7, 9, 9, 7, 6 }; + OHOS::Media::InitializationOptions opts = { { 5, 7 }, + Media::PixelFormat::ARGB_8888, + Media::PixelFormat::ARGB_8888 }; + std::unique_ptr<OHOS::Media::PixelMap> pixelMap = + OHOS::Media::PixelMap::Create(color, sizeof(color) / sizeof(color[0]), opts); + std::shared_ptr<OHOS::Media::PixelMap> pixelMapIn = move(pixelMap); + pixelMapIn->EncodeTlv(rawData1); + systemDefinedPixelMap1.SetRawData(rawData1); std::shared_ptr<UnifiedRecord> record1 = std::make_shared<SystemDefinedPixelMap>(systemDefinedPixelMap1); data1.AddRecord(record1); @@ -2011,6 +2021,115 @@ HWTEST_F(UdmfClientTest, SetData024, TestSize.Level1) LOG_INFO(UDMF_TEST, "SetData024 end."); } +/** +* @tc.name: SetData025 +* @tc.desc: Set PixelMap record with valid params and get data +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, SetData025, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "SetData025 begin."); + + CustomOption option1 = { .intention = Intention::UD_INTENTION_DRAG }; + UnifiedData data1; + std::string key; + SystemDefinedPixelMap systemDefinedPixelMap1; + UDDetails details1; + details1.insert({ "udmf_key", "udmf_value" }); + systemDefinedPixelMap1.SetDetails(details1); + std::vector<uint8_t> rawData1 = { 1, 2, 3, 4, 5 }; + + systemDefinedPixelMap1.SetRawData(rawData1); + std::shared_ptr<UnifiedRecord> record1 = std::make_shared<SystemDefinedPixelMap>(systemDefinedPixelMap1); + data1.AddRecord(record1); + auto status = UdmfClient::GetInstance().SetData(option1, data1, key); + ASSERT_EQ(status, E_OK); + + QueryOption option2 = { .key = key }; + AddPrivilege(option2); + SetHapToken2(); + UnifiedData data2; + status = UdmfClient::GetInstance().GetData(option2, data2); + ASSERT_EQ(status, E_OK); + + std::shared_ptr<UnifiedRecord> record2 = data2.GetRecordAt(0); + ASSERT_NE(record2, nullptr); + auto type = record2->GetType(); + ASSERT_EQ(type, UDType::SYSTEM_DEFINED_PIXEL_MAP); + + auto systemDefinedRecord2 = static_cast<SystemDefinedRecord *>(record2.get()); + ASSERT_NE(systemDefinedRecord2, nullptr); + CompareDetails(systemDefinedRecord2->GetDetails()); + + auto systemDefinedPixelMap2 = static_cast<SystemDefinedPixelMap *>(record2.get()); + ASSERT_NE(systemDefinedPixelMap2, nullptr); + auto rawData2 = systemDefinedPixelMap2->GetRawData(); + EXPECT_EQ(rawData1.size(), rawData2.size()); + for (uint32_t i = 0; i < rawData1.size(); ++i) { + EXPECT_EQ(rawData1[i], rawData2[i]); + } + + LOG_INFO(UDMF_TEST, "SetData025 end."); +} + +/** +* @tc.name: SetData026 +* @tc.desc: Set more record with valid params and get data +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, SetData026, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "SetData026 begin."); + + CustomOption option1 = { .intention = Intention::UD_INTENTION_DRAG }; + UnifiedData data1; + std::string key; + SystemDefinedPixelMap systemDefinedPixelMap1; + UDDetails details1; + details1.insert({ "udmf_key", "udmf_value" }); + systemDefinedPixelMap1.SetDetails(details1); + std::vector<uint8_t> rawData1 = { 1, 2, 3, 4, 5 }; + + systemDefinedPixelMap1.SetRawData(rawData1); + std::shared_ptr<UnifiedRecord> record1 = std::make_shared<SystemDefinedPixelMap>(systemDefinedPixelMap1); + std::shared_ptr<UnifiedRecord> record2 = std::make_shared<PlainText>(UDType::PLAIN_TEXT, "this is a content"); + data1.AddRecord(record1); + data1.AddRecord(record2); + auto status = UdmfClient::GetInstance().SetData(option1, data1, key); + ASSERT_EQ(status, E_OK); + + QueryOption option2 = { .key = key }; + AddPrivilege(option2); + SetHapToken2(); + UnifiedData data2; + status = UdmfClient::GetInstance().GetData(option2, data2); + ASSERT_EQ(status, E_OK); + + std::shared_ptr<UnifiedRecord> record3 = data2.GetRecordAt(0); + ASSERT_NE(record3, nullptr); + auto type = record3->GetType(); + ASSERT_EQ(type, UDType::SYSTEM_DEFINED_PIXEL_MAP); + + auto systemDefinedRecord2 = static_cast<SystemDefinedRecord *>(record3.get()); + ASSERT_NE(systemDefinedRecord2, nullptr); + CompareDetails(systemDefinedRecord2->GetDetails()); + + auto systemDefinedPixelMap2 = static_cast<SystemDefinedPixelMap *>(record3.get()); + ASSERT_NE(systemDefinedPixelMap2, nullptr); + auto rawData2 = systemDefinedPixelMap2->GetRawData(); + EXPECT_EQ(rawData1.size(), rawData2.size()); + for (uint32_t i = 0; i < rawData1.size(); ++i) { + EXPECT_EQ(rawData1[i], rawData2[i]); + } + + std::shared_ptr<UnifiedRecord> record4 = data2.GetRecordAt(1); + auto plainText = static_cast<PlainText *>(record4.get()); + ASSERT_EQ(UDType::PLAIN_TEXT, plainText->GetType()); + ASSERT_EQ("this is a content", plainText->GetContent()); + + LOG_INFO(UDMF_TEST, "SetData026 end."); +} + /** * @tc.name: GetSummary003 * @tc.desc: Get summary data diff --git a/udmf/framework/jskitsimpl/common/napi_error_utils.cpp b/udmf/framework/jskitsimpl/common/napi_error_utils.cpp index d0a99948..23d7445a 100644 --- a/udmf/framework/jskitsimpl/common/napi_error_utils.cpp +++ b/udmf/framework/jskitsimpl/common/napi_error_utils.cpp @@ -90,8 +90,8 @@ void ThrowNapiError(napi_env env, int32_t status, const std::string &errMessage, } else { jsCode = std::to_string(napiError.jsCode); } - LOG_INFO(UDMF_KITS_NAPI, "ThrowNapiError, status:%{public}d, jsCode: %{public}s, message: %{public}s", status, - jsCode.c_str(), errMessage.c_str()); + LOG_INFO(UDMF_KITS_NAPI, "ThrowNapiError, status:%{public}d, jsCode: %{public}s, message: %{public}s", + status, jsCode.c_str(), errMessage.c_str()); napi_throw_error(env, jsCode.c_str(), message.c_str()); } } // namespace UDMF diff --git a/udmf/framework/ndkimpl/data/udmf.cpp b/udmf/framework/ndkimpl/data/udmf.cpp index 85c264ce..e45aa73e 100644 --- a/udmf/framework/ndkimpl/data/udmf.cpp +++ b/udmf/framework/ndkimpl/data/udmf.cpp @@ -30,12 +30,24 @@ #include "system_defined_appitem.h" #include "application_defined_record.h" #include "system_defined_pixelmap.h" +#include "file.h" +#include "audio.h" +#include "folder.h" +#include "image.h" +#include "video.h" using namespace OHOS::UDMF; static constexpr uint64_t MAX_RECORDS_COUNT = 4 * 1024 * 1024; static constexpr uint64_t MAX_RECORDS_SIZE = 4 * 1024 * 1024; static constexpr uint64_t MAX_KEY_STRING_LEN = 1 * 1024 * 1024; +static const std::map<std::string, UDType> FILE_TYPES = { + { UDMF_META_GENERAL_FILE, UDType::FILE }, + { UDMF_META_AUDIO, UDType::AUDIO }, + { UDMF_META_FOLDER, UDType::FOLDER }, + { UDMF_META_IMAGE, UDType::IMAGE }, + { UDMF_META_VIDEO, UDType::VIDEO } +}; static void DestroyStringArray(char**& bufArray, unsigned int& count) { @@ -136,6 +148,17 @@ static bool IsUnifiedPropertiesValid(OH_UdmfProperty* properties) properties->cid == NdkStructId::UDMF_UNIFIED_DATA_PROPERTIES_ID; } +static void AddFileUriTypeIfContains(std::vector<std::string>& types) +{ + for (auto type : types) { + if (FILE_TYPES.find(type) != FILE_TYPES.end()) { + types.push_back(UDMF_META_GENERAL_FILE_URI); + break; + } + } + return; +} + OH_UdmfData* OH_UdmfData_Create() { OH_UdmfData* data = new (std::nothrow) OH_UdmfData; @@ -182,6 +205,7 @@ char** OH_UdmfData_GetTypes(OH_UdmfData* unifiedData, unsigned int* count) return unifiedData->typesArray; } std::vector<std::string> typeLabels = unifiedData->unifiedData_->GetEntriesTypes(); + AddFileUriTypeIfContains(typeLabels); unifiedData->typesArray = StrVectorToTypesArray(typeLabels); unifiedData->typesArray == nullptr ? unifiedData->typesCount = 0 : unifiedData->typesCount = typeLabels.size(); *count = unifiedData->typesCount; @@ -201,6 +225,7 @@ char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* record, unsigned int* count) } auto types = record->record_->GetUtdIds(); std::vector<std::string> typeLabels {types.begin(), types.end()}; + AddFileUriTypeIfContains(typeLabels); record->typesArray = StrVectorToTypesArray(typeLabels); record->typesArray == nullptr ? record->typesCount = 0 : record->typesCount = typeLabels.size(); *count = record->typesCount; @@ -308,7 +333,7 @@ int OH_UdmfData_GetRecordCount(OH_UdmfData *data) OH_UdmfRecord* OH_UdmfData_GetRecord(OH_UdmfData* data, unsigned int index) { - if (!IsUnifiedDataValid(data) || index < 0) { + if (!IsUnifiedDataValid(data)) { return nullptr; } std::lock_guard<std::mutex> lock(data->mutex); @@ -408,18 +433,12 @@ int OH_UdmfRecord_AddGeneralEntry(OH_UdmfRecord* record, const char* typeId, count > MAX_GENERAL_ENTRY_SIZE || strlen(typeId) > MAX_KEY_STRING_LEN) { return UDMF_E_INVALID_PARAM; } - std::string utdId(typeId); - std::string prefix(APPLICATION_DEFINED_TYPE); - if (utdId.compare(0, prefix.length(), prefix) != 0) { - LOG_ERROR(UDMF_CAPI, "not appdefined type:%{public}s", utdId.c_str()); - return UDMF_E_INVALID_PARAM; - } std::vector<uint8_t> recordValue(entry, entry + count); if (record->record_->GetType() == UD_BUTT) { record->record_ = std::make_shared<ApplicationDefinedRecord>(APPLICATION_DEFINED_RECORD, recordValue); record->record_->SetUtdId(typeId); } else { - record->record_->AddEntry(utdId, std::move(recordValue)); + record->record_->AddEntry(typeId, std::move(recordValue)); } record->recordDataLen = count; return UDMF_E_OK; @@ -554,7 +573,30 @@ int OH_UdmfRecord_AddFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri) if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) { return UDMF_E_INVALID_PARAM; } - AddUds<UnifiedRecord>(record, fileUri, UDType::FILE_URI); + std::string* fileType = std::get_if<std::string>(&(fileUri->obj->value_[FILE_TYPE])); + if (fileType == nullptr) { + return UDMF_ERR; + } + int32_t utdId = UtdUtils::GetUtdEnumFromUtdId(*fileType); + switch (utdId) { + case UDType::FILE: + AddUds<File>(record, fileUri, UDType::FILE); + break; + case UDType::AUDIO: + AddUds<Audio>(record, fileUri, UDType::AUDIO); + break; + case UDType::FOLDER: + AddUds<Audio>(record, fileUri, UDType::FOLDER); + break; + case UDType::IMAGE: + AddUds<Image>(record, fileUri, UDType::IMAGE); + break; + case UDType::VIDEO: + AddUds<Video>(record, fileUri, UDType::VIDEO); + break; + default: + AddUds<UnifiedRecord>(record, fileUri, UDType::FILE_URI); + } return UDMF_E_OK; } @@ -569,6 +611,7 @@ int OH_UdmfRecord_AddPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap) int GetUds(OH_UdmfRecord* record, UdsObject* udsObject, UDType type) { + record->record_->InitObject(); auto value = record->record_->GetEntry(UtdUtils::GetUtdIdFromUtdEnum(type)); if (!std::holds_alternative<std::shared_ptr<Object>>(value)) { return UDMF_ERR; @@ -630,7 +673,16 @@ int OH_UdmfRecord_GetFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri) if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) { return UDMF_E_INVALID_PARAM; } - return GetUds(record, fileUri, UDType::FILE_URI); + for (auto fileType : FILE_TYPES) { + int ret = GetUds(record, fileUri, fileType.second); + if (ret == UDMF_E_OK) { + fileUri->obj->value_[UNIFORM_DATA_TYPE] = UDMF_META_GENERAL_FILE_URI; + fileUri->obj->value_[FILE_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(fileType.second); + return UDMF_E_OK; + } + } + LOG_ERROR(UDMF_CAPI, "could't find file uri"); + return UDMF_ERR; } int OH_UdmfRecord_GetPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap) diff --git a/udmf/framework/ndkimpl/data/udmf_capi_common.h b/udmf/framework/ndkimpl/data/udmf_capi_common.h index b7ee65c7..c79eac13 100644 --- a/udmf/framework/ndkimpl/data/udmf_capi_common.h +++ b/udmf/framework/ndkimpl/data/udmf_capi_common.h @@ -21,7 +21,7 @@ #include <mutex> #include <cstdint> -# define MAX_GENERAL_ENTRY_SIZE (128 * 1024 * 1024) +# define MAX_GENERAL_ENTRY_SIZE (100 * 1024 * 1024) struct UdsObject { const int64_t cid; @@ -30,7 +30,7 @@ struct UdsObject { explicit UdsObject(int cid); template<typename T> bool HasObjectKey(const char* paramName); template<typename T> T* GetUdsValue(const char* paramName); - template<typename T> int SetUdsValue(const char* paramName, T pramValue); + template<typename T> int SetUdsValue(const char* paramName, const T pramValue); }; enum NdkStructId : std::int64_t { diff --git a/udmf/framework/ndkimpl/unittest/udmf_test.cpp b/udmf/framework/ndkimpl/unittest/udmf_test.cpp index 5992a2e9..6d6532d3 100644 --- a/udmf/framework/ndkimpl/unittest/udmf_test.cpp +++ b/udmf/framework/ndkimpl/unittest/udmf_test.cpp @@ -29,6 +29,7 @@ #include "plain_text.h" #include "udmf_meta.h" #include "data_provider_impl.h" +#include "image.h" using namespace testing::ext; using namespace OHOS::Security::AccessToken; @@ -660,12 +661,12 @@ HWTEST_F(UDMFTest, OH_Udmf_GetGeneralEntry001, TestSize.Level0) */ HWTEST_F(UDMFTest, OH_Udmf_AddAndGetGeneralEntry002, TestSize.Level0) { - char typeId[] = "general.plain-text"; + char typeId[] = "general.plain-text-1"; unsigned char entry[] = "CreateGeneralRecord"; unsigned int count = sizeof(entry); OH_UdmfRecord *record = OH_UdmfRecord_Create(); int addRes1 = OH_UdmfRecord_AddGeneralEntry(record, typeId, entry, count); - EXPECT_EQ(addRes1, UDMF_E_INVALID_PARAM); + EXPECT_EQ(addRes1, UDMF_E_OK); } /** @@ -1885,4 +1886,57 @@ HWTEST_F(UDMFTest, OH_UdmfData_IsLocal001, TestSize.Level1) OH_UdmfData_Destroy(data2); } + +/** + * @tc.name: FileUriTest001 + * @tc.desc: test fileUri between js and capi + * @tc.type: FUNC + */ +HWTEST_F(UDMFTest, FileUriTest001, TestSize.Level1) +{ + std::string uri = "https://xxx/xx/xx.jpg"; + std::shared_ptr<Image> image = std::make_shared<Image>(); + image->SetUri(uri); + std::shared_ptr<UnifiedData> unifiedData = std::make_shared<UnifiedData>(); + unifiedData->AddRecord(image); + std::string key; + CustomOption option = { + .intention = UD_INTENTION_DRAG + }; + int setRet = UdmfClient::GetInstance().SetData(option, *unifiedData, key); + EXPECT_EQ(setRet, E_OK); + + OH_UdmfData* udmfData = OH_UdmfData_Create(); + OH_Udmf_GetUnifiedData(key.c_str(), UDMF_INTENTION_DRAG, udmfData); + + unsigned int dataTypeCount; + char** dataTypes = OH_UdmfData_GetTypes(udmfData, &dataTypeCount); + EXPECT_EQ(dataTypeCount, 2); + EXPECT_NE(dataTypes, nullptr); + EXPECT_EQ(strcmp(dataTypes[0], UDMF_META_IMAGE), 0); + EXPECT_EQ(strcmp(dataTypes[1], UDMF_META_GENERAL_FILE_URI), 0); + + unsigned int recordCount; + OH_UdmfRecord** records = OH_UdmfData_GetRecords(udmfData, &recordCount); + EXPECT_EQ(recordCount, 1); + EXPECT_NE(records, nullptr); + + for (unsigned int idx = 0; idx < recordCount; ++idx) { + unsigned int recordTypeCount; + char** recordTypes = OH_UdmfRecord_GetTypes(records[idx], &recordTypeCount); + EXPECT_EQ(recordTypeCount, 2); + EXPECT_NE(recordTypes, nullptr); + EXPECT_EQ(strcmp(recordTypes[0], UDMF_META_IMAGE), 0); + EXPECT_EQ(strcmp(recordTypes[1], UDMF_META_GENERAL_FILE_URI), 0); + for (unsigned int recordIdx = 0; recordIdx < recordTypeCount; ++recordIdx) { + if (strcmp(recordTypes[recordIdx], UDMF_META_GENERAL_FILE_URI) == 0) { + OH_UdsFileUri* fileUri = OH_UdsFileUri_Create(); + int getFileUriRet = OH_UdmfRecord_GetFileUri(records[idx], fileUri); + EXPECT_EQ(getFileUriRet, UDMF_E_OK); + const char* getFileUri = OH_UdsFileUri_GetFileUri(fileUri); + EXPECT_EQ(strcmp(getFileUri, uri.c_str()), 0); + } + } + } +} } diff --git a/udmf/framework/ndkimpl/unittest/uds_test.cpp b/udmf/framework/ndkimpl/unittest/uds_test.cpp index 7ae4007e..4dd4603e 100644 --- a/udmf/framework/ndkimpl/unittest/uds_test.cpp +++ b/udmf/framework/ndkimpl/unittest/uds_test.cpp @@ -1064,7 +1064,7 @@ HWTEST_F(UdsTest, OH_UdsArrayBuffer_SetData_001, TestSize.Level1) result = OH_UdsArrayBuffer_SetData(buffer, data, 0); EXPECT_EQ(UDMF_E_INVALID_PARAM, result); - result = OH_UdsArrayBuffer_SetData(buffer, data, 128 * 1024 * 1024 + 1); + result = OH_UdsArrayBuffer_SetData(buffer, data, 100 * 1024 * 1024 + 1); EXPECT_EQ(UDMF_E_INVALID_PARAM, result); result = OH_UdsArrayBuffer_SetData(buffer, data, len); diff --git a/udmf/interfaces/cj/BUILD.gn b/udmf/interfaces/cj/BUILD.gn new file mode 100644 index 00000000..5546b5b4 --- /dev/null +++ b/udmf/interfaces/cj/BUILD.gn @@ -0,0 +1,128 @@ +# 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. +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/distributeddatamgr/udmf/udmf.gni") + +ohos_shared_library("cj_unified_data_channel_ffi") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "${udmf_interfaces_path}/cj/include", + "${udmf_interfaces_path}/innerkits/client", + "${udmf_interfaces_path}/innerkits/common", + "${udmf_interfaces_path}/innerkits/data", + "${udmf_interfaces_path}/jskits/common", + "${udmf_interfaces_path}/jskits/data", + + "${udmf_framework_path}/common", + "${udmf_framework_path}/innerkits/service", + ] + + if (product_name != "ohos-sdk") { + sources = [ + "${udmf_interfaces_path}/cj/src/unified_data_ffi.cpp", + "${udmf_interfaces_path}/cj/src/unified_data_impl.cpp", + "${udmf_interfaces_path}/cj/src/unified_record_ffi.cpp", + "${udmf_interfaces_path}/cj/src/unified_record_impl.cpp", + "${udmf_interfaces_path}/cj/src/utils.cpp", + ] + + deps = [ "../innerkits:udmf_client" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "ability_runtime:abilitykit_native", + "ability_runtime:napi_common", + "c_utils:utils", + "hilog:libhilog", + "image_framework:cj_image_ffi", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + + public_external_deps = [ "image_framework:image" ] + } + + # cflags = [ "-fvisibility=hidden" ] + innerapi_tags = [ "platformsdk" ] + subsystem_name = "distributeddatamgr" + part_name = "udmf" +} + +ohos_shared_library("cj_uniform_type_descriptor_ffi") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "${udmf_interfaces_path}/cj/include", + "${udmf_interfaces_path}/innerkits/client", + "${udmf_interfaces_path}/innerkits/common", + "${udmf_interfaces_path}/innerkits/data", + "${udmf_interfaces_path}/jskits/common", + "${udmf_interfaces_path}/jskits/data", + + "${udmf_framework_path}/common", + "${udmf_framework_path}/innerkits/service", + ] + + if (product_name != "ohos-sdk") { + sources = [ + "${udmf_interfaces_path}/cj/src/type_descriptor_ffi.cpp", + "${udmf_interfaces_path}/cj/src/type_descriptor_impl.cpp", + "${udmf_interfaces_path}/cj/src/uniform_type_descriptor_ffi.cpp", + "${udmf_interfaces_path}/cj/src/uniform_type_descriptor_impl.cpp", + "${udmf_interfaces_path}/cj/src/utils.cpp", + ] + + deps = [ + "../innerkits:udmf_client", + "../innerkits:utd_client", + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "ability_runtime:abilitykit_native", + "ability_runtime:napi_common", + "c_utils:utils", + "hilog:libhilog", + "image_framework:cj_image_ffi", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + + public_external_deps = [ "image_framework:image" ] + } + + # cflags = [ "-fvisibility=hidden" ] + innerapi_tags = [ "platformsdk" ] + subsystem_name = "distributeddatamgr" + part_name = "udmf" +} diff --git a/udmf/interfaces/cj/include/type_descriptor_ffi.h b/udmf/interfaces/cj/include/type_descriptor_ffi.h new file mode 100644 index 00000000..8c5640d5 --- /dev/null +++ b/udmf/interfaces/cj/include/type_descriptor_ffi.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_TYPE_DESCRIPTOR_FFI_H +#define UDMF_TYPE_DESCRIPTOR_FFI_H + +#include <cstdint> +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" + +#include "type_descriptor_impl.h" + +namespace OHOS { +namespace UDMF { +extern "C" { + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetTypeId(int64_t typeDescriptorID); + FFI_EXPORT CArrString FfiUDMFUniformTypeDescriptorGetBelongingToTypes(int64_t typeDescriptorID); + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetDescription(int64_t typeDescriptorID); + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetReferenceURL(int64_t typeDescriptorID); + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetIconFile(int64_t typeDescriptorID); + FFI_EXPORT CArrString FfiUDMFUniformTypeDescriptorGetFilenameExtensions(int64_t typeDescriptorID); + FFI_EXPORT CArrString FfiUDMFUniformTypeDescriptorGetMimeTypes(int64_t typeDescriptorID); + FFI_EXPORT bool FfiUDMFUniformTypeDescriptorBelongsTo(int64_t typeDescriptorID, const char *type); + FFI_EXPORT bool FfiUDMFUniformTypeDescriptorIsLowerLevelType(int64_t typeDescriptorID, const char *type); + FFI_EXPORT bool FfiUDMFUniformTypeDescriptorIsHigherLevelType(int64_t typeDescriptorID, const char *type); + FFI_EXPORT bool FfiUDMFUniformTypeDescriptorEquals(int64_t thisTypeDescriptorID, int64_t thatTypeDescriptorID); +} +} +} + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/type_descriptor_impl.h b/udmf/interfaces/cj/include/type_descriptor_impl.h new file mode 100644 index 00000000..9e8194ca --- /dev/null +++ b/udmf/interfaces/cj/include/type_descriptor_impl.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_TYPE_DESCRIPTOR_IMPL_H +#define UDMF_TYPE_DESCRIPTOR_IMPL_H + +#include <memory> + +#include "type_descriptor.h" +#include "cj_common_ffi.h" +#include "udmf_log.h" + +namespace OHOS { +namespace UDMF { + using namespace OHOS::UDMF; + + class CTypeDescriptor : public OHOS::FFI::FFIData { + DECL_TYPE(CTypeDescriptor, OHOS::FFI::FFIData) + public: + CTypeDescriptor(std::shared_ptr<UDMF::TypeDescriptor> typeDescriptor); + + char *GetTypeId(); + CArrString GetBelongingToTypes(); + char *GetDescription(); + char *GetIconFile(); + char *GetReferenceURL(); + CArrString GetFilenameExtensions(); + CArrString GetMimeTypes(); + + bool BelongsTo(const char *type); + bool IsLowerLevelType(const char *type); + bool IsHigherLevelType(const char *type); + bool Equals(CTypeDescriptor* thatCTypeDescriptor); + + const std::shared_ptr<UDMF::TypeDescriptor> &GetTypeDescriptor() const; + + private: + std::shared_ptr<UDMF::TypeDescriptor> typeDescriptor_; + }; + +} +} // namespace OHOS::UDMF + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/udmf_log.h b/udmf/interfaces/cj/include/udmf_log.h new file mode 100644 index 00000000..f992c7ac --- /dev/null +++ b/udmf/interfaces/cj/include/udmf_log.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_LOG_H +#define UDMF_LOG_H + +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD001656 +#define LOG_TAG "UDMFCffi" + +#define LOGI(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_INFO)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGD(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_DEBUG)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGE(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_ERROR)) { \ + HILOG_ERROR(LOG_CORE, __VA_ARGS__); \ +} + +#endif diff --git a/udmf/interfaces/cj/include/unified_data_ffi.h b/udmf/interfaces/cj/include/unified_data_ffi.h new file mode 100644 index 00000000..489fd8e7 --- /dev/null +++ b/udmf/interfaces/cj/include/unified_data_ffi.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFIED_DATA_FFI_H +#define UDMF_UNIFIED_DATA_FFI_H + +#include <cstdint> +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" + +#include "unified_data_impl.h" + +namespace OHOS { +namespace UDMF { +extern "C" { + FFI_EXPORT int64_t FfiUDMFUnifiedDataConstructor(); + FFI_EXPORT int64_t FfiUDMFUnifiedDataConstructorwWithRecord(int64_t unifiedRecordId); + FFI_EXPORT void FfiUDMFUnifiedDataAddRecord(int64_t unifiedDataId, int64_t unifiedRecordId); + FFI_EXPORT CArrUnifiedRecord FfiUDMFUnifiedDataGetRecords(int64_t unifiedDataId); + FFI_EXPORT bool FfiUDMFUnifiedDataHasType(int64_t unifiedDataId, const char *type); + FFI_EXPORT CArrString FfiUDMFUnifiedDataGetTypes(int64_t unifiedDataId); +} +} +} + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/unified_data_impl.h b/udmf/interfaces/cj/include/unified_data_impl.h new file mode 100644 index 00000000..0ccd9434 --- /dev/null +++ b/udmf/interfaces/cj/include/unified_data_impl.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFIED_DATA_IMPL_H +#define UDMF_UNIFIED_DATA_IMPL_H + +#include <memory> + +#include "unified_data.h" +#include "unified_record_impl.h" +#include "cj_common_ffi.h" + +namespace OHOS { +namespace UDMF { + using namespace OHOS::UDMF; + + typedef CArrI64 CArrUnifiedRecord; + + class CUnifiedData : public OHOS::FFI::FFIData { + DECL_TYPE(CUnifiedData, OHOS::FFI::FFIData) + public: + CUnifiedData(); + CUnifiedData(UDMF::CUnifiedRecord *record); + + void AddRecord(UDMF::CUnifiedRecord *record); + CArrUnifiedRecord GetRecords(); + bool HasType(const char *type); + CArrString GetTypes(); + + private: + std::shared_ptr<UDMF::UnifiedData> unifiedData_; + std::vector<UDMF::CUnifiedRecord *> records_; + }; + +} +} // namespace OHOS::UDMF + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/unified_record_ffi.h b/udmf/interfaces/cj/include/unified_record_ffi.h new file mode 100644 index 00000000..11cdecd7 --- /dev/null +++ b/udmf/interfaces/cj/include/unified_record_ffi.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFIED_RECORD_FFI_H +#define UDMF_UNIFIED_RECORD_FFI_H + +#include <cstdint> + +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" + +#include "unified_record_impl.h" + +namespace OHOS { +namespace UDMF { +extern "C" { + FFI_EXPORT int64_t FfiUDMFUnifiedRecordConstructor(); + FFI_EXPORT int64_t FfiUDMFUnifiedRecordConstructorwithType(const char *type, CJValueType value); + FFI_EXPORT char *FfiUDMFUnifiedRecordGetType(int64_t unifiedId); + FFI_EXPORT CJValueType FfiUDMFUnifiedRecordGetValue(int64_t unifiedId); +} +} +} + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/unified_record_impl.h b/udmf/interfaces/cj/include/unified_record_impl.h new file mode 100644 index 00000000..1b71c182 --- /dev/null +++ b/udmf/interfaces/cj/include/unified_record_impl.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFIED_RECORD_IMPL_H +#define UDMF_UNIFIED_RECORD_IMPL_H + +#include "unified_record.h" +#include "cj_common_ffi.h" + +namespace OHOS { +namespace UDMF { + using namespace OHOS::UDMF; + + struct CJValueType { + int32_t integer32; + int64_t integer64; + double dou; + bool boolean; + char *string; + CArrUI8 byteArray; + int64_t pixelMapId; + + uint8_t tag; + }; + + enum TypeSymbol { + INTEGER32 = 0, + INTEGER64 = 1, + DOUBLE = 2, + BOOLEAN = 3, + STRING = 4, + BYTEARRAY = 5, + PIXELMAP = 6 + }; + + class CUnifiedRecord : public OHOS::FFI::FFIData { + DECL_TYPE(CUnifiedRecord, OHOS::FFI::FFIData) + public: + CUnifiedRecord(); + CUnifiedRecord(const char *type, CJValueType value); + CJValueType ValueType2CJValueType(ValueType value); + ValueType CJValueType2ValueType(CJValueType value); + char *GetType(); + CJValueType GetValue(); + + const std::shared_ptr<UDMF::UnifiedRecord> &GetUnifiedRecord() const; + + private: + std::shared_ptr<UDMF::UnifiedRecord> unifiedRecord_; + int64_t pixelMapId_; + }; + +} +} // namespace OHOS::UDMF + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/uniform_type_descriptor_ffi.h b/udmf/interfaces/cj/include/uniform_type_descriptor_ffi.h new file mode 100644 index 00000000..d8688715 --- /dev/null +++ b/udmf/interfaces/cj/include/uniform_type_descriptor_ffi.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFORM_TYPE_DESCRIPTOR_FFI_H +#define UDMF_UNIFORM_TYPE_DESCRIPTOR_FFI_H + +#include <cstdint> +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" + +#include "uniform_type_descriptor_impl.h" + +namespace OHOS { +namespace UDMF { +extern "C" { + FFI_EXPORT int64_t FfiUDMFUniformTypeDescriptorGetTypeDescriptor(const char *typeId); + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetUniformDataTypeByFilenameExtension + (const char *cFilenameExtension, const char *cBelongsTo); + FFI_EXPORT char *FfiUDMFUniformTypeDescriptorGetUniformDataTypeByMIMEType + (const char *cMimeType, const char *cBelongsTo); +} +} +} + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/uniform_type_descriptor_impl.h b/udmf/interfaces/cj/include/uniform_type_descriptor_impl.h new file mode 100644 index 00000000..4a9a6dc7 --- /dev/null +++ b/udmf/interfaces/cj/include/uniform_type_descriptor_impl.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UNIFORM_TYPE_DESCRIPTOR_IMPL_H +#define UDMF_UNIFORM_TYPE_DESCRIPTOR_IMPL_H + +#include <memory> + +#include "uniform_type_descriptor_ffi.h" +#include "type_descriptor.h" +#include "cj_common_ffi.h" +#include "udmf_log.h" + +namespace OHOS { +namespace UDMF { + using namespace OHOS::UDMF; + int64_t GetTypeDescriptor(const char *typeId); + char *GetUniformDataTypeByFilenameExtension(const char *cFilenameExtension, const char *cBelongsTo); + char *GetUniformDataTypeByMIMEType(const char *cMimeType, const char *cBelongsTo); +} +} // namespace OHOS::UDMF + +#endif \ No newline at end of file diff --git a/udmf/interfaces/cj/include/utils.h b/udmf/interfaces/cj/include/utils.h new file mode 100644 index 00000000..727d426e --- /dev/null +++ b/udmf/interfaces/cj/include/utils.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_UDMF_UTILS_H +#define OHOS_UDMF_UTILS_H + +#include <cstdint> +#include <memory> +#include <string> +#include <vector> +#include "cj_common_ffi.h" + +#define FFI_EXPORT __attribute__((visibility("default"))) + +class FFI_EXPORT Utils { + public: + static char *MallocCString(const std::string &origin); + static CArrString StringVectorToArray(std::vector<std::string> vector); +}; +#endif // OHOS_UDMF_UTILS_H \ No newline at end of file diff --git a/udmf/interfaces/cj/src/type_descriptor_ffi.cpp b/udmf/interfaces/cj/src/type_descriptor_ffi.cpp new file mode 100644 index 00000000..a5afb68a --- /dev/null +++ b/udmf/interfaces/cj/src/type_descriptor_ffi.cpp @@ -0,0 +1,144 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "type_descriptor_ffi.h" +#include "type_descriptor_impl.h" +#include "cj_common_ffi.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { +extern "C" { + + char *FfiUDMFUniformTypeDescriptorGetTypeId(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return nullptr; + } + + return data->GetTypeId(); + } + + CArrString FfiUDMFUniformTypeDescriptorGetBelongingToTypes(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return CArrString{}; + } + + return data->GetBelongingToTypes(); + } + + char *FfiUDMFUniformTypeDescriptorGetDescription(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return nullptr; + } + + return data->GetDescription(); + } + + char *FfiUDMFUniformTypeDescriptorGetReferenceURL(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return nullptr; + } + + return data->GetReferenceURL(); + } + + char *FfiUDMFUniformTypeDescriptorGetIconFile(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return nullptr; + } + + return data->GetIconFile(); + } + + CArrString FfiUDMFUniformTypeDescriptorGetFilenameExtensions(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return CArrString{}; + } + + return data->GetFilenameExtensions(); + } + + CArrString FfiUDMFUniformTypeDescriptorGetMimeTypes(int64_t typeDescriptorID) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return CArrString{}; + } + + return data->GetMimeTypes(); + } + + bool FfiUDMFUniformTypeDescriptorBelongsTo(int64_t typeDescriptorID, const char *type) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return false; + } + + return data->BelongsTo(type); + } + + bool FfiUDMFUniformTypeDescriptorIsLowerLevelType(int64_t typeDescriptorID, const char *type) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return false; + } + + return data->IsLowerLevelType(type); + } + + bool FfiUDMFUniformTypeDescriptorIsHigherLevelType(int64_t typeDescriptorID, const char *type) + { + auto data = FFIData::GetData<CTypeDescriptor>(typeDescriptorID); + if (data == nullptr) { + return false; + } + + return data->IsHigherLevelType(type); + } + + bool FfiUDMFUniformTypeDescriptorEquals(int64_t thisTypeDescriptorID, int64_t thatTypeDescriptorID) + { + auto thisTypeDescriptor = FFIData::GetData<CTypeDescriptor>(thisTypeDescriptorID); + if (thisTypeDescriptor == nullptr) { + return false; + } + + auto thatTypeDescriptor = FFIData::GetData<CTypeDescriptor>(thatTypeDescriptorID); + if (thatTypeDescriptor == nullptr) { + return false; + } + + return thisTypeDescriptor->Equals(thatTypeDescriptor); + } +} +} +} diff --git a/udmf/interfaces/cj/src/type_descriptor_impl.cpp b/udmf/interfaces/cj/src/type_descriptor_impl.cpp new file mode 100644 index 00000000..c95e5fe8 --- /dev/null +++ b/udmf/interfaces/cj/src/type_descriptor_impl.cpp @@ -0,0 +1,114 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "type_descriptor_ffi.h" +#include "type_descriptor_impl.h" +#include "cj_common_ffi.h" +#include "type_descriptor.h" + +#include <string> +#include <vector> + +#include "ffi_remote_data.h" + +#include "utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { + CTypeDescriptor::CTypeDescriptor(std::shared_ptr<UDMF::TypeDescriptor> typeDescriptor) + { + typeDescriptor_ = typeDescriptor; + } + + char *CTypeDescriptor::GetTypeId() + { + std::string ret = typeDescriptor_->GetTypeId(); + return Utils::MallocCString(ret); + } + + CArrString CTypeDescriptor::GetBelongingToTypes() + { + std::vector<std::string> types = typeDescriptor_->GetBelongingToTypes(); + return Utils::StringVectorToArray(types); + } + + char *CTypeDescriptor::GetDescription() + { + std::string ret = typeDescriptor_->GetDescription(); + return Utils::MallocCString(ret); + } + + char *CTypeDescriptor::GetIconFile() + { + std::string ret = typeDescriptor_->GetIconFile(); + return Utils::MallocCString(ret); + } + + char *CTypeDescriptor::GetReferenceURL() + { + std::string ret = typeDescriptor_->GetReferenceURL(); + return Utils::MallocCString(ret); + } + + CArrString CTypeDescriptor::GetFilenameExtensions() + { + std::vector<std::string> types = typeDescriptor_->GetFilenameExtensions(); + return Utils::StringVectorToArray(types); + } + + CArrString CTypeDescriptor::GetMimeTypes() + { + std::vector<std::string> types = typeDescriptor_->GetMimeTypes(); + return Utils::StringVectorToArray(types); + } + + + bool CTypeDescriptor::BelongsTo(const char *type) + { + bool result = false; + typeDescriptor_->BelongsTo(type, result); + return result; + } + + bool CTypeDescriptor::IsLowerLevelType(const char *type) + { + bool result = false; + typeDescriptor_->IsLowerLevelType(type, result); + return result; + } + + bool CTypeDescriptor::IsHigherLevelType(const char *type) + { + bool result = false; + typeDescriptor_->IsHigherLevelType(type, result); + return result; + } + + const std::shared_ptr<UDMF::TypeDescriptor> &CTypeDescriptor::GetTypeDescriptor() const + { + return typeDescriptor_; + } + + bool CTypeDescriptor::Equals(CTypeDescriptor* thatCTypeDescriptor) + { + return typeDescriptor_->Equals(thatCTypeDescriptor->GetTypeDescriptor()); + } + +} +} diff --git a/udmf/interfaces/cj/src/unified_data_ffi.cpp b/udmf/interfaces/cj/src/unified_data_ffi.cpp new file mode 100644 index 00000000..6cf4c519 --- /dev/null +++ b/udmf/interfaces/cj/src/unified_data_ffi.cpp @@ -0,0 +1,98 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "unified_data_ffi.h" +#include "unified_data_impl.h" +#include "unified_record_impl.h" +#include "cj_common_ffi.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { +extern "C" { + + int64_t FfiUDMFUnifiedDataConstructor() + { + auto nativeCJUnifiedData = FFIData::Create<CUnifiedData>(); + if (nativeCJUnifiedData == nullptr) { + return -1; + } + return nativeCJUnifiedData->GetID(); + } + + int64_t FfiUDMFUnifiedDataConstructorWithRecord(int64_t unifiedRecordId) + { + auto record = FFIData::GetData<CUnifiedRecord>(unifiedRecordId); + if (record == nullptr) { + return -1; + } + + auto nativeCJUnifiedData = FFIData::Create<CUnifiedData>(record); + if (nativeCJUnifiedData == nullptr) { + return -1; + } + return nativeCJUnifiedData->GetID(); + } + + void FfiUDMFUnifiedDataAddRecord(int64_t unifiedDataId, int64_t unifiedRecordId) + { + auto record = FFIData::GetData<CUnifiedRecord>(unifiedRecordId); + if (record == nullptr) { + return; + } + + auto data = FFIData::GetData<CUnifiedData>(unifiedDataId); + if (data == nullptr) { + return; + } + + data->AddRecord(record); + } + + CArrUnifiedRecord FfiUDMFUnifiedDataGetRecords(int64_t unifiedDataId) + { + auto data = FFIData::GetData<CUnifiedData>(unifiedDataId); + if (data == nullptr) { + return CArrUnifiedRecord{}; + } + + return data->GetRecords(); + } + + bool FfiUDMFUnifiedDataHasType(int64_t unifiedDataId, const char *type) + { + auto data = FFIData::GetData<CUnifiedData>(unifiedDataId); + if (data == nullptr) { + return false; + } + + return data->HasType(type); + } + + CArrString FfiUDMFUnifiedDataGetTypes(int64_t unifiedDataId) + { + auto data = FFIData::GetData<CUnifiedData>(unifiedDataId); + if (data == nullptr) { + return CArrString{}; + } + + return data->GetTypes(); + } +} +} +} diff --git a/udmf/interfaces/cj/src/unified_data_impl.cpp b/udmf/interfaces/cj/src/unified_data_impl.cpp new file mode 100644 index 00000000..47ebd4db --- /dev/null +++ b/udmf/interfaces/cj/src/unified_data_impl.cpp @@ -0,0 +1,138 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "unified_data_ffi.h" +#include "unified_data_impl.h" +#include "unified_record_impl.h" +#include "cj_common_ffi.h" +#include <cstdlib> +#include <string> +#include <variant> +#include <vector> +#include <map> +#include <iomanip> + +#include "ffi_remote_data.h" + +#include "application_defined_record_napi.h" +#include "audio_napi.h" +#include "file_napi.h" +#include "folder_napi.h" +#include "html_napi.h" +#include "image_napi.h" +#include "link_napi.h" +#include "napi_data_utils.h" +#include "napi_error_utils.h" +#include "plain_text_napi.h" +#include "system_defined_appitem_napi.h" +#include "system_defined_form_napi.h" +#include "system_defined_pixelmap_napi.h" +#include "system_defined_record_napi.h" +#include "text_napi.h" +#include "unified_data.h" +#include "unified_record_napi.h" +#include "video_napi.h" + +#include "utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { + + CUnifiedData::CUnifiedData() + { + unifiedData_ = std::make_shared<UnifiedData>(); + } + + CUnifiedData::CUnifiedData(UDMF::CUnifiedRecord *record) + { + unifiedData_ = std::make_shared<UnifiedData>(); + + if (record == nullptr) { + return; + } + unifiedData_->AddRecord(record->GetUnifiedRecord()); + this->records_.push_back(record); + } + + void CUnifiedData::AddRecord(UDMF::CUnifiedRecord *record) + { + if (record == nullptr) { + return; + } + this->records_.push_back(record); + unifiedData_->AddRecord(record->GetUnifiedRecord()); + } + + static CArrUnifiedRecord VectorToArray(std::vector<int64_t> vector) + { + if (vector.size() == 0) { + return CArrUnifiedRecord{}; + } + int64_t *head = static_cast<int64_t *>(malloc(vector.size() * sizeof(int64_t))); + if (head == nullptr) { + return CArrUnifiedRecord{}; + } + for (unsigned long i = 0; i < vector.size(); i++) { + head[i] = vector[i]; + } + CArrUnifiedRecord int64Array = {head, vector.size()}; + return int64Array; + } + + CArrUnifiedRecord CUnifiedData::GetRecords() + { + std::vector<int64_t> recordIds; + for (auto record : this->records_) { + if (record == nullptr) { + break; + } + recordIds.push_back(record->GetID()); + } + return VectorToArray(recordIds); + } + + bool CUnifiedData::HasType(const char *type) + { + return unifiedData_->HasType(type); + } + + static CArrString StringVectorToArray(std::vector<std::string> vector) + { + if (vector.size() == 0) { + return CArrString{}; + } + char **head = static_cast<char **>(malloc(vector.size() * sizeof(char *))); + if (head == nullptr) { + return CArrString{}; + } + for (unsigned long i = 0; i < vector.size(); i++) { + head[i] = Utils::MallocCString(vector[i]); + } + CArrString stringArray = {head, vector.size()}; + return stringArray; + } + + CArrString CUnifiedData::GetTypes() + { + std::vector<std::string> types = unifiedData_->GetTypesLabels(); + return StringVectorToArray(types); + } + +} +} diff --git a/udmf/interfaces/cj/src/unified_record_ffi.cpp b/udmf/interfaces/cj/src/unified_record_ffi.cpp new file mode 100644 index 00000000..c2ab6baa --- /dev/null +++ b/udmf/interfaces/cj/src/unified_record_ffi.cpp @@ -0,0 +1,64 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "unified_record_ffi.h" +#include "unified_record_impl.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { +extern "C" { + + int64_t FfiUDMFUnifiedRecordConstructor() + { + auto nativeCJUnifiedRecord = FFIData::Create<CUnifiedRecord>(); + if (nativeCJUnifiedRecord == nullptr) { + return -1; + } + return nativeCJUnifiedRecord->GetID(); + } + + int64_t FfiUDMFUnifiedRecordConstructorwithType(const char *type, CJValueType value) + { + auto nativeCJUnifiedRecord = FFIData::Create<CUnifiedRecord>(type, value); + if (nativeCJUnifiedRecord == nullptr) { + return -1; + } + return nativeCJUnifiedRecord->GetID(); + } + + char *FfiUDMFUnifiedRecordGetType(int64_t unifiedId) + { + auto instance = FFIData::GetData<CUnifiedRecord>(unifiedId); + if (instance == nullptr) { + return nullptr; + } + return instance->GetType(); + } + + CJValueType FfiUDMFUnifiedRecordGetValue(int64_t unifiedId) + { + auto instance = FFIData::GetData<CUnifiedRecord>(unifiedId); + if (instance == nullptr) { + return CJValueType{}; + } + return instance->GetValue(); + } +} +} +} diff --git a/udmf/interfaces/cj/src/unified_record_impl.cpp b/udmf/interfaces/cj/src/unified_record_impl.cpp new file mode 100644 index 00000000..145fd849 --- /dev/null +++ b/udmf/interfaces/cj/src/unified_record_impl.cpp @@ -0,0 +1,208 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "unified_record_ffi.h" +#include "unified_record_impl.h" + +#include <cstdlib> +#include <string> +#include <variant> +#include <vector> +#include <map> +#include <iomanip> +#include "ffi_remote_data.h" + +#include "plain_text.h" +#include "html.h" +#include "link.h" +#include "image.h" +#include "pixel_map_impl.h" +#include "pixel_map.h" + +#include "video.h" +#include "audio.h" +#include "folder.h" +#include "system_defined_appitem.h" +#include "system_defined_form.h" +#include "system_defined_pixelmap.h" +#include "application_defined_record.h" +#include "utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { + static CArrUI8 VectorToByteArray(std::vector<uint8_t> bytes) + { + if (bytes.size() == 0) { + return CArrUI8{}; + } + uint8_t *head = static_cast<uint8_t *>(malloc(bytes.size() * sizeof(uint8_t))); + if (head == nullptr) { + return CArrUI8{}; + } + for (unsigned long i = 0; i < bytes.size(); i++) { + head[i] = bytes[i]; + } + CArrUI8 byteArray = {head, bytes.size()}; + return byteArray; + } + + CJValueType CUnifiedRecord::ValueType2CJValueType(ValueType value) + { + CJValueType cjvalue; + if (auto p = std::get_if<int32_t>(&value)) { + cjvalue.integer32 = *p; + cjvalue.tag = INTEGER32; + } + if (auto p = std::get_if<int64_t>(&value)) { + cjvalue.integer64 = *p; + cjvalue.tag = INTEGER64; + } + if (auto p = std::get_if<double>(&value)) { + cjvalue.dou = *p; + cjvalue.tag = DOUBLE; + } + if (auto p = std::get_if<bool>(&value)) { + cjvalue.boolean = *p; + cjvalue.tag = BOOLEAN; + } + if (auto p = std::get_if<std::string>(&value)) { + cjvalue.string = Utils::MallocCString(*p); + cjvalue.tag = STRING; + } + if (auto p = std::get_if<std::vector<uint8_t>>(&value)) { + cjvalue.byteArray = VectorToByteArray(*p); + cjvalue.tag = BYTEARRAY; + } + if (auto p = std::get_if<std::shared_ptr<OHOS::Media::PixelMap>>(&value)) { + cjvalue.pixelMapId = this->pixelMapId_; + cjvalue.tag = PIXELMAP; + } + + return cjvalue; + } + + ValueType CUnifiedRecord::CJValueType2ValueType(CJValueType cjvalue) + { + ValueType value; + switch (cjvalue.tag) { + case INTEGER32: + value = cjvalue.integer32; + break; + case INTEGER64: + value = cjvalue.integer64; + break; + case DOUBLE: + value = cjvalue.dou; + break; + case BOOLEAN: + value = cjvalue.boolean; + break; + case STRING: + value = cjvalue.string; + break; + case BYTEARRAY: { + std::vector<uint8_t> bytes = std::vector<uint8_t>(); + for (int64_t i = 0; i < cjvalue.byteArray.size; i++) { + bytes.push_back(cjvalue.byteArray.head[i]); + } + value = bytes; + break; + } + + case PIXELMAP: { + auto instance = FFIData::GetData<OHOS::Media::PixelMapImpl>(cjvalue.pixelMapId); + if (instance == nullptr) { + value = -1; + break; + } + value = instance->GetRealPixelMap(); + break; + } + + default: + value = -1; + break; + } + + return value; + } + + CUnifiedRecord::CUnifiedRecord() + { + unifiedRecord_ = std::make_shared<UnifiedRecord>(); + } + + CUnifiedRecord::CUnifiedRecord(const char *type, CJValueType cjvalue) + { + UDType utdType = APPLICATION_DEFINED_RECORD; + if (UtdUtils::IsValidUtdId(type)) { + utdType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(type)); + } + ValueType value = CJValueType2ValueType(cjvalue); + if (cjvalue.tag == PIXELMAP) { + this->pixelMapId_ = cjvalue.pixelMapId; + } + std::map<UDType, std::function<std::shared_ptr<UnifiedRecord>(UDType, ValueType)>> constructors = { + {TEXT, [](UDType type, ValueType value) { return std::make_shared<Text>(type, value); }}, + {PLAIN_TEXT, [](UDType type, ValueType value) { return std::make_shared<PlainText>(type, value); }}, + {HTML, [](UDType type, ValueType value) { return std::make_shared<Html>(type, value); }}, + {HYPERLINK, [](UDType type, ValueType value) { return std::make_shared<Link>(type, value); }}, + {FILE, [](UDType type, ValueType value) { return std::make_shared<File>(type, value); }}, + {IMAGE, [](UDType type, ValueType value) { return std::make_shared<Image>(type, value); }}, + {VIDEO, [](UDType type, ValueType value) { return std::make_shared<Video>(type, value); }}, + {AUDIO, [](UDType type, ValueType value) { return std::make_shared<Audio>(type, value); }}, + {FOLDER, [](UDType type, ValueType value) { return std::make_shared<Folder>(type, value); }}, + {SYSTEM_DEFINED_RECORD, [](UDType type, ValueType value) + { return std::make_shared<SystemDefinedRecord>(type, value); }}, + {SYSTEM_DEFINED_APP_ITEM, [](UDType type, ValueType value) + { return std::make_shared<SystemDefinedAppItem>(type, value); }}, + {SYSTEM_DEFINED_FORM, [](UDType type, ValueType value) + { return std::make_shared<SystemDefinedForm>(type, value); }}, + {SYSTEM_DEFINED_PIXEL_MAP, [](UDType type, ValueType value) + { return std::make_shared<SystemDefinedPixelMap>(type, value); }}, + {APPLICATION_DEFINED_RECORD, [](UDType type, ValueType value) + { return std::make_shared<ApplicationDefinedRecord>(type, value); }}, + }; + auto constructor = constructors.find(utdType); + if (constructor == constructors.end()) { + unifiedRecord_ = std::make_shared<UnifiedRecord>(utdType, value); + return; + } + unifiedRecord_ = constructor->second(utdType, value); + } + + char *CUnifiedRecord::GetType() + { + std::string ret = UtdUtils::GetUtdIdFromUtdEnum(this->unifiedRecord_->GetType()); + return Utils::MallocCString(ret); + } + + CJValueType CUnifiedRecord::GetValue() + { + ValueType value = this->unifiedRecord_->GetValue(); + CJValueType cjvalue = ValueType2CJValueType(value); + return cjvalue; + } + + const std::shared_ptr<UDMF::UnifiedRecord> &CUnifiedRecord::GetUnifiedRecord() const + { + return unifiedRecord_; + } +} +} diff --git a/udmf/interfaces/cj/src/uniform_type_descriptor_ffi.cpp b/udmf/interfaces/cj/src/uniform_type_descriptor_ffi.cpp new file mode 100644 index 00000000..2480f258 --- /dev/null +++ b/udmf/interfaces/cj/src/uniform_type_descriptor_ffi.cpp @@ -0,0 +1,44 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "uniform_type_descriptor_ffi.h" +#include "uniform_type_descriptor_impl.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { +extern "C" { + + int64_t FfiUDMFUniformTypeDescriptorGetTypeDescriptor(const char *typeId) + { + return UDMF::GetTypeDescriptor(typeId); + } + + char *FfiUDMFUniformTypeDescriptorGetUniformDataTypeByFilenameExtension( + const char *cFilenameExtension, const char *cBelongsTo) + { + return UDMF::GetUniformDataTypeByFilenameExtension(cFilenameExtension, cBelongsTo); + } + + char *FfiUDMFUniformTypeDescriptorGetUniformDataTypeByMIMEType(const char *cMimeType, const char *cBelongsTo) + { + return UDMF::GetUniformDataTypeByMIMEType(cMimeType, cBelongsTo); + } +} +} +} diff --git a/udmf/interfaces/cj/src/uniform_type_descriptor_impl.cpp b/udmf/interfaces/cj/src/uniform_type_descriptor_impl.cpp new file mode 100644 index 00000000..b80d7cb9 --- /dev/null +++ b/udmf/interfaces/cj/src/uniform_type_descriptor_impl.cpp @@ -0,0 +1,98 @@ + +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "uniform_type_descriptor_impl.h" +#include "cj_common_ffi.h" + +#include <string> +#include <vector> +#include "utd_client.h" +#include "type_descriptor_impl.h" + +#include "ffi_remote_data.h" + +#include "utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::UDMF; + +namespace OHOS { +namespace UDMF { + int64_t GetTypeDescriptor(const char *typeId) + { + std::shared_ptr<TypeDescriptor> descriptor; + UtdClient::GetInstance().GetTypeDescriptor(typeId, descriptor); + if (descriptor == nullptr) { + return -1; + } + auto nativeCJTypeDescriptor = FFIData::Create<CTypeDescriptor>(descriptor); + if (nativeCJTypeDescriptor == nullptr) { + return -1; + } + return nativeCJTypeDescriptor->GetID(); + } + + + char *GetUniformDataTypeByFilenameExtension(const char *cFilenameExtension, const char *cBelongsTo) + { + std::string belongsTo = cBelongsTo; + std::string typeId; + auto status = E_OK; + if (belongsTo.empty()) { + LOGI("call GetUniformDataTypeByFilenameExtension with not cBelongsTo") + status = UtdClient::GetInstance().GetUniformDataTypeByFilenameExtension(cFilenameExtension, typeId); + } else { + LOGI("call GetUniformDataTypeByFilenameExtension with cBelongsTo") + status = UtdClient::GetInstance() + .GetUniformDataTypeByFilenameExtension(cFilenameExtension, typeId, belongsTo); + } + if (status != E_OK) { + LOGE("invalid arguments!") + return nullptr; + } + if (!typeId.empty()) { + return Utils::MallocCString(typeId); + } else { + return nullptr; + } + } + + char *GetUniformDataTypeByMIMEType(const char *cMimeType, const char *cBelongsTo) + { + std::string belongsTo = cBelongsTo; + std::string typeId; + auto status = E_OK; + if (belongsTo.empty()) { + LOGI("call GetUniformDataTypeByMIMEType with not cBelongsTo") + status = UtdClient::GetInstance().GetUniformDataTypeByMIMEType(cMimeType, typeId); + } else { + LOGI("call GetUniformDataTypeByMIMEType with cBelongsTo") + status = UtdClient::GetInstance().GetUniformDataTypeByMIMEType(cMimeType, typeId, belongsTo); + } + if (status != E_OK) { + LOGE("invalid arguments!") + return nullptr; + } + if (!typeId.empty()) { + return Utils::MallocCString(typeId); + } else { + return nullptr; + } + } + +} +} diff --git a/udmf/interfaces/cj/src/utils.cpp b/udmf/interfaces/cj/src/utils.cpp new file mode 100644 index 00000000..ce763896 --- /dev/null +++ b/udmf/interfaces/cj/src/utils.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" + +char* Utils::MallocCString(const std::string& origin) +{ + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char* res = static_cast<char*>(malloc(sizeof(char) * len)); + if (res == nullptr) { + return nullptr; + } + return std::char_traits<char>::copy(res, origin.c_str(), len); +} + +CArrString Utils::StringVectorToArray(std::vector<std::string> vector) +{ + if (vector.size() == 0) { + return CArrString{}; + } + char **head = static_cast<char **>(malloc(vector.size() * sizeof(char *))); + if (head == nullptr) { + return CArrString{}; + } + for (unsigned long i = 0; i < vector.size(); i++) { + head[i] = Utils::MallocCString(vector[i]); + } + CArrString stringArray = {head, vector.size()}; + return stringArray; +} \ No newline at end of file diff --git a/udmf/interfaces/innerkits/BUILD.gn b/udmf/interfaces/innerkits/BUILD.gn index fba7873d..1bca5736 100644 --- a/udmf/interfaces/innerkits/BUILD.gn +++ b/udmf/interfaces/innerkits/BUILD.gn @@ -60,6 +60,7 @@ ohos_shared_library("udmf_client") { "${udmf_framework_path}/innerkitsimpl/common/unified_key.cpp", "${udmf_framework_path}/innerkitsimpl/common/unified_meta.cpp", "${udmf_framework_path}/innerkitsimpl/convert/ndk_data_conversion.cpp", + "${udmf_framework_path}/innerkitsimpl/convert/udmf_conversion.cpp", "${udmf_framework_path}/innerkitsimpl/data/application_defined_record.cpp", "${udmf_framework_path}/innerkitsimpl/data/audio.cpp", "${udmf_framework_path}/innerkitsimpl/data/file.cpp", diff --git a/udmf/interfaces/innerkits/common/unified_meta.h b/udmf/interfaces/innerkits/common/unified_meta.h index 1a3fc65e..db165b1d 100644 --- a/udmf/interfaces/innerkits/common/unified_meta.h +++ b/udmf/interfaces/innerkits/common/unified_meta.h @@ -32,7 +32,7 @@ namespace OHOS { namespace UDMF { constexpr const char* UNIFORM_DATA_TYPE = "uniformDataType"; -constexpr const char* CONTENT = "content"; +constexpr const char* CONTENT = "textContent"; constexpr const char* ABSTRACT = "abstract"; constexpr const char* URL = "url"; constexpr const char* DESCRIPTION = "description"; @@ -44,13 +44,20 @@ constexpr const char* APP_ICON_ID = "appIconId"; constexpr const char* APP_LABEL_ID = "appLabelId"; constexpr const char* BUNDLE_NAME = "bundleName"; constexpr const char* ABILITY_NAME = "abilityName"; -constexpr const char* FILE_URI_PARAM = "fileUri"; +constexpr const char* FILE_URI_PARAM = "oriUri"; constexpr const char* FILE_TYPE = "fileType"; constexpr const char* PIXEL_MAP = "pixelMap"; -constexpr const char* APPLICATION_DEFINED_TYPE = "ApplicationDefined"; constexpr const char* ARRAY_BUFFER = "arrayBuffer"; constexpr const char* ARRAY_BUFFER_LENGTH = "arrayBufferLen"; - +constexpr static const char *FORMID = "formId"; +constexpr static const char *FORMNAME = "formName"; +constexpr static const char *MODULE = "module"; +constexpr static const char *BUNDLENAME = "bundleName"; +constexpr static const char *ABILITYNAME = "abilityName"; +constexpr static const char *ORI_URI = "oriUri"; +constexpr static const char *REMOTE_URI = "remoteUri"; +constexpr static const char *APPLICATION_DEFINED_TYPE = "applicationDefinedType"; +constexpr static const char *RAW_DATA = "rawData"; enum UDType : int32_t { ENTITY = 0, @@ -472,6 +479,8 @@ enum UDType : int32_t { OPENHARMONY_APP, HMOS_WIFI, TEL, + ETS, + JSON5, UD_BUTT }; @@ -551,8 +560,16 @@ using ValueType = std::variant<std::monostate, int32_t, int64_t, double, bool, s std::shared_ptr<OHOS::AAFwk::Want>, std::shared_ptr<OHOS::Media::PixelMap>, std::shared_ptr<Object>, nullptr_t>; struct API_EXPORT Object { - bool GetValue(const std::string &key, std::string &value); - bool GetValue(const std::string &key, std::shared_ptr<Object> &value); + template<typename T> + bool GetValue(const std::string &key, T &value) + { + auto it = value_.find(key); + if (it != value_.end() && std::holds_alternative<T>(it->second)) { + value = std::get<T>(it->second); + return true; + } + return false; + } std::map<std::string, ValueType> value_; }; diff --git a/udmf/interfaces/innerkits/convert/udmf_conversion.h b/udmf/interfaces/innerkits/convert/udmf_conversion.h new file mode 100644 index 00000000..69f9fb45 --- /dev/null +++ b/udmf/interfaces/innerkits/convert/udmf_conversion.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_UDMF_CONVERSION_H +#define UDMF_UDMF_CONVERSION_H + +#include "unified_data.h" +#include "visibility.h" + +namespace OHOS::UDMF { +class UdmfConversion { +public: + static void API_EXPORT ConvertRecordToSubclass(std::shared_ptr<UnifiedRecord> &record); + static void API_EXPORT ConvertRecordToSubclass(UnifiedData &data); + static void API_EXPORT ConvertRecordToSubclass(std::vector<UnifiedData> &datas); + + static void API_EXPORT InitValueObject(UnifiedData &data); + static void API_EXPORT InitValueObject(std::vector<UnifiedData> &datas); + +private: + static void SetValueWhenNotUds(std::shared_ptr<UnifiedRecord> record); +}; +} + +#endif // UDMF_UDMF_CONVERSION_H diff --git a/udmf/interfaces/innerkits/data/application_defined_record.h b/udmf/interfaces/innerkits/data/application_defined_record.h index cb32d456..845a745a 100644 --- a/udmf/interfaces/innerkits/data/application_defined_record.h +++ b/udmf/interfaces/innerkits/data/application_defined_record.h @@ -34,6 +34,8 @@ public: std::vector<uint8_t> GetRawData() const; void SetRawData(const std::vector<uint8_t> &rawData); + + void InitObject() override; protected: std::string applicationDefinedType; std::vector<uint8_t> rawData_; diff --git a/udmf/interfaces/innerkits/data/file.h b/udmf/interfaces/innerkits/data/file.h index 57ae3b39..55156bf0 100644 --- a/udmf/interfaces/innerkits/data/file.h +++ b/udmf/interfaces/innerkits/data/file.h @@ -35,6 +35,7 @@ public: void SetDetails(UDDetails &variantMap); UDDetails GetDetails() const; + void InitObject() override; protected: std::string oriUri_; diff --git a/udmf/interfaces/innerkits/data/html.h b/udmf/interfaces/innerkits/data/html.h index e6d24278..67f9feab 100644 --- a/udmf/interfaces/innerkits/data/html.h +++ b/udmf/interfaces/innerkits/data/html.h @@ -33,11 +33,10 @@ public: void SetHtmlContent(const std::string &htmlContent); std::string GetPlainContent() const; void SetPlainContent(const std::string &htmlContent); - ValueType GetValue() override; + void InitObject() override; static bool CheckValue(const ValueType &value); private: - void InitObject(); constexpr static const char *HTML_CONTENT = "htmlContent"; constexpr static const char *PLAINT_CONTENT = "plainContent"; std::string htmlContent_; diff --git a/udmf/interfaces/innerkits/data/link.h b/udmf/interfaces/innerkits/data/link.h index 75825b46..9d76d7df 100644 --- a/udmf/interfaces/innerkits/data/link.h +++ b/udmf/interfaces/innerkits/data/link.h @@ -34,11 +34,10 @@ public: void SetUrl(const std::string &url); std::string GetDescription() const; void SetDescription(const std::string &description); - ValueType GetValue() override; + void InitObject() override; static bool CheckValue(const ValueType &value); private: - void InitObject(); constexpr static const char *URL = "url"; constexpr static const char *DESCRIPTION = "description"; diff --git a/udmf/interfaces/innerkits/data/plain_text.h b/udmf/interfaces/innerkits/data/plain_text.h index 712cba05..b0d81ccd 100644 --- a/udmf/interfaces/innerkits/data/plain_text.h +++ b/udmf/interfaces/innerkits/data/plain_text.h @@ -32,11 +32,10 @@ public: void SetContent(const std::string &content); std::string GetAbstract() const; void SetAbstract(const std::string &abstract); - ValueType GetValue() override; + void InitObject() override; static bool CheckValue(const ValueType &value); private: - void InitObject(); constexpr static const char *TEXT_CONTENT = "textContent"; constexpr static const char *ABSTRACT = "abstract"; std::string content_; diff --git a/udmf/interfaces/innerkits/data/system_defined_appitem.h b/udmf/interfaces/innerkits/data/system_defined_appitem.h index fad64989..962e8508 100644 --- a/udmf/interfaces/innerkits/data/system_defined_appitem.h +++ b/udmf/interfaces/innerkits/data/system_defined_appitem.h @@ -42,11 +42,10 @@ public: void SetAbilityName(const std::string &abilityName); void SetItems(UDDetails &details); UDDetails GetItems(); - ValueType GetValue() override; + void InitObject() override; static bool CheckValue(const ValueType &value); private: - void InitObject(); constexpr static const char *APPID = "appId"; constexpr static const char *APPNAME = "appName"; constexpr static const char *APPICONID = "appIconId"; diff --git a/udmf/interfaces/innerkits/data/system_defined_form.h b/udmf/interfaces/innerkits/data/system_defined_form.h index 9f634c76..7ce952ce 100644 --- a/udmf/interfaces/innerkits/data/system_defined_form.h +++ b/udmf/interfaces/innerkits/data/system_defined_form.h @@ -41,6 +41,8 @@ public: void SetItems(UDDetails &details); UDDetails GetItems(); + void InitObject() override; + private: int32_t formId_{-1}; std::string formName_; @@ -48,11 +50,6 @@ private: std::string abilityName_; std::string module_; - constexpr static const char *FORMID = "formId"; - constexpr static const char *FORMNAME = "formName"; - constexpr static const char *MODULE = "module"; - constexpr static const char *BUNDLENAME = "bundleName"; - constexpr static const char *ABILITYNAME = "abilityName"; }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/data/system_defined_pixelmap.h b/udmf/interfaces/innerkits/data/system_defined_pixelmap.h index f505f48a..04f59351 100644 --- a/udmf/interfaces/innerkits/data/system_defined_pixelmap.h +++ b/udmf/interfaces/innerkits/data/system_defined_pixelmap.h @@ -31,11 +31,9 @@ public: std::vector<uint8_t> GetRawData() const; void SetRawData(const std::vector<uint8_t> &rawData); - ValueType GetValue() override; + void InitObject() override; private: - void InitObject(); std::vector<uint8_t> rawData_; - bool updateObjectFlag_ = true; }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/data/system_defined_record.h b/udmf/interfaces/innerkits/data/system_defined_record.h index 7fda2e51..010352a0 100644 --- a/udmf/interfaces/innerkits/data/system_defined_record.h +++ b/udmf/interfaces/innerkits/data/system_defined_record.h @@ -32,10 +32,10 @@ public: void SetDetails(UDDetails &details); UDDetails GetDetails() const; + void InitObject() override; + protected: UDDetails details_; -private: - void InitObject(); }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/data/text.h b/udmf/interfaces/innerkits/data/text.h index 3f0854ba..fcb10608 100644 --- a/udmf/interfaces/innerkits/data/text.h +++ b/udmf/interfaces/innerkits/data/text.h @@ -32,10 +32,10 @@ public: void SetDetails(UDDetails &variantMap); UDDetails GetDetails() const; + void InitObject() override; + protected: UDDetails details_; -private: - void InitObject(); }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/data/unified_record.h b/udmf/interfaces/innerkits/data/unified_record.h index 78387e5f..d8d4b677 100644 --- a/udmf/interfaces/innerkits/data/unified_record.h +++ b/udmf/interfaces/innerkits/data/unified_record.h @@ -38,9 +38,9 @@ public: std::string GetUid() const; void SetUid(const std::string &id); - virtual ValueType GetValue(); + ValueType GetValue(); void SetValue(const ValueType &value); - ValueType GetOriginValue(); + ValueType GetOriginValue() const; void SetUtdId(const std::string &utdId); std::set<std::string> GetUtdIds() const; @@ -58,11 +58,15 @@ public: void SetRecordId(uint32_t recordId); uint32_t GetRecordId() const; void SetChannelName(const std::string &channelName); + + virtual void InitObject(); + bool HasObject(); protected: static constexpr const char *UNIFORM_DATA_TYPE = "uniformDataType"; static constexpr const char *DETAILS = "details"; UDType dataType_; ValueType value_; + bool hasObject_ = false; private: std::string uid_; // unique identifier std::string utdId_; -- Gitee