diff --git a/BUILD.gn b/BUILD.gn index f25102073259ae5ace6ff0d0de23f748d5e7d495..e759bcf16d04461c11e7fd8a5e1e3a62a2a33be3 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -29,6 +29,9 @@ group("fuzztest") { testonly = true deps = [] deps += [ + "services/distributeddataservice/adapter/test:fuzztest", + "services/distributeddataservice/app/test/fuzztest:fuzztest", + "services/distributeddataservice/service/test/fuzztest:fuzztest", "test/fuzztest/autolaunch_fuzzer:fuzztest", "test/fuzztest/kvstoredisksize_fuzzer:fuzztest", ] diff --git a/bundle.json b/bundle.json index a5d2bd57f46cd728cf4daf6c2b3815ea71863c93..1d4318ba4667304b6361a6b69fca1f599dd1a3b0 100644 --- a/bundle.json +++ b/bundle.json @@ -1,6 +1,6 @@ { - "name": "@ohos/distributeddatamgr_datamgr_service", - "version": "1.0.0", + "name": "@ohos/datamgr_service", + "version": "3.2.0", "description": "Distributed data manager that provides the capability to store data in the databases of different devices", "homePage": "https://gitee.com/openharmony", "license": "Apache V2", @@ -37,51 +37,54 @@ "component": { "name": "datamgr_service", "subsystem": "distributeddatamgr", - "syscap": [ - "SystemCapability.DistributedDataManager.KVStore.Core", - "SystemCapability.DistributedDataManager.KVStore.Lite", - "SystemCapability.DistributedDataManager.KVStore.DistributedKVStore" + "syscap": [], + "features": [ + "datamgr_service_config", + "datamgr_service_udmf" ], - "features": [], "adapted_system_type": [ "standard" ], - "rom": "", - "ram": "", + "rom": "5120KB", + "ram": "8192KB", "hisysevent_config": [ "//foundation/distributeddatamgr/datamgr_service/hisysevent.yaml" ], "deps": { "components": [ - "libuv", - "common_event_service", + "ability_base", + "ability_runtime", + "access_token", "bundle_framework", - "safwk", - "zlib", - "init", - "os_account", - "common", - "samgr", + "common_event_service", + "c_utils", "dataclassification", + "data_share", + "device_auth", + "device_manager", "dsoftbus", - "jsoncpp", - "hitrace_native", - "access_token", + "hilog", + "hisysevent", + "hitrace", "huks", - "ability_base", - "ability_runtime", - "hiviewdfx_hilog_native", - "hisysevent_native", - "device_auth", + "kv_store", "ipc", - "napi" + "napi", + "netmanager_base", + "os_account", + "relational_store", + "safwk", + "samgr", + "udmf", + "app_file_service" ], "third_party": [ - "uv_static", - "sqlite", - "libz", + "cJSON", "jsoncpp", - "libcrypto_shared" + "libuv", + "openssl", + "sqlite", + "zlib" ] }, "build": { @@ -90,7 +93,7 @@ "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:build_module", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:build_module", "//foundation/distributeddatamgr/datamgr_service/conf:build_module", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd:build_module" + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share:build_module" ], "inner_kits": [], "test": [ @@ -100,4 +103,4 @@ ] } } -} +} \ No newline at end of file diff --git a/conf/BUILD.gn b/conf/BUILD.gn index 0e9037c6ca75d87b2bdce081d72354b9cef3578a..330b9f2e540eb9278a1d63e70275ef8998353504 100644 --- a/conf/BUILD.gn +++ b/conf/BUILD.gn @@ -12,10 +12,13 @@ # limitations under the License. import("//build/ohos.gni") import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") #/system/etc/distributeddata/conf group("build_module") { - deps = [ ":default_conf" ] + if (datamgr_service_config) { + deps = [ ":default_conf" ] + } } ohos_prebuilt_etc("default_conf") { source = "config.json" diff --git a/conf/config.json b/conf/config.json index 6f13c2cfcfe47725217790225733da2c79e931f0..cf89a760cce8d5244f042aaa87bb079439377234 100644 --- a/conf/config.json +++ b/conf/config.json @@ -20,6 +20,9 @@ }, { "lib": "libudmf_server.z.so" + }, + { + "lib": "libdata_share_service.z.so" } ], "bundleChecker": { diff --git a/datamgr_service.gni b/datamgr_service.gni index 6ec402a19d78db68d0e97b6f7d131cf7793fb8c7..8a79ca9d5b6d22f91f6738d40eaec26184c2f89d 100644 --- a/datamgr_service.gni +++ b/datamgr_service.gni @@ -15,6 +15,11 @@ distributedfilejs_path = "//foundation/distributeddatamgr/distributedfile" kv_store_path = "//foundation/distributeddatamgr/kv_store" +relational_store_path = "//foundation/distributeddatamgr/relational_store" + +relational_store_inner_api_path = + "${relational_store_path}/interfaces/inner_api/rdb" + kv_store_common_path = "${kv_store_path}/frameworks/common" kv_store_distributeddb_path = "${kv_store_path}/frameworks/libs/distributeddb" @@ -26,6 +31,15 @@ datashare_path = "//foundation/distributeddatamgr/data_share" ipc_core_path = "//foundation/communication/ipc/interfaces/innerkits/ipc_core" device_manager_path = "//foundation/distributedhardware/device_manager" + +file_service_path = "//foundation/filemanagement/app_file_service" + +data_service_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice" + +udmf_path = "//foundation/distributeddatamgr/udmf" + +dataobject_path = "//foundation/distributeddatamgr/data_object" + declare_args() { datamgr_service_power = true if (!defined(global_parts_info.power_manager_native_powermgr_client) || @@ -39,4 +53,8 @@ declare_args() { } else { os_account_part_is_enabled = false } + + datamgr_service_config = true + + datamgr_service_udmf = false } diff --git a/hisysevent.yaml b/hisysevent.yaml index 44a9a78521497dfb3ebf5c234c75af515d119e48..daba8439e4ebde010512cf18fda59d089653d055 100644 --- a/hisysevent.yaml +++ b/hisysevent.yaml @@ -100,6 +100,15 @@ DATABASE_BEHAVIOUR: STORE_ID: {type: STRING, desc: store id } BEHAVIOUR_INFO: {type: STRING, desc: behaviour type and behaviour resulte } +UDMF_DATA_BEHAVIOR: + __BASE: {type: BEHAVIOR, level: MINOR, desc: The event is behaviour record } + APP_ID: {type: STRING, desc: app id } + CHANNEL: {type: STRING, desc: channel name } + DATA_SIZE: {type: INT64, desc: data size } + DATA_TYPE: {type: STRING, desc: data type } + OPERATION: {type: STRING, desc: data operation } + RESULT: {type: STRING, desc: data operation result } + OPEN_DATABASE_FAILED: __BASE: {type: FAULT, level: CRITICAL, desc: The database open failed} APP_ID: {type: STRING, desc: app id } diff --git a/services/distributeddataservice/adapter/BUILD.gn b/services/distributeddataservice/adapter/BUILD.gn index caf33746307011a6462dbd1bc5b0a7808a018813..7c5cebe19fb10d5e8bf84fe7331ae29a4506b575 100644 --- a/services/distributeddataservice/adapter/BUILD.gn +++ b/services/distributeddataservice/adapter/BUILD.gn @@ -45,7 +45,6 @@ ohos_shared_library("distributeddata_adapter") { configs = [ ":distributeddata_adapter_private_config" ] deps = [ "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/account:distributeddata_account_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/autils:distributeddata_autils_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/dfx:distributeddata_dfx_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/permission:distributeddata_permission_static", @@ -53,10 +52,10 @@ ohos_shared_library("distributeddata_adapter") { external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hitrace_native:libhitracechain", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", ] public_configs = [ ":distributeddata_adapter_public_config" ] diff --git a/services/distributeddataservice/adapter/account/BUILD.gn b/services/distributeddataservice/adapter/account/BUILD.gn index d2a449b8a939396f56c8312e7b37be02b0a74aac..e94286519f5542a49a1bf6e0103624d8e99426fd 100755 --- a/services/distributeddataservice/adapter/account/BUILD.gn +++ b/services/distributeddataservice/adapter/account/BUILD.gn @@ -42,7 +42,7 @@ ohos_static_library("distributeddata_account_static") { "ability_base:want", "c_utils:utils", "common_event_service:cesfwk_innerkits", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", ] if (os_account_part_is_enabled) { diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp index 7284cca5de2629bc2ae1201f88ce5b9510e6f9e5..875a2ca3dd7af2943c3b408e66aabacbfc59d6c3 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp @@ -16,11 +16,8 @@ #define LOG_TAG "EVENT_HANDLER" #include "account_delegate_impl.h" -#include #include #include -#include -#include "constant.h" namespace OHOS { namespace DistributedKv { diff --git a/services/distributeddataservice/adapter/account/test/BUILD.gn b/services/distributeddataservice/adapter/account/test/BUILD.gn index fa8c3d6edc219124ea89d6af7383eaf84476a4bd..34a2846e3514bf12d2a036ca9fad7ea2f7bdae4e 100755 --- a/services/distributeddataservice/adapter/account/test/BUILD.gn +++ b/services/distributeddataservice/adapter/account/test/BUILD.gn @@ -38,7 +38,7 @@ ohos_unittest("AccountDelegateTest") { "ability_base:want", "bundle_framework:appexecfwk_base", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] diff --git a/services/distributeddataservice/adapter/autils/src/constant.cpp b/services/distributeddataservice/adapter/autils/src/constant.cpp deleted file mode 100644 index f393d354c1666d9eb528a76c6f95a0e5898dcef4..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/autils/src/constant.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "constant.h" -#include -#include -#include - -namespace OHOS { -namespace DistributedKv { -// the Key Prefix for Meta data of KvStore. -const std::string KvStoreMetaRow::KEY_PREFIX = "KvStoreMetaData"; - -const std::string SecretMetaRow::KEY_PREFIX = "SecretKey"; - -/* version for distributed kv data service. */ -const std::string Constant::VERSION = "1"; - -/* meta name for distributed kv data service. */ -const std::string Constant::META_DIR_NAME = "Meta"; - -/* name for distributed kv data service. */ -const std::string Constant::SERVICE_NAME = "mdds"; - -/* root path for distributed kv data service. */ -const std::string Constant::ROOT_PATH = "/data/misc_de/0"; - -/* root path for distributeddata service and system services. */ -const std::string Constant::ROOT_PATH_DE = "/data/misc_de/0"; - -/* root path for self-developed and non-self-developed app. */ -const std::string Constant::ROOT_PATH_CE = "/data/misc_ce/0"; - -// the max length for key is 1024. -const size_t Constant::MAX_KEY_LENGTH = 1024; - -// the max length for StoreId is 128. -const size_t Constant::MAX_STORE_ID_LENGTH = 128; - -// the max length for value is 4M. -const size_t Constant::MAX_VALUE_LENGTH = 4 * 1024 * 1024; - -// the max batch for putBatch is 128. -const size_t Constant::MAX_BATCH_SIZE = 128; - -// the max capacity for ipc is 800K. -const size_t Constant::MAX_IPC_CAPACITY = 800 * 1024; - -// the default mode is 0755, stands for r/w/x for user, r/x for group, r/x for others. -const mode_t Constant::DEFAULT_MODE = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - -// the mode for dir is 0755, r/w/x for user, r/-/x for group, r/-/x for others. -const mode_t Constant::DEFAULT_MODE_DIR = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - -// the mode for file is 0600, r/w/- for user, -/-/- for group, -/-/- for others. -const mode_t Constant::DEFAULT_MODE_FILE = S_IRUSR | S_IWUSR; - -// Size threshold of switching to large data is a little smaller than MAX_IPC_CAPACITY. -const int Constant::SWITCH_RAW_DATA_SIZE = 700 * 1024; - -const int Constant::MAX_OPEN_KVSTORES = 16; - -// default group id for synchronization. -const std::string Constant::DEFAULT_GROUP_ID = "default"; - -// true indicates the ownership of distributed data is DEVICE, otherwise, ACCOUNT -const bool Constant::STOREID_ONLY_FLAG = true; - -// service meta db name. -const std::string Constant::SERVICE_META_DB_NAME = "service_meta"; - -const std::string Constant::KEY_SEPARATOR = "###"; - -const std::string Constant::ROOT_KEY_GENERATED = "RootKeyGenerated"; - -std::vector KvStoreMetaRow::GetKeyFor(const std::string &key) -{ - std::string str = Constant::Concatenate({KvStoreMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); - return std::vector(str.begin(), str.end()); -} - -std::vector SecretMetaRow::GetKeyFor(const std::string &key) -{ - std::string str = Constant::Concatenate({SecretMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); - return std::vector(str.begin(), str.end()); -} - -std::string Constant::Concatenate(std::initializer_list stringList) -{ - std::string result; - size_t result_size = 0; - for (const std::string &str : stringList) { - result_size += str.size(); - } - result.reserve(result_size); - for (const std::string &str : stringList) { - result.append(str.data(), str.size()); - } - return result; -} - -std::string Constant::GetDefaultDeviceAccountId() -{ - return "0"; -} - -std::string Constant::GetDefaultHarmonyAccountName() -{ - return "default"; -} -} // namespace DistributedKv -} // namespace OHOS diff --git a/services/distributeddataservice/adapter/autils/src/directory_utils.cpp b/services/distributeddataservice/adapter/autils/src/directory_utils.cpp deleted file mode 100644 index b126261064e9204ab9454c9263af7bc1adaf5d12..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/autils/src/directory_utils.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "DirectoryUtils" - -#include "directory_utils.h" -#include -#include -#include "log_print.h" -#include "unistd.h" - -namespace OHOS { -namespace DistributedKv { -// change the mode of all files in the specified directory recursively. -bool DirectoryUtils::ChangeModeFileOnly(const std::string &path, const mode_t &mode) -{ - ZLOGI("begin."); - std::string subPath; - bool ret = true; - DIR *dir = opendir(path.c_str()); - if (dir == nullptr) { - return false; - } - - while (true) { - struct dirent *ptr = readdir(dir); - if (ptr == nullptr) { - break; - } - - // skip current directory and parent directory. - if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { - continue; - } - - subPath = IncludeDelimiterAtPathTail(path) + std::string(ptr->d_name); - if (ptr->d_type == DT_DIR) { - ret = ChangeModeFileOnly(subPath, mode); - continue; - } - - // change the mode of file only. - if ((access(subPath.c_str(), F_OK) == 0) && (ptr->d_type == DT_REG)) { - ZLOGD("[Von-Debug]change the file[%s] to mode[%d].", subPath.c_str(), mode); - if (!ChangeMode(subPath, mode)) { - closedir(dir); - ZLOGD("[Von-Debug]change the file[%s] to mode[%d] failed.", subPath.c_str(), mode); - return false; - } - } - } - closedir(dir); - return ret; -} - -// change the mode of all subdirectories in the specified directory recursively. -bool DirectoryUtils::ChangeModeDirOnly(const std::string &path, const mode_t &mode) -{ - ZLOGI("begin."); - std::string subPath; - bool ret = true; - DIR *dir = opendir(path.c_str()); - if (dir == nullptr) { - return false; - } - - while (true) { - struct dirent *ptr = readdir(dir); - if (ptr == nullptr) { - break; - } - - // skip current directory and parent directory. - if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { - continue; - } - - subPath = IncludeDelimiterAtPathTail(path) + std::string(ptr->d_name); - if (ptr->d_type == DT_DIR) { - ret = ChangeModeDirOnly(subPath, mode); - continue; - } - - // change the mode of directory only. - if ((access(subPath.c_str(), F_OK) == 0) && (ptr->d_type == DT_DIR)) { - ZLOGD("[Von-Debug]change the dir[%s] to mode[%d].", subPath.c_str(), mode); - if (!ChangeMode(subPath, mode)) { - closedir(dir); - ZLOGD("[Von-Debug]change the dir[%s] to mode[%d] failed.", subPath.c_str(), mode); - return false; - } - } - } - closedir(dir); - - std::string currentPath = ExcludeDelimiterAtPathTail(path); - if (access(currentPath.c_str(), F_OK) == 0) { - if (!ChangeMode(currentPath, mode)) { - return false; - } - } - return ret; -} - -// create all subdirectories in the specified directory recursively. -bool DirectoryUtils::CreateDirectory(const std::string &path) -{ - std::string::size_type index = 0; - do { - std::string subPath; - index = path.find('/', index + 1); - if (index == std::string::npos) { - subPath = path; - } else { - subPath = path.substr(0, index); - } - - if (access(subPath.c_str(), F_OK) != 0) { - if (mkdir(subPath.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) { - return false; - } - } - } while (index != std::string::npos); - - return access(path.c_str(), F_OK) == 0; -} - -// exclude separators '/' at the end of the path. -std::string DirectoryUtils::ExcludeDelimiterAtPathTail(const std::string &path) -{ - if (path.rfind('/') != path.size() - 1) { - return path; - } - - if (!path.empty()) { - return path.substr(0, static_cast(path.size()) - 1); - } - - return path; -} - -// include separators '/' at the end of the path. -std::string DirectoryUtils::IncludeDelimiterAtPathTail(const std::string &path) -{ - if (path.rfind('/') != path.size() - 1) { - return path + "/"; - } - - return path; -} -} // namespace DistributedKv -} // namespace OHOS diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.cpp b/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.cpp deleted file mode 100644 index 7a8ad6b835c6a7b1507026f27ba5498ea847bbb8..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "KvStoreThreadPoolImpl" -#include "kv_store_thread_pool_impl.h" - -#include -#include -#include - -#include "kv_store_thread.h" -#include "log_print.h" - -namespace OHOS { -namespace DistributedKv { -KvStoreThreadPoolImpl::~KvStoreThreadPoolImpl() -{ - Stop(); -} - -void KvStoreThreadPoolImpl::Start() -{ - ZLOGI("start"); - running = true; - for (int i = 0; i < threadNum; i++) { - threadList.emplace_back(this, poolName_.substr(0, MAX_THREAD_NAME_SIZE) + "_" + std::to_string(i)); - } -} - -void KvStoreThreadPoolImpl::Stop() -{ - ZLOGW("stop"); - if (!running) { - return; - } - { - std::unique_lock lock(taskListMutex); - running = false; - for (auto task = taskList.begin(); task != taskList.end(); task++) { - ZLOGI("running task in stop()"); - (*task)(); - ZLOGI("running task finish"); - } - taskList.clear(); - } - has_task.notify_all(); - for (auto thread = threadList.begin(); thread != threadList.end(); thread++) { - thread->Join(); - } -} - -bool KvStoreThreadPoolImpl::IsRunning() const -{ - return running; -} - -KvStoreThreadPoolImpl::KvStoreThreadPoolImpl(int threadNum, std::string poolName, bool startImmediately) - : taskList(), threadList(), threadNum(threadNum) -{ - this->poolName_ = poolName; - if (threadNum <= 0 || threadNum > MAX_POOL_SIZE) { - this->threadNum = DEFAULT_POOL_SIZE; - } - if (startImmediately) { - Start(); - } -} - -bool KvStoreThreadPoolImpl::AddTask(KvStoreTask &&task) -{ - ZLOGD("start"); - if (threadList.empty()) { - Start(); - } - std::unique_lock lock(taskListMutex); - if (!running) { - return false; - } - taskList.push_back(std::move(task)); - has_task.notify_one(); - return true; -} - -KvStoreTask KvStoreThreadPoolImpl::ScheduleTask() -{ - std::unique_lock lock(taskListMutex); - if (taskList.empty() && running) { - has_task.wait(lock, [&]() {return !running || !taskList.empty(); }); - } - if (taskList.empty()) { - ZLOGW("taskList empty. schedule empty task(pool stopping?)"); - return KvStoreTask([]() {;}); - } - KvStoreTask ret = std::move(taskList.front()); - taskList.pop_front(); - return ret; -} -} // namespace DistributedKv -} // namespace OHOS diff --git a/services/distributeddataservice/adapter/autils/test/unittest/kv_store_thread_pool_test.cpp b/services/distributeddataservice/adapter/autils/test/unittest/kv_store_thread_pool_test.cpp deleted file mode 100644 index f95274403522392ded271cdf8c93d3685ce509f2..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/autils/test/unittest/kv_store_thread_pool_test.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include "kv_store_thread_pool.h" - -using namespace testing::ext; -using namespace OHOS::DistributedKv; - -class KvStoreThreadPoolTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -void KvStoreThreadPoolTest::SetUpTestCase(void) -{} - -void KvStoreThreadPoolTest::TearDownTestCase(void) -{} - -void KvStoreThreadPoolTest::SetUp(void) -{} - -void KvStoreThreadPoolTest::TearDown(void) -{} - -/** - * @tc.name: TestApplyTask001 - * @tc.desc: test if task can be done asynchronous. - * @tc.type: FUNC - * @tc.require: AR000CQS31 - * @tc.author: liqiao - */ -HWTEST_F(KvStoreThreadPoolTest, TestApplyTask001, TestSize.Level1) -{ - auto pool = KvStoreThreadPool::GetPool(8, "Task001", true); - int var = 0; - auto start = std::chrono::system_clock::now(); - pool->AddTask(KvStoreTask([&var](){ - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - var++; - })); - auto end = std::chrono::system_clock::now(); - std::chrono::duration returnTime = end - start; - EXPECT_LT(returnTime.count(), 0.05); - EXPECT_EQ(var, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(150)); - EXPECT_EQ(var, 1); -} - -/** - * @tc.name: TestApplyTask002 - * @tc.desc: test if task can be done in different thread. - * @tc.type: FUNC - * @tc.require: AR000CQS31 - * @tc.author: liqiao - */ -HWTEST_F(KvStoreThreadPoolTest, TestApplyTask002, TestSize.Level2) -{ - auto pool = KvStoreThreadPool::GetPool(2, "Task002", false); - int var = 0; - std::mutex varMutex; - auto start = std::chrono::system_clock::now(); - KvStoreTask task([&](){ - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - std::lock_guard lock(varMutex); - var++; - }); - for (int i = 0; i < 8; i++) { - pool->AddTask(KvStoreTask(task)); - } - auto end = std::chrono::system_clock::now(); - std::chrono::duration returnTime = end - start; - EXPECT_LT(returnTime.count(), 0.1); - EXPECT_EQ(var, 0); - std::this_thread::sleep_for(std::chrono::milliseconds(700)); - EXPECT_EQ(var, 2); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - EXPECT_EQ(var, 4); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - EXPECT_EQ(var, 6); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - EXPECT_EQ(var, 8); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - EXPECT_EQ(var, 8); - pool->Stop(); -} - -/** - * @tc.name: TestApplyTask003 - * @tc.desc: test whether task can be done if they are not scheduled when calling Stop(). - * @tc.type: FUNC - * @tc.require: AR000CQS31 - * @tc.author: liqiao - */ -HWTEST_F(KvStoreThreadPoolTest, TestApplyTask003, TestSize.Level1) -{ - auto pool = KvStoreThreadPool::GetPool(2, "Task003", false); - int var = 0; - std::mutex varMutex; - KvStoreTask task([&](){ - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - std::lock_guard lock(varMutex); - var++; - }); - for (int i = 0; i < 8; i++) { - pool->AddTask(KvStoreTask(task)); - } - EXPECT_EQ(var, 0); - pool->Stop(); - EXPECT_EQ(var, 8); -} diff --git a/services/distributeddataservice/adapter/broadcaster/BUILD.gn b/services/distributeddataservice/adapter/broadcaster/BUILD.gn index fe0fc348fa18a324750a9c9b28a4a35f69bea101..472bef0cfdef4ba3ff5ad54cc40e426cac4ae024 100755 --- a/services/distributeddataservice/adapter/broadcaster/BUILD.gn +++ b/services/distributeddataservice/adapter/broadcaster/BUILD.gn @@ -30,13 +30,12 @@ ohos_static_library("distributeddata_broadcaster_static") { cflags_cc = [ "-fvisibility=hidden" ] external_deps = [ - # "ces:libcommonevent", "ability_base:base", "ability_base:want", "bundle_framework:appexecfwk_base", "c_utils:utils", "common_event_service:cesfwk_innerkits", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] subsystem_name = "distributeddatamgr" diff --git a/services/distributeddataservice/adapter/communicator/BUILD.gn b/services/distributeddataservice/adapter/communicator/BUILD.gn index be70a5dda4425ec3388336297927fcfc90c380b8..ce3266a47b1144e4b5fa1e146b1894dfd2be6f45 100755 --- a/services/distributeddataservice/adapter/communicator/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/BUILD.gn @@ -58,7 +58,9 @@ ohos_static_library("distributeddata_communicator_static") { "c_utils:utils", "device_manager:devicemanagersdk", "dsoftbus:softbus_client", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "ipc:ipc_core", + "netmanager_base:net_conn_manager_if", ] subsystem_name = "distributeddatamgr" diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp index 5a02eb33afad08c849acb93bd3336f59373f4b06..c29f60aa3d0be49a40992b09f5594275d52135bc 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp @@ -43,10 +43,10 @@ AppPipeHandler::AppPipeHandler(const PipeInfo &pipeInfo) softbusAdapter_ = SoftBusAdapter::GetInstance(); } -Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) +Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - return softbusAdapter_->SendData(pipeInfo, deviceId, ptr, size, info); + return softbusAdapter_->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status AppPipeHandler::StartWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h index 5fe49b7e85b0a4c8344c85e39bd4862247f6d4de..2a2508c5d7da9d6382f33f45acf62e77c6eeaee9 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h @@ -42,8 +42,8 @@ public: // stop DataChangeListener to watch data change; Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); void SetMessageTransFlag(const PipeInfo &pipeInfo, bool flag); diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp index d6580c8b81798e51d310e7aa699af842eada3a6e..f379414703727351e2d30a629af032ce498124c3 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp @@ -58,15 +58,15 @@ Status AppPipeMgr::StopWatchDataChange(const AppDataChangeListener *observer, co } // Send data to other device, function will be called back after sent to notify send result. -Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) +Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - if (size > DataBuffer::MAX_TRANSFER_SIZE || size <= 0 || ptr == nullptr || + if (dataInfo.length > DataBuffer::MAX_TRANSFER_SIZE || dataInfo.length == 0 || dataInfo.data == nullptr || pipeInfo.pipeId.empty() || deviceId.deviceId.empty()) { - ZLOGW("Input is invalid, maxSize:%d, current size:%d", DataBuffer::MAX_TRANSFER_SIZE, size); + ZLOGW("Input is invalid, maxSize:%u, current size:%u", DataBuffer::MAX_TRANSFER_SIZE, dataInfo.length); return Status::ERROR; } - ZLOGD("pipeInfo:%s ,size:%d", pipeInfo.pipeId.c_str(), size); + ZLOGD("pipeInfo:%s ,size:%u, total length:%u", pipeInfo.pipeId.c_str(), dataInfo.length, totalLength); std::shared_ptr appPipeHandler; { std::lock_guard lock(dataBusMapMutex_); @@ -77,7 +77,7 @@ Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, } appPipeHandler = it->second; } - return appPipeHandler->SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeHandler->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } // start server diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h index c942cd46690cfbdf900d1ff44219db110a5227b3..222248c5adedd2c20e5d2068e35f35a64bd8ab69 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h @@ -36,8 +36,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); // start server Status Start(const PipeInfo &pipeInfo); // stop server diff --git a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp index 75b71e644c371cb10d393a2022e9d6f8b0e2ccc9..ee654fccdc96dd26c4f2dd7c26953d84f01aa116 100644 --- a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp @@ -48,10 +48,10 @@ Status CommunicationProviderImpl::StopWatchDataChange(const AppDataChangeListene return appPipeMgr_.StopWatchDataChange(observer, pipeInfo); } -Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, - int size, const MessageInfo &info) +Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - return appPipeMgr_.SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeMgr_.SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status CommunicationProviderImpl::Start(const PipeInfo &pipeInfo) diff --git a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h index 469a7101ddde6c8bf25b13ad20eb82869e33d96b..edac68dc52fa77ab205b2d0a69d5267b830f5229 100644 --- a/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h +++ b/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h @@ -36,8 +36,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) override; // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) override; + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) override; // start 1 server to listen data from other devices; Status Start(const PipeInfo &pipeInfo) override; diff --git a/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp b/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp index 84d2f95a7314a7a84eb01ced8ae6b0eaca0c9049..49dd545977f7a54c06855e48c0c5b201ccdb546d 100644 --- a/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp +++ b/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp @@ -19,14 +19,6 @@ namespace OHOS { namespace AppDistributedKv { int DataBuffer::sequence_ = 0; -const size_t DataBuffer::MAX_DATA_LEN = 1024 * 1024 * 5; - -const int DataBuffer::MAX_TRANSFER_SIZE = 1024 * 1024 * 5 - DataBuffer::HEADER_LEN; - -const uint32_t DataBuffer::VERSION = 0; - -const uint32_t DataBuffer::TYPE = 0; - DataBuffer::DataBuffer() : buf_(nullptr), size_(0), used_(0) {} diff --git a/services/distributeddataservice/adapter/communicator/src/data_buffer.h b/services/distributeddataservice/adapter/communicator/src/data_buffer.h index 1a7627c10adb2ba03f6175214ee6905d49867c7b..e56d89155a2d240a2234ab38f3463418d75dc2b0 100644 --- a/services/distributeddataservice/adapter/communicator/src/data_buffer.h +++ b/services/distributeddataservice/adapter/communicator/src/data_buffer.h @@ -45,17 +45,17 @@ public: size_t GetBufUsed() const; // header length - static const int HEADER_LEN = sizeof(HeaderInfo); + static const uint32_t HEADER_LEN = sizeof(HeaderInfo); // max size for transferring data using pipe is 5M - static const size_t MAX_DATA_LEN; + static constexpr size_t MAX_DATA_LEN = 1024 * 1024 * 5; // 5M; max size for transfer using pipe (12 is header length, rest is data wait for transferring) - static const int MAX_TRANSFER_SIZE; + static constexpr uint32_t MAX_TRANSFER_SIZE = 1024 * 1024 * 5 - HEADER_LEN; - static const uint32_t VERSION; + static constexpr uint32_t VERSION = 0; - static const uint32_t TYPE; + static constexpr uint32_t TYPE = 0; private: char *buf_; diff --git a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index 2ea67eb8c9e03d8f6d7da5887ad2e143d4d01f86..3a560b2a2278f8f19be1f68d6e53982210438acd 100644 --- a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -15,13 +15,19 @@ #define LOG_TAG "DeviceManagerAdapter" #include "device_manager_adapter.h" + #include -#include "log_print.h" + #include "kvstore_utils.h" +#include "log_print.h" +#include "net_conn_callback_stub.h" +#include "net_conn_client.h" +#include "net_handle.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedHardware; using namespace OHOS::AppDistributedKv; +using namespace OHOS::NetManagerStandard; using KvStoreUtils = OHOS::DistributedKv::KvStoreUtils; constexpr int32_t DM_OK = 0; constexpr const char *PKG_NAME = "ohos.distributeddata.service"; @@ -74,7 +80,66 @@ void DataMgrDmInitCall::OnRemoteDied() dmAdapter_.Init(executors_); } +class NetConnCallbackObserver : public NetConnCallbackStub { +public: + explicit NetConnCallbackObserver(DeviceManagerAdapter &dmAdapter) : dmAdapter_(dmAdapter) {} + ~NetConnCallbackObserver() override = default; + int32_t NetAvailable(sptr &netHandle) override; + int32_t NetCapabilitiesChange(sptr &netHandle, const sptr &netAllCap) override; + int32_t NetConnectionPropertiesChange(sptr &netHandle, const sptr &info) override; + int32_t NetLost(sptr &netHandle) override; + int32_t NetUnavailable() override; + int32_t NetBlockStatusChange(sptr &netHandle, bool blocked) override; + +private: + DeviceManagerAdapter &dmAdapter_; +}; + +int32_t NetConnCallbackObserver::NetAvailable(sptr &netHandle) +{ + ZLOGI("OnNetworkAvailable"); + dmAdapter_.Online(dmAdapter_.cloudDmInfo); + dmAdapter_.isNetAvailable_ = true; + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetUnavailable() +{ + ZLOGI("OnNetworkUnavailable"); + dmAdapter_.isNetAvailable_ = false; + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetCapabilitiesChange(sptr &netHandle, + const sptr &netAllCap) +{ + ZLOGI("OnNetCapabilitiesChange"); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetConnectionPropertiesChange(sptr &netHandle, + const sptr &info) +{ + ZLOGI("OnNetConnectionPropertiesChange"); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetLost(sptr &netHandle) +{ + ZLOGI("OnNetLost"); + dmAdapter_.isNetAvailable_ = false; + dmAdapter_.Offline(dmAdapter_.cloudDmInfo); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetBlockStatusChange(sptr &netHandle, bool blocked) +{ + ZLOGI("OnNetBlockStatusChange"); + return DistributedKv::SUCCESS; +} + DeviceManagerAdapter::DeviceManagerAdapter() + : cloudDmInfo({ "cloudDeviceId", "cloudDeviceName", 0, "cloudNetworkId", 0 }) { ZLOGI("construct"); } @@ -107,11 +172,12 @@ std::function DeviceManagerAdapter::RegDevCallback() auto dmInitCall = std::make_shared(*this, executors_); auto resultInit = devManager.InitDeviceManager(PKG_NAME, dmInitCall); auto resultState = devManager.RegisterDevStateCallback(PKG_NAME, "", dmStateCall); - if (resultInit == DM_OK && resultState == DM_OK) { + auto resultNet = RegOnNetworkChange(); + if (resultInit == DM_OK && resultState == DM_OK && resultNet) { return; } constexpr int32_t INTERVAL = 500; - executors_->Schedule(RegDevCallback(), std::chrono::milliseconds(INTERVAL)); + executors_->Schedule(std::chrono::milliseconds(INTERVAL), RegDevCallback()); }; } @@ -153,6 +219,7 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d", KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_ONLINE); + syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); auto observers = GetObservers(); for (const auto &item : observers) { // notify db if (item == nullptr) { @@ -176,7 +243,6 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) [this, dvInfo]() { TimeOut(dvInfo.uuid); }); - syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); for (const auto &item : observers) { // set compatible identify, sync service meta if (item == nullptr) { continue; @@ -404,6 +470,9 @@ std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkI if (networkId.empty()) { return ""; } + if (networkId == DeviceManagerAdapter::cloudDmInfo.networkId) { + return "netUuid"; + } DeviceInfo dvInfo; if (deviceInfos_.Get(networkId, dvInfo)) { return dvInfo.uuid; @@ -422,6 +491,9 @@ std::string DeviceManagerAdapter::GetUdidByNetworkId(const std::string &networkI if (networkId.empty()) { return ""; } + if (networkId == DeviceManagerAdapter::cloudDmInfo.networkId) { + return "netUdid"; + } DeviceInfo dvInfo; if (deviceInfos_.Get(networkId, dvInfo)) { return dvInfo.udid; @@ -451,7 +523,7 @@ std::vector DeviceManagerAdapter::ToUUID(const std::vector DeviceManagerAdapter::ToUUID(std::vector de std::vector uuids; for (auto &device : devices) { if (device.uuid.empty()) { - continue ; + continue; } uuids.push_back(std::move(device.uuid)); } @@ -488,4 +560,24 @@ std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const } return encryptedUuid; } + +bool DeviceManagerAdapter::RegOnNetworkChange() +{ + sptr observer = new (std::nothrow) NetConnCallbackObserver(*this); + if (observer == nullptr) { + ZLOGE("new operator error.observer is nullptr"); + return false; + } + int nRet = NetConnClient::GetInstance().RegisterNetConnCallback(observer); + if (nRet != NETMANAGER_SUCCESS) { + ZLOGE("RegisterNetConnCallback failed, ret = %{public}d", nRet); + return false; + } + return true; +} + +bool DeviceManagerAdapter::IsNetworkAvailable() +{ + return isNetAvailable_; +} } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index c93a2a9771ad11d2bdd3d5880f8eb54760b6d484..4b435d1e2a6a0eaf750147c638d46eed14545535 100644 --- a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -111,11 +111,19 @@ DBStatus ProcessCommunicatorImpl::RegOnDataReceive(const OnDataReceive &callback } DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) +{ + uint32_t totalLength = 0; + return SendData(dstDevInfo, data, length, totalLength); +} + +DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, + uint32_t totalLength) { PipeInfo pi = {thisProcessLabel_, ""}; + const DataInfo dataInfo = { const_cast(data), length}; DeviceId destination; destination.deviceId = dstDevInfo.identifier; - Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, data, static_cast(length)); + Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); if (errCode != Status::SUCCESS) { ZLOGE("commProvider_ SendData Fail."); return DBStatus::DB_ERROR; diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index 277d2d73d6002e8c305e2f06b89cb40e550d7d5c..2cd755e074648e72c14b3798722f64372d5ee34d 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -28,7 +28,6 @@ #include "app_data_change_listener.h" #include "app_device_change_listener.h" #include "block_data.h" -#include "platform_specific.h" #include "session.h" #include "softbus_bus_center.h" #include "softbus_client.h" @@ -47,8 +46,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *data, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index e86d19455e649156a04b01e518ddf372c07de511..9f795a780e79951c0389fc3bfaa4a8a5b048157e 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -38,6 +38,7 @@ enum SoftBusAdapterErrorCode : int32_t { PEER_SESSION_NAME_INVALID, PEER_DEVICE_ID_INVALID, SESSION_SIDE_INVALID, + ROUTE_TYPE_INVALID, }; constexpr int32_t SESSION_NAME_SIZE_MAX = 65; constexpr int32_t DEVICE_ID_SIZE_MAX = 65; @@ -52,6 +53,7 @@ struct ConnDetailsInfo { char peerName[SESSION_NAME_SIZE_MAX] = ""; std::string peerDevUuid; int32_t side = -1; + int32_t routeType = -1; }; class AppDataListenerWrap { public: @@ -160,8 +162,8 @@ Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppData return Status::ERROR; } -Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *data, int size, - const MessageInfo &info) +Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { std::shared_ptr conn; { @@ -176,7 +178,7 @@ Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &device } if (conn != nullptr) { - return conn->Send(data, size); + return conn->Send(dataInfo, totalLength); } return Status::ERROR; @@ -359,6 +361,13 @@ int AppDataListenerWrap::GetConnDetailsInfo(int connId, ConnDetailsInfo &connInf return SESSION_SIDE_INVALID; } + int32_t routeType = RouteType::INVALID_ROUTE_TYPE; + ret = GetSessionOption(connId, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + if (ret != SOFTBUS_OK) { + return ROUTE_TYPE_INVALID; + } + connInfo.routeType = routeType; + return SOFTBUS_OK; } @@ -379,8 +388,8 @@ int AppDataListenerWrap::OnConnectOpened(int connId, int result) } ZLOGD("[OnConnectOpened] conn id:%{public}d, my name:%{public}s, peer name:%{public}s, " - "peer devId:%{public}s, side:%{public}d", connId, connInfo.myName, connInfo.peerName, - KvStoreUtils::ToBeAnonymous(connInfo.peerDevUuid).c_str(), connInfo.side); + "peer devId:%{public}s, side:%{public}d, routeType:%{public}d", connId, connInfo.myName, connInfo.peerName, + KvStoreUtils::ToBeAnonymous(connInfo.peerDevUuid).c_str(), connInfo.side, connInfo.routeType); return 0; } @@ -435,7 +444,7 @@ void SoftBusAdapter::SofBusDeviceChangeListenerImpl::OnDeviceChanged(const AppDi } CommunicationStrategy::GetInstance().SetStrategy(info.uuid, strategy, - [this](const std::string deviceId, Strategy strategy) { + [this](const std::string &deviceId, Strategy strategy) { std::shared_ptr conn = SoftBusAdapter::GetInstance()->GetConnect(deviceId); if (conn != nullptr) { conn->AfterStrategyUpdate(strategy); diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp b/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp index fe9601d64a66d21c2381114f0aee49666fa623e9..ecba7a53ddc2204d7edddc0f1699805d0ea096e8 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -51,6 +51,7 @@ void SoftBusClient::RestoreDefaultValue() { connId_ = INVALID_CONNECT_ID; status_ = ConnectStatus::DISCONNECT; + routeType_ = RouteType::INVALID_ROUTE_TYPE; strategy_ = Strategy::DEFAULT; mtu_ = DEFAULT_MTU_SIZE; } @@ -61,16 +62,17 @@ uint32_t SoftBusClient::GetMtuSize() const return mtu_; } -Status SoftBusClient::Send(const uint8_t *data, int size) +Status SoftBusClient::Send(const DataInfo &dataInfo, uint32_t totalLength) { std::lock_guard lock(mutex_); - auto result = OpenConnect(); + auto result = OpenConnect(totalLength); if (result != Status::SUCCESS) { return result; } - ZLOGD("send data connId:%{public}d, data size:%{public}d.", connId_, size); - int32_t ret = SendBytes(connId_, data, size); + ZLOGD("send data connId:%{public}d, data size:%{public}u, total length:%{public}u.", + connId_, dataInfo.length, totalLength); + int32_t ret = SendBytes(connId_, dataInfo.data, dataInfo.length); if (ret != SOFTBUS_OK) { ZLOGE("send data to connId%{public}d failed, ret:%{public}d.", connId_, ret); return Status::ERROR; @@ -79,30 +81,90 @@ Status SoftBusClient::Send(const uint8_t *data, int size) return Status::SUCCESS; } -Status SoftBusClient::OpenConnect() +Status SoftBusClient::OpenConnect(uint32_t totalLength) { + strategy_ = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); if (status_ == ConnectStatus::CONNECT_OK) { - return Status::SUCCESS; + auto result = SwitchChannel(totalLength); + if (result != Status::SUCCESS) { + status_ = ConnectStatus::DISCONNECT; + } + + status_ = ConnectStatus::CONNECT_OK; + return result; } - auto result = Open(); + auto result = CreateChannel(totalLength); if (result != Status::SUCCESS) { return result; } status_ = ConnectStatus::CONNECT_OK; - UpdateMtuSize(); return Status::SUCCESS; } -Status SoftBusClient::Open() +Status SoftBusClient::SwitchChannel(uint32_t totalLength) +{ + if (strategy_ == Strategy::BUTT) { + return Status::NETWORK_ERROR; + } + + if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { + return Status::SUCCESS; + } + + if (routeType_ == RouteType::WIFI_STA) { + return Status::SUCCESS; + } + + if (routeType_ == RouteType::BT_BLE || routeType_ == RouteType::BT_BR) { + if (totalLength < P2P_SIZE_THRESHOLD) { + return Status::SUCCESS; + } + + ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to wifi or p2p.", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); + CloseSession(connId_); + RestoreDefaultValue(); + return Open(GetSessionAttribute(true)); + } + + if (routeType_ == RouteType::WIFI_P2P) { + if (totalLength > P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR) { + return Status::SUCCESS; + } + + ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to ble or br.", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); + CloseSession(connId_); + RestoreDefaultValue(); + return Open(GetSessionAttribute(false)); + } + + return Status::NETWORK_ERROR; +} + +Status SoftBusClient::CreateChannel(uint32_t totalLength) +{ + if (strategy_ == Strategy::BUTT) { + return Status::NETWORK_ERROR; + } + + if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { + return Open(GetSessionAttribute(true)); + } + + if (totalLength < P2P_SIZE_THRESHOLD) { + return Open(GetSessionAttribute(false)); + } + return Open(GetSessionAttribute(true)); +} + +Status SoftBusClient::Open(SessionAttribute attr) { - Strategy strategy = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); - SessionAttribute attr = { 0 }; - InitSessionAttribute(strategy, attr); int id = OpenSession(pipe_.pipeId.c_str(), pipe_.pipeId.c_str(), DmAdapter::GetInstance().ToNetworkID(device_.deviceId).c_str(), "GROUP_ID", &attr); ZLOGI("open %{public}s,session:%{public}s,connId:%{public}d,linkNum:%{public}d,strategy:%{public}d", - KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), id, attr.linkTypeNum, strategy); + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), id, attr.linkTypeNum, strategy_); if (id < 0) { ZLOGW("Open %{public}s, type:%{public}d failed, connId:%{public}d", pipe_.pipeId.c_str(), attr.dataType, id); @@ -110,22 +172,34 @@ Status SoftBusClient::Open() } connId_ = id; - strategy_ = strategy; int state = getConnStatus_(connId_); ZLOGI("waited for notification, state:%{public}d connId:%{public}d", state, id); if (state != SOFTBUS_OK) { ZLOGE("open callback result error"); return Status::NETWORK_ERROR; } + + int32_t routeType = RouteType::INVALID_ROUTE_TYPE; + auto ret = GetSessionOption(connId_, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + if (ret != SOFTBUS_OK) { + ZLOGE("get routeType failed, session:%{public}s, connId:%{public}d", pipe_.pipeId.c_str(), connId_); + return Status::NETWORK_ERROR; + } + routeType_ = routeType; + + UpdateMtuSize(); + ZLOGI("open %{public}s, session:%{public}s success, connId:%{public}d, routeType:%{public}d", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); return Status::SUCCESS; } -void SoftBusClient::InitSessionAttribute(Strategy strategy, SessionAttribute &attr) +SessionAttribute SoftBusClient::GetSessionAttribute(bool isP2P) { + SessionAttribute attr; attr.dataType = TYPE_BYTES; // If the dataType is BYTES, the default strategy is wifi_5G > wifi_2.4G > BR, without P2P; - if (strategy == Strategy::DEFAULT) { - return; + if (!isP2P) { + return attr; } int index = 0; @@ -134,6 +208,7 @@ void SoftBusClient::InitSessionAttribute(Strategy strategy, SessionAttribute &at attr.linkType[index++] = LINK_TYPE_WIFI_P2P; attr.linkType[index++] = LINK_TYPE_BR; attr.linkTypeNum = index; + return attr; } void SoftBusClient::UpdateMtuSize() diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/services/distributeddataservice/adapter/communicator/src/softbus_client.h index 4a4346062453360f81d69acf203e97f0372b5f88..a99d9b1c5d0c08f453970efc2a41c4765ae7233f 100644 --- a/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -19,6 +19,7 @@ #include #include +#include "commu_types.h" #include "communication_strategy.h" #include "session.h" #include "softbus_bus_center.h" @@ -30,7 +31,7 @@ public: ~SoftBusClient(); using Strategy = CommunicationStrategy::Strategy; - Status Send(const uint8_t *data, int size); + Status Send(const DataInfo &dataInfo, uint32_t totalLength); bool operator==(int32_t connId) const; bool operator==(const std::string &deviceId) const; uint32_t GetMtuSize() const; @@ -41,16 +42,21 @@ private: DISCONNECT, }; - Status OpenConnect(); - Status Open(); - void InitSessionAttribute(Strategy strategy, SessionAttribute &attr); + Status OpenConnect(uint32_t totalLength); + Status SwitchChannel(uint32_t totalLength); + Status CreateChannel(uint32_t totalLength); + Status Open(SessionAttribute attr); + SessionAttribute GetSessionAttribute(bool isP2P); void RestoreDefaultValue(); void UpdateMtuSize(); static constexpr int32_t INVALID_CONNECT_ID = -1; static constexpr uint32_t WAIT_MAX_TIME = 10; static constexpr uint32_t DEFAULT_MTU_SIZE = 4096u; + static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB + static constexpr float SWITCH_DELAY_FACTOR = 0.6f; int32_t connId_ = INVALID_CONNECT_ID; + int32_t routeType_ = RouteType::INVALID_ROUTE_TYPE; Strategy strategy_ = Strategy::DEFAULT; ConnectStatus status_ = ConnectStatus::DISCONNECT; std::mutex mutex_; diff --git a/services/distributeddataservice/adapter/communicator/test/BUILD.gn b/services/distributeddataservice/adapter/communicator/test/BUILD.gn index a3fa43ac1ad48518221acd752132beaee2811fdc..b3dbad12f7c0f3ef2c8067325330b2a9b202de2f 100755 --- a/services/distributeddataservice/adapter/communicator/test/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/test/BUILD.gn @@ -30,7 +30,7 @@ ohos_unittest("CommunicationProviderTest") { ] external_deps = [ "dsoftbus:softbus_client", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] deps = [ @@ -55,7 +55,7 @@ ohos_unittest("DeviceManagerAdapterTest") { ] external_deps = [ "dsoftbus:softbus_client", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] deps = [ diff --git a/services/distributeddataservice/adapter/autils/test/BUILD.gn b/services/distributeddataservice/adapter/communicator/test/fuzztest/BUILD.gn old mode 100755 new mode 100644 similarity index 43% rename from services/distributeddataservice/adapter/autils/test/BUILD.gn rename to services/distributeddataservice/adapter/communicator/test/fuzztest/BUILD.gn index afd7c605f06a0a922cca3a0f89de40e46883e680..dacf421df4682cdbe259f46e31535df42a1e347c --- a/services/distributeddataservice/adapter/autils/test/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2023 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,39 +10,12 @@ # 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/test.gni") -module_output_path = "datamgr_service/distributeddatafwk" +import("//build/ohos.gni") -############################################################################### -config("module_private_config") { - visibility = [ ":*" ] - - include_dirs = [ - "../../include/autils/", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - ] - defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] -} - -ohos_unittest("KvStoreThreadPoolTest") { - module_out_path = module_output_path - - sources = [ "unittest/kv_store_thread_pool_test.cpp" ] - - configs = [ ":module_private_config" ] - - deps = [ - "../../autils:distributeddata_autils_static", - "//third_party/googletest:gtest_main", - ] -} - -group("unittest") { +######################################################################################### +group("fuzztest") { testonly = true - deps = [] - - deps += [ ":KvStoreThreadPoolTest" ] + deps = [ "softbusadapter_fuzzer:fuzztest" ] } -############################################################################### diff --git a/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..25df6bdb94d26f73be10de4d43ef1587bfc08b05 --- /dev/null +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn @@ -0,0 +1,68 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("SoftBusAdapterFuzzTest") { + module_out_path = "datamgr_service/adapter" + + include_dirs = [ + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/adapter/include/log", + "${data_service_path}/adapter/include/autils", + "${data_service_path}/adapter/include/utils", + "${data_service_path}/adapter/communicator/src", + "${dsoftbus_core_path}", + "${kv_store_common_path}", + "${kv_store_distributeddb_path}/interfaces/include", + "${kv_store_distributeddb_path}/include", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + ] + + fuzz_config_file = "${data_service_path}/adapter/communicator/test/fuzztest/softbusadapter_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "softbusadapter_fuzzer.cpp" ] + + deps = [ + "${data_service_path}/adapter/communicator:distributeddata_communicator_static", + "${data_service_path}/adapter/dfx:distributeddata_dfx_static", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + ] + + external_deps = [ + "c_utils:utils", + "device_manager:devicemanagersdk", + "dsoftbus:softbus_client", + "hilog:libhilog", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":SoftBusAdapterFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/corpus/init b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/project.xml b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool.cpp b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.cpp similarity index 46% rename from services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool.cpp rename to services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.cpp index d8ccdc62a134a7500711adf9205093ff02cca5f9..cc9721064055b98521dca506f5b5618d70c9a3c1 100644 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool.cpp +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,26 +13,35 @@ * limitations under the License. */ -#define LOG_TAG "KvStoreThreadPool" +#include "softbusadapter_fuzzer.h" -#include "kv_store_thread_pool_impl.h" -#include "log_print.h" +#include +#include + +#include "softbus_adapter_standard.cpp" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::AppDistributedKv; namespace OHOS { -namespace DistributedKv { -std::shared_ptr KvStoreThreadPool::GetPool(int poolSize, std::string poolName, bool startImmediately) +bool OnBytesReceivedFuzz(const uint8_t *data, size_t size) { - std::shared_ptr poolImpl = - std::make_shared(poolSize, std::move(poolName), startImmediately); - if (poolImpl == nullptr) { - return nullptr; - } - return std::shared_ptr(std::dynamic_pointer_cast(poolImpl)); + int connId = static_cast(*data); + unsigned int dataLen = static_cast(size); + AppDataListenerWrap::OnBytesReceived(connId, data, dataLen); + return true; } +} // namespace OHOS -std::string KvStoreThreadPool::GetPoolName() +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - return poolName_; -} -} // namespace DistributedKv -} // namespace OHOS + if (data == nullptr) { + return 0; + } + + OHOS::OnBytesReceivedFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/autils/platform_specific.h b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.h similarity index 73% rename from services/distributeddataservice/adapter/include/autils/platform_specific.h rename to services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.h index 6634dbf40a545c24ca61c156dc41e15b40e3453b..d77e3037e5a2c2ce48f13fd258a21a9d1404eb97 100644 --- a/services/distributeddataservice/adapter/include/autils/platform_specific.h +++ b/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/softbusadapter_fuzzer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,13 +13,9 @@ * limitations under the License. */ -#ifndef PLATFORM_SPECIFIC_H -#define PLATFORM_SPECIFIC_H +#ifndef SOFTBUSADAPTER_FUZZER_H +#define SOFTBUSADAPTER_FUZZER_H -#if defined _WIN32 - #define OS_WINDOWS -#else - #define OS_OHOS -#endif +#define FUZZ_PROJECT_NAME "softbusadapter_fuzzer" -#endif // PLATFORM_SPECIFIC_H +#endif // SOFTBUSADAPTER_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp b/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp index 137f105cc8841ef73b7f92a905a04d470cba38b2..0000371d35d830cd2d06690e078653c4c520df6c 100644 --- a/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp +++ b/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp @@ -132,7 +132,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider005, TestSize.Level std::string content = "Helloworlds"; const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di17 = {"127.0.0.2"}; - Status status = CommunicationProvider::GetInstance().SendData(id17, di17, t, content.length()); + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); EXPECT_NE(status, Status::SUCCESS); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener17, id17); CommunicationProvider::GetInstance().Stop(id17); diff --git a/services/distributeddataservice/adapter/dfx/BUILD.gn b/services/distributeddataservice/adapter/dfx/BUILD.gn index c137b61fef10ccc8ac363a1a47f1bb7680b870c8..9d23ea69a0912a7c7dd7b0d09bc5343deaa280fe 100644 --- a/services/distributeddataservice/adapter/dfx/BUILD.gn +++ b/services/distributeddataservice/adapter/dfx/BUILD.gn @@ -41,16 +41,13 @@ ohos_static_library("distributeddata_dfx_static") { cflags_cc = [ "-fvisibility=hidden" ] - deps = [ - "../autils:distributeddata_autils_static", - "//third_party/openssl:libcrypto_shared", - ] + deps = [ "//third_party/openssl:libcrypto_shared" ] external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hitrace_native:libhitracechain", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp index 9e3b46197aa52b347f1c22de519e843dcf97cb2e..7632db6c834296e57c5540cb992c108f1dc15f38 100644 --- a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "behaviour_reporter_impl.h" namespace OHOS { @@ -22,6 +21,13 @@ ReportStatus BehaviourReporterImpl::Report(const BehaviourMsg &msg) HiViewAdapter::ReportBehaviour(DfxCodeConstant::DATABASE_BEHAVIOUR, msg, executors_); return ReportStatus::SUCCESS; } + +ReportStatus BehaviourReporterImpl::UDMFReport(const UdmfBehaviourMsg &msg) +{ + HiViewAdapter::ReportUdmfBehaviour(DfxCodeConstant::UDMF_DATA_BEHAVIOR, msg, executors_); + return ReportStatus::SUCCESS; +} + void BehaviourReporterImpl::SetThreadPool(std::shared_ptr executors) { executors_ = executors; diff --git a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h index 7ac010b1975b2847b5878086126c9bb816f80170..5fff69e41bb6f24f9bbcdb610b3ff164a595600b 100644 --- a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h @@ -25,6 +25,7 @@ class BehaviourReporterImpl : public BehaviourReporter { public: virtual ~BehaviourReporterImpl() {} ReportStatus Report(const struct BehaviourMsg &msg) override; + ReportStatus UDMFReport(const UdmfBehaviourMsg &msg) override; void SetThreadPool(std::shared_ptr executors); private: diff --git a/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h b/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h index a78caaaf7f959f8d9809e55546559e2c80cf9cde..cc2cba1d19716c83e325a6d6d50776be83e71c78 100644 --- a/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h +++ b/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h @@ -32,5 +32,6 @@ public: static inline const int DATABASE_CORRUPTED_FAILED = 950001113; static inline const int DATABASE_REKEY_FAILED = 950001114; static inline const int DATABASE_BEHAVIOUR = 950001115; + static inline const int UDMF_DATA_BEHAVIOR = 950001116; }; #endif // DISTRIBUTEDDATAMGR_DFX_CODE_CONSTANT_H diff --git a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp index 9ac6fef2feb123a05d71f3253fcd0bd675f2d4be..47aa3016bb9400b8a2d4ce465cb381ea1dc77d29 100644 --- a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp +++ b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp @@ -47,6 +47,11 @@ constexpr const char *TAG = "TAG"; constexpr const char *POWERSTATS = "PowerStats"; // behaviour key constexpr const char *BEHAVIOUR_INFO = "BEHAVIOUR_INFO"; +constexpr const char *CHANNEL = "CHANNEL"; +constexpr const char *DATA_SIZE = "DATA_SIZE"; +constexpr const char *DATA_TYPE = "DATA_TYPE"; +constexpr const char *OPERATION = "OPERATION"; +constexpr const char *RESULT = "RESULT"; const std::map EVENT_COVERT_TABLE = { { DfxCodeConstant::SERVICE_FAULT, "SERVICE_FAULT" }, @@ -63,6 +68,7 @@ const std::map EVENT_COVERT_TABLE = { { DfxCodeConstant::DATABASE_CORRUPTED_FAILED, "DATABASE_CORRUPTED_FAILED" }, { DfxCodeConstant::DATABASE_REKEY_FAILED, "DATABASE_REKEY_FAILED" }, { DfxCodeConstant::DATABASE_BEHAVIOUR, "DATABASE_BEHAVIOUR" }, + { DfxCodeConstant::UDMF_DATA_BEHAVIOR, "UDMF_DATA_BEHAVIOR" }, }; } using OHOS::HiviewDFX::HiSysEvent; @@ -298,6 +304,27 @@ void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerforma StartTimerThread(executors); } +void HiViewAdapter::ReportUdmfBehaviour( + int dfxCode, const UdmfBehaviourMsg &msg, std::shared_ptr executors) +{ + if (executors == nullptr) { + ZLOGI("report udmf behavior failed"); + return; + } + ExecutorPool::Task task([dfxCode, msg]() { + HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, + CoverEventID(dfxCode), + HiSysEvent::EventType::BEHAVIOR, + APP_ID, msg.appId, + CHANNEL, msg.channel, + DATA_SIZE, msg.dataSize, + DATA_TYPE, msg.dataType, + OPERATION, msg.operation, + RESULT, msg.result); + }); + executors->Execute(std::move(task)); +} + void HiViewAdapter::InvokeApiPerformance() { std::string message; diff --git a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h index 21de2703b9b2a71fa5e27aae92885d205d168fc7..cb03b82cd27ed6ad376ef80295854420c24b7956 100644 --- a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h +++ b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h @@ -46,6 +46,7 @@ public: static void ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat, std::shared_ptr executors); static void ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::shared_ptr executors); + static void ReportUdmfBehaviour(int dfxCode, const UdmfBehaviourMsg &msg, std::shared_ptr executors); static void StartTimerThread(std::shared_ptr executors); private: diff --git a/services/distributeddataservice/adapter/dfx/test/BUILD.gn b/services/distributeddataservice/adapter/dfx/test/BUILD.gn index de03ed064b9eed0b936d296c663657709d68b62d..fe26d017b5bbed375bf6bd608a8c277d9fb48bd1 100755 --- a/services/distributeddataservice/adapter/dfx/test/BUILD.gn +++ b/services/distributeddataservice/adapter/dfx/test/BUILD.gn @@ -41,13 +41,12 @@ ohos_unittest("DistributeddataDfxMSTTest") { external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ - "../../autils:distributeddata_autils_static", "../../dfx:distributeddata_dfx_static", "//third_party/googletest:gtest_main", "//third_party/openssl:libcrypto_shared", @@ -100,13 +99,12 @@ ohos_unittest("DistributeddataDfxUTTest") { external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ - "../../autils:distributeddata_autils_static", "//third_party/googletest:gtest_main", "//third_party/openssl:libcrypto_shared", ] @@ -118,6 +116,9 @@ group("unittest") { testonly = true deps = [] - deps += [ ":DistributeddataDfxMSTTest" ] + deps += [ + ":DistributeddataDfxMSTTest", + ":DistributeddataDfxUTTest", + ] } ############################################################################### diff --git a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp index b93b5632b3c6d06f0061b8bca27805aabe16f3c0..f4887d3c2de86434ef62d7bb1f19cb4438d99d3f 100644 --- a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp +++ b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp @@ -35,21 +35,25 @@ public: void DistributedataDfxUTTest::SetUpTestCase() { - size_t max = 12; - size_t min = 5; - Reporter::GetInstance()->SetThreadPool(std::make_shared(max, min)); FakeHivew::Clear(); } void DistributedataDfxUTTest::TearDownTestCase() { - Reporter::GetInstance()->SetThreadPool(nullptr); FakeHivew::Clear(); } -void DistributedataDfxUTTest::SetUp() {} +void DistributedataDfxUTTest::SetUp() +{ + size_t max = 12; + size_t min = 5; + Reporter::GetInstance()->SetThreadPool(std::make_shared(max, min)); +} -void DistributedataDfxUTTest::TearDown() {} +void DistributedataDfxUTTest::TearDown() +{ + Reporter::GetInstance()->SetThreadPool(nullptr); +} /** * @tc.name: Dfx001 diff --git a/services/distributeddataservice/adapter/include/autils/constant.h b/services/distributeddataservice/adapter/include/autils/constant.h deleted file mode 100644 index 1d974894073ee7d858c3089243664b800bbd6bce..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/include/autils/constant.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef KV_DATASERVICE_CONSTANT_H -#define KV_DATASERVICE_CONSTANT_H - -#include -#include -#include -#include -#include -#include -#include -#include "visibility.h" - -namespace OHOS { -namespace DistributedKv { -class KvStoreMetaRow { -public: - KVSTORE_API static const std::string KEY_PREFIX; - - KVSTORE_API static std::vector GetKeyFor(const std::string &key); -}; - -class SecretMetaRow { -public: - KVSTORE_API static const std::string KEY_PREFIX; - - KVSTORE_API static std::vector GetKeyFor(const std::string &key); -}; - -class Constant { -public: - // concatenate strings and return a composition string. - KVSTORE_API static std::string Concatenate(std::initializer_list stringList); - - // delete left bland in s by reference. - template - static void LeftTrim(T &s); - - // delete right bland in s by reference. - template - static void RightTrim(T &s); - - // delete both left and right bland in s by reference. - template - static void Trim(T &s); - - // delete left bland in s by reference, not change raw string. - template - static T LeftTrimCopy(T s); - - // delete right bland in s by reference, not change raw string. - template - static T RightTrimCopy(T s); - - // delete both left and right bland in s by reference, not change raw string. - template - static T TrimCopy(T s); - - // get default device account id. - KVSTORE_API static std::string GetDefaultDeviceAccountId(); - - // get default harmony account name. - KVSTORE_API static std::string GetDefaultHarmonyAccountName(); - - // default group id for synchronization based on harmony account. - KVSTORE_API static const std::string DEFAULT_GROUP_ID; - - // Indicates whether only storeid are used as hash materials for the DistributedDB path generated. - KVSTORE_API static const bool STOREID_ONLY_FLAG; - - // version for distributed kv data service. - KVSTORE_API static const std::string VERSION; - - // meta name for distributed kv data service. - KVSTORE_API static const std::string META_DIR_NAME; - - // name for distributed kv data service. - KVSTORE_API static const std::string SERVICE_NAME; - - // root path for distributed kv data service. - KVSTORE_API static const std::string ROOT_PATH; - - // root path for distributeddata service and system services. - KVSTORE_API static const std::string ROOT_PATH_DE; - - // root path for self-developed and non-self-developed app. - KVSTORE_API static const std::string ROOT_PATH_CE; - - // the max length for key is 256. - KVSTORE_API static const size_t MAX_KEY_LENGTH; - - // the max length for value is 1M. - KVSTORE_API static const size_t MAX_VALUE_LENGTH; - - // the max length for StoreId is 64. - KVSTORE_API static const size_t MAX_STORE_ID_LENGTH; - - // the max batch for putBatch is 128. - KVSTORE_API static const size_t MAX_BATCH_SIZE; - - // the max capacity for ipc is 800KB. - KVSTORE_API static const size_t MAX_IPC_CAPACITY; - - // service meta db name. - KVSTORE_API static const std::string SERVICE_META_DB_NAME; - - KVSTORE_API static const std::string KEY_SEPARATOR; - - KVSTORE_API static const mode_t DEFAULT_MODE; - - KVSTORE_API static const mode_t DEFAULT_MODE_DIR; - - KVSTORE_API static const mode_t DEFAULT_MODE_FILE; - - KVSTORE_API static const int SWITCH_RAW_DATA_SIZE; - - KVSTORE_API static const int MAX_OPEN_KVSTORES; - - // name for process label (bus name for communication). compatible with HwDDMP - KVSTORE_API static const std::string ROOT_KEY_GENERATED; -}; - -// trim from start (in place) -template -void Constant::LeftTrim(T &s) -{ - s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); })); -} - -// trim from end (in place) -template -void Constant::RightTrim(T &s) -{ - s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end()); -} - -// trim from both ends (in place) -template -void Constant::Trim(T &s) -{ - LeftTrim(s); - RightTrim(s); -} - -// trim from start (copying) -template -T Constant::LeftTrimCopy(T s) -{ - LeftTrim(s); - return s; -} - -// trim from end (copying) -template -T Constant::RightTrimCopy(T s) -{ - RightTrim(s); - return s; -} - -// trim from both ends (copying) -template -T Constant::TrimCopy(T s) -{ - Trim(s); - return s; -} -} // namespace DistributedKv -} // namespace OHOS -#endif // KV_DATASERVICE_CONSTANT_H diff --git a/services/distributeddataservice/adapter/include/communicator/commu_types.h b/services/distributeddataservice/adapter/include/communicator/commu_types.h index ca822697061b3d3fc9920e1843950d9d782e11d5..bcd72794b586a32e7e12a4911bd7a35fade908a8 100644 --- a/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -35,6 +35,21 @@ enum DeviceType { OTHERS, }; +enum RouteType : int32_t { + INVALID_ROUTE_TYPE = -1, + ROUTE_TYPE_ALL = 0, + WIFI_STA = 1, + WIFI_P2P = 2, + BT_BR = 3, + BT_BLE = 4, + BUTT = 5, +}; + +struct DataInfo { + uint8_t *data; + uint32_t length; +}; + struct API_EXPORT PipeInfo { std::string pipeId; std::string userId; diff --git a/services/distributeddataservice/adapter/include/communicator/communication_provider.h b/services/distributeddataservice/adapter/include/communicator/communication_provider.h index 0418b0c324c7d072da315c02046ca0aab9051d9c..b0295285171ea7a4ed1081305949d8da131d50cf 100644 --- a/services/distributeddataservice/adapter/include/communicator/communication_provider.h +++ b/services/distributeddataservice/adapter/include/communicator/communication_provider.h @@ -45,8 +45,8 @@ public: virtual Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) = 0; // Send data to other device, function will be called back after sent to notify send result - virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info = { MessageType::DEFAULT }) = 0; + virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info = { MessageType::DEFAULT }) = 0; // start one server to listen data from other devices; virtual Status Start(const PipeInfo &pipeInfo) = 0; diff --git a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h index 9cb05a88287f92328ccc43401e6d0a7d54da3648..71b0441674448658e9aed8fb9850440f10ddd6c5 100644 --- a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h +++ b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h @@ -54,12 +54,15 @@ public: static std::vector ToUUID(std::vector devices); std::string ToNetworkID(const std::string &id); void NotifyReadyEvent(const std::string &uuid); + bool IsNetworkAvailable(); friend class DataMgrDmStateCall; + friend class NetConnCallbackObserver; private: DeviceManagerAdapter(); ~DeviceManagerAdapter(); std::function RegDevCallback(); + bool RegOnNetworkChange(); bool GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo &dvInfo); void SaveDeviceInfo(const DeviceInfo &deviceInfo, const AppDistributedKv::DeviceChangeType &type); void UpdateDeviceInfo(); @@ -73,12 +76,14 @@ private: std::mutex devInfoMutex_ {}; DeviceInfo localInfo_ {}; + const DmDeviceInfo cloudDmInfo; ConcurrentMap observers_ {}; LRUBucket deviceInfos_ {64}; static constexpr size_t TIME_TASK_CAPACITY = 50; static constexpr int32_t SYNC_TIMEOUT = 10 * 1000; // ms ConcurrentMap syncTask_ {}; std::shared_ptr executors_; + bool isNetAvailable_ = false; }; } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index 26146c6ffd3431cc3d19a90c93b4ecbf774b955f..259f775ea55c249082f30cd6957177fca1ade8de 100644 --- a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -46,6 +46,8 @@ public: DBStatus RegOnDataReceive(const OnDataReceive &callback) override; DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) override; + DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, + uint32_t totalLength) override; uint32_t GetMtuSize() override; uint32_t GetMtuSize(const DeviceInfos &devInfo) override; DeviceInfos GetLocalDeviceInfos() override; diff --git a/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h b/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h index 57b1f32c4f57a02ea91b6fa13fef658cbb3b02d5..82431c96e67e37ad632f48e15dc68b333fdf4b38 100644 --- a/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h +++ b/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h @@ -23,6 +23,7 @@ namespace DistributedDataDfx { class BehaviourReporter { public: KVSTORE_API virtual ReportStatus Report(const BehaviourMsg &msg) = 0; + KVSTORE_API virtual ReportStatus UDMFReport(const UdmfBehaviourMsg &msg) = 0; KVSTORE_API virtual ~BehaviourReporter() {} }; } // namespace DistributedDataDfx diff --git a/services/distributeddataservice/adapter/include/dfx/dfx_types.h b/services/distributeddataservice/adapter/include/dfx/dfx_types.h index e8ab47b42d922a70ec2d715ee9bad6d8ed42e602..cbc0117d044d6c3c2cbc5070c5e1f0042f28c3d7 100644 --- a/services/distributeddataservice/adapter/include/dfx/dfx_types.h +++ b/services/distributeddataservice/adapter/include/dfx/dfx_types.h @@ -131,6 +131,15 @@ struct BehaviourMsg { std::string extensionInfo; }; +struct UdmfBehaviourMsg { + std::string appId; + std::string channel; + int64_t dataSize; + std::string dataType; + std::string operation; + std::string result; +}; + struct VisitStat { std::string appId; std::string interfaceName; diff --git a/services/distributeddataservice/adapter/include/dfx/reporter.h b/services/distributeddataservice/adapter/include/dfx/reporter.h index f84af98ae02429b9dbb108a0547a0a286bd70a02..de60c0e848f15bdbd8484fc883f517308abf17aa 100644 --- a/services/distributeddataservice/adapter/include/dfx/reporter.h +++ b/services/distributeddataservice/adapter/include/dfx/reporter.h @@ -43,6 +43,17 @@ public: void SetThreadPool(std::shared_ptr executors) { executors_ = executors; + if (executors != nullptr) { + ServiceFault(); + RuntimeFault(); + DatabaseFault(); + CommunicationFault(); + DatabaseStatistic(); + VisitStatistic(); + TrafficStatistic(); + ApiPerformanceStatistic(); + BehaviourReporter(); + } }; private: diff --git a/services/distributeddataservice/adapter/include/permission/permission_validator.h b/services/distributeddataservice/adapter/include/permission/permission_validator.h index ab78f1990e0fd3df0a1680964e34aded0810d2cc..322d8b00257603b82440057df5da7488a33601a0 100644 --- a/services/distributeddataservice/adapter/include/permission/permission_validator.h +++ b/services/distributeddataservice/adapter/include/permission/permission_validator.h @@ -27,9 +27,11 @@ public: // check whether the client process have enough privilege to share data with the other devices. // tokenId: client process tokenId API_EXPORT bool CheckSyncPermission(uint32_t tokenId); + API_EXPORT bool IsCloudConfigPermit(uint32_t tokenId); private: static constexpr const char *DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; + static constexpr const char *CLOUD_DATA_CONFIG = "ohos.permission.CLOUDDATA_CONFIG"; }; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/adapter/permission/BUILD.gn b/services/distributeddataservice/adapter/permission/BUILD.gn index 48e7792729a88cd4c0a65108c0645116ba273ced..2c47874654b0952eb3fd89fc8deb162c446fade3 100644 --- a/services/distributeddataservice/adapter/permission/BUILD.gn +++ b/services/distributeddataservice/adapter/permission/BUILD.gn @@ -35,7 +35,7 @@ ohos_static_library("distributeddata_permission_static") { external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/services/distributeddataservice/adapter/permission/src/permission_validator.cpp b/services/distributeddataservice/adapter/permission/src/permission_validator.cpp index 93218763ca61ba9e4d1a5ea35692fabb7ce5a8fd..f4f58c6d9a5cd17c3b6b9bcc2f859f4cff666e39 100644 --- a/services/distributeddataservice/adapter/permission/src/permission_validator.cpp +++ b/services/distributeddataservice/adapter/permission/src/permission_validator.cpp @@ -42,5 +42,12 @@ bool PermissionValidator::CheckSyncPermission(uint32_t tokenId) ZLOGE("token:0x%{public}x", tokenId); return false; } + +bool PermissionValidator::IsCloudConfigPermit(uint32_t tokenId) +{ + auto permit = AccessTokenKit::VerifyAccessToken(tokenId, CLOUD_DATA_CONFIG); + ZLOGD("cloud permit: %{public}d", permit); + return permit == PERMISSION_GRANTED; +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/adapter/permission/test/BUILD.gn b/services/distributeddataservice/adapter/permission/test/BUILD.gn index a19f4c30fdd885df876c31c845aa60eb9a77ed61..509f49b312a16d8c8a3cd5e9dcca8793a34bc74a 100644 --- a/services/distributeddataservice/adapter/permission/test/BUILD.gn +++ b/services/distributeddataservice/adapter/permission/test/BUILD.gn @@ -42,7 +42,7 @@ ohos_unittest("PermissionValidatorTest") { "//third_party/googletest:gtest_main", ] - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + external_deps = [ "hilog:libhilog" ] defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/test/BUILD.gn b/services/distributeddataservice/adapter/test/BUILD.gn index b716360d7b795f9b46b48331f44193708d313a68..f85ada83e4e6922db5824e910fc8c5e187a4b800 100755 --- a/services/distributeddataservice/adapter/test/BUILD.gn +++ b/services/distributeddataservice/adapter/test/BUILD.gn @@ -19,9 +19,14 @@ group("unittest") { deps += [ "../account/test:unittest", - "../autils/test:unittest", "../communicator/test:unittest", "../dfx/test:unittest", "../permission/test:unittest", ] } + +group("fuzztest") { + testonly = true + + deps = [ "../communicator/test/fuzztest:fuzztest" ] +} diff --git a/services/distributeddataservice/adapter/utils/BUILD.gn b/services/distributeddataservice/adapter/utils/BUILD.gn index b57d430bb0024e90d3d89eb9714d1db9e93e3422..6442a139ccbf9ea9f26422f6cef0c13a1955be23 100755 --- a/services/distributeddataservice/adapter/utils/BUILD.gn +++ b/services/distributeddataservice/adapter/utils/BUILD.gn @@ -35,7 +35,7 @@ ohos_static_library("distributeddata_utils_static") { external_deps = [ "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index 6fa9ba6aa580f0f6ca556fb9c7deea240e25ef41..607c673207dabb0b9bc30aee8731d4b4a6dcf4e8 100644 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -30,7 +30,7 @@ ohos_prebuilt_etc("distributed_data.cfg") { } ohos_sa_profile("distributeddata_profile") { - sources = [ "../sa_profile/1301.xml" ] + sources = [ "../sa_profile/1301.json" ] part_name = "datamgr_service" } @@ -118,10 +118,10 @@ ohos_shared_library("distributeddataservice") { "bundle_framework:appexecfwk_core", "c_utils:utils", "dataclassification:data_transit_mgr", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hitrace_native:libhitracechain", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", "ipc:ipc_core", "kv_store:distributeddata_inner", "safwk:system_ability_fwk", diff --git a/services/distributeddataservice/app/distributed_data.cfg b/services/distributeddataservice/app/distributed_data.cfg index 3c0eb54e128659550dea6f619eab4b84b10c49d2..fbc1350a9b9f8f2d89a85cce776546d132e65fae 100644 --- a/services/distributeddataservice/app/distributed_data.cfg +++ b/services/distributeddataservice/app/distributed_data.cfg @@ -15,9 +15,9 @@ ], "services":[{ "name" : "distributeddata", - "path" : ["/system/bin/sa_main","/system/profile/distributeddata.xml"], + "path" : ["/system/bin/sa_main","/system/profile/distributeddata.json"], "uid" : "ddms", - "gid" : ["system","shell","readproc","ddms"], + "gid" : ["system","shell","readproc","ddms","dfs_share"], "writepid":[ "/dev/cpuset/foreground/tasks", "/dev/stune/foreground/tasks", diff --git a/services/distributeddataservice/app/src/checker/BUILD.gn b/services/distributeddataservice/app/src/checker/BUILD.gn index 1f59492cac8717e5eb1cff7ae28164ceff672cd3..0cb0a4f85db0286e026232eb390b4055408e8fe2 100644 --- a/services/distributeddataservice/app/src/checker/BUILD.gn +++ b/services/distributeddataservice/app/src/checker/BUILD.gn @@ -40,7 +40,7 @@ ohos_static_library("distributeddata_checker_static") { "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", "samgr:samgr_proxy", ] diff --git a/services/distributeddataservice/app/src/dump_helper.cpp b/services/distributeddataservice/app/src/dump_helper.cpp index f718164e8eb770a0683fa729d6b099a650485b33..0c5f77a566968d39b35383dea67bcd9d0a00dd61 100644 --- a/services/distributeddataservice/app/src/dump_helper.cpp +++ b/services/distributeddataservice/app/src/dump_helper.cpp @@ -112,25 +112,25 @@ void DumpHelper::ShowHelp(int fd) { std::string result; result.append("Usage:dump [options]\n") - .append("Description:\n") - .append(CMD_USER_INFO) - .append(" ") - .append("dump all user information in the system\n") - .append(CMD_APP_INFO) - .append(" ") - .append("dump list of all app information in the system\n") - .append(CMD_APP_INFO) - .append(" [appID] ") - .append("dump information about the specified app in the system\n") - .append(CMD_STORE_INFO) - .append(" ") - .append("dump list of all store information in the system\n") - .append(CMD_STORE_INFO) - .append(" [storeID] ") - .append("dump information about the specified store in the system\n") - .append(CMD_ERROR_INFO) - .append(" ") - .append("dump the recent errors information in the system\n"); + .append("Description:\n") + .append(CMD_USER_INFO) + .append(" ") + .append("dump all user information in the system\n") + .append(CMD_APP_INFO) + .append(" ") + .append("dump list of all app information in the system\n") + .append(CMD_APP_INFO) + .append(" [appID] ") + .append("dump information about the specified app in the system\n") + .append(CMD_STORE_INFO) + .append(" ") + .append("dump list of all store information in the system\n") + .append(CMD_STORE_INFO) + .append(" [storeID] ") + .append("dump information about the specified store in the system\n") + .append(CMD_ERROR_INFO) + .append(" ") + .append("dump the recent errors information in the system\n"); dprintf(fd, "%s\n", result.c_str()); } diff --git a/services/distributeddataservice/app/src/feature_stub_impl.cpp b/services/distributeddataservice/app/src/feature_stub_impl.cpp index 01171f9513cfb78b60cc0e22d16dffa5e00d3954..f1f52b91366ed6ec82223d1b2c78e10b85e22ab8 100644 --- a/services/distributeddataservice/app/src/feature_stub_impl.cpp +++ b/services/distributeddataservice/app/src/feature_stub_impl.cpp @@ -13,6 +13,9 @@ * limitations under the License. */ #include "feature_stub_impl.h" + +#include "bootstrap.h" +#include "ipc_skeleton.h" namespace OHOS::DistributedData { FeatureStubImpl::FeatureStubImpl(std::shared_ptr feature) : featureImpl_(std::move(feature)) @@ -37,7 +40,8 @@ int32_t FeatureStubImpl::OnInitialize(std::shared_ptr executor) if (featureImpl_ == nullptr) { return -1; } - featureImpl_->OnExecutor(std::move(executor)); + featureImpl_->OnBind({ Bootstrap::GetInstance().GetProcessLabel(), + static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor)}); return featureImpl_->OnInitialize(); } @@ -57,6 +61,14 @@ int32_t FeatureStubImpl::OnAppUninstall(const std::string &bundleName, int32_t u return featureImpl_->OnAppUninstall(bundleName, user, index, tokenId); } +int32_t FeatureStubImpl::OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) +{ + if (featureImpl_ == nullptr) { + return -1; + } + return featureImpl_->OnAppUpdate(bundleName, user, index, tokenId); +} + int32_t FeatureStubImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { if (featureImpl_ == nullptr) { diff --git a/services/distributeddataservice/app/src/feature_stub_impl.h b/services/distributeddataservice/app/src/feature_stub_impl.h index 6fc9c824b5960dd27f1001c66aee93ae0285e4bd..b00646bc0493d9ccf4d3f5464be2f975bea78458 100644 --- a/services/distributeddataservice/app/src/feature_stub_impl.h +++ b/services/distributeddataservice/app/src/feature_stub_impl.h @@ -33,6 +33,7 @@ public: int32_t OnInitialize(std::shared_ptr executor); int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName); int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); + int32_t OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account); int32_t Online(const std::string &device); diff --git a/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn b/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn index 61f307283ca76fb291cbaf2e631358958f68d5a3..eae2ee8337b39abf79546c3d5a6a07180de53fa7 100755 --- a/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn +++ b/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn @@ -23,7 +23,6 @@ ohos_static_library("distributeddata_flowctrl_static") { "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//third_party/json/single_include", - "//commonlibrary/c_utils/base/include", ] cflags_cc = [ "-fvisibility=hidden" ] diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index ee5ef9e7b90aebcd78d88e1f1d143ab652da1c31..df12f123cd393d3f784814b725c71f5fb23cfcb7 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -25,7 +25,6 @@ #include "checker/checker_manager.h" #include "communication_provider.h" #include "config_factory.h" -#include "constant.h" #include "crypto_manager.h" #include "device_manager_adapter.h" #include "device_matrix.h" @@ -50,6 +49,7 @@ #include "upgrade.h" #include "upgrade_manager.h" #include "user_delegate.h" +#include "utils/anonymous.h" #include "utils/block_integer.h" #include "utils/crypto.h" @@ -68,12 +68,24 @@ KvStoreDataService::KvStoreDataService(bool runOnCreate) : SystemAbility(runOnCreate), mutex_(), clients_() { ZLOGI("begin."); + if (executors_ == nullptr) { + constexpr size_t MAX = 12; + constexpr size_t MIN = 5; + executors_ = std::make_shared(MAX, MIN); + DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared(executors_)); + } } KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate) : SystemAbility(systemAbilityId, runOnCreate), mutex_(), clients_() { ZLOGI("begin"); + if (executors_ == nullptr) { + constexpr size_t MAX = 12; + constexpr size_t MIN = 5; + executors_ = std::make_shared(MAX, MIN); + DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared(executors_)); + } } KvStoreDataService::~KvStoreDataService() @@ -91,7 +103,6 @@ void KvStoreDataService::Initialize() #endif auto communicator = std::make_shared(RouteHeadHandlerImpl::Create); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); - DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared(executors_)); ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); AppDistributedKv::CommunicationProvider::GetInstance(); @@ -150,7 +161,7 @@ void KvStoreDataService::LoadFeatures() { ZLOGI("begin."); auto features = FeatureSystem::GetInstance().GetFeatureName(FeatureSystem::BIND_NOW); - for (auto &feature : features) { + for (auto const &feature : features) { GetFeatureInterface(feature); } } @@ -233,9 +244,6 @@ void KvStoreDataService::OnStart() { ZLOGI("distributeddata service onStart"); EventCenter::Defer defer; - constexpr size_t MAX = 12; - constexpr size_t MIN = 5; - executors_ = std::make_shared(MAX, MIN); Reporter::GetInstance()->SetThreadPool(executors_); AccountDelegate::GetInstance()->BindExecutor(executors_); AccountDelegate::GetInstance()->RegisterHashFunc(Crypto::Sha256); @@ -303,7 +311,7 @@ void KvStoreDataService::StartService() DumpHelper::GetInstance().AddErrorInfo("StartService: Service publish failed."); } // Initialize meta db delegate manager. - KvStoreMetaManager::GetInstance().SubscribeMeta(KvStoreMetaRow::KEY_PREFIX, + KvStoreMetaManager::GetInstance().SubscribeMeta(StoreMetaData::GetKey({}), [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { OnStoreMetaChanged(key, value, flag); }); @@ -332,7 +340,7 @@ void KvStoreDataService::OnStoreMetaChanged( StoreMetaData metaData; metaData.Unmarshall({ value.begin(), value.end() }); ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(), - metaData.storeId.c_str(), metaData.isDirty); + Anonymous::Change(metaData.storeId).c_str(), metaData.isDirty); auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (metaData.deviceId != deviceId || metaData.deviceId.empty()) { ZLOGD("ignore other device change or invalid meta device"); @@ -342,7 +350,7 @@ void KvStoreDataService::OnStoreMetaChanged( if (!metaData.isDirty || metaData.appType != HARMONY_APP) { return; } - ZLOGI("dirty kv store. storeId:%{public}s", metaData.storeId.c_str()); + ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str()); } bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( @@ -651,67 +659,43 @@ void KvStoreDataService::OnDeviceOnline(const AppDistributedKv::DeviceInfo &info }); } -void KvStoreDataService::OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info) +void KvStoreDataService::OnDeviceOffline(const AppDistributedKv::DeviceInfo &info) { if (info.uuid.empty()) { return; } features_.ForEachCopies([&info](const auto &key, sptr &value) { - value->OnReady(info.uuid); + value->Offline(info.uuid); return false; }); } -bool DbMetaCallbackDelegateMgr::GetKvStoreDiskSize(const std::string &storeId, uint64_t &size) +void KvStoreDataService::OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info) { - if (IsDestruct()) { - return false; + if (info.uuid.empty()) { + return; } - DistributedDB::DBStatus ret = delegate_->GetKvStoreDiskSize(storeId, size); - return (ret == DistributedDB::DBStatus::OK); + features_.ForEachCopies([&info](const auto &key, sptr &value) { + value->OnReady(info.uuid); + return false; + }); } -void DbMetaCallbackDelegateMgr::GetKvStoreKeys(std::vector &dbStats) +int32_t KvStoreDataService::OnUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) { - if (IsDestruct()) { - return; - } - DistributedDB::DBStatus dbStatusTmp; - Option option {.createIfNecessary = true, .isMemoryDb = false, .isEncryptedDb = false}; - DistributedDB::KvStoreNbDelegate *nbDelegate = nullptr; - delegate_->GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, - [&nbDelegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *delegate) { - nbDelegate = delegate; - dbStatusTmp = dbStatus; + features_.ForEachCopies( + [bundleName, user, index, tokenId](const auto &, sptr &value) { + value->OnAppUninstall(bundleName, user, index, tokenId); + return false; }); - - if (dbStatusTmp != DistributedDB::DBStatus::OK) { - return; - } - DistributedDB::Key dbKey = KvStoreMetaRow::GetKeyFor(""); - std::vector entries; - nbDelegate->GetEntries(dbKey, entries); - if (entries.empty()) { - delegate_->CloseKvStore(nbDelegate); - return; - } - for (auto const &entry : entries) { - std::string key = std::string(entry.key.begin(), entry.key.end()); - std::vector out; - Split(key, Constant::KEY_SEPARATOR, out); - if (out.size() >= VECTOR_SIZE) { - StoreInfo storeInfo = {out[USER_ID], out[APP_ID], out[STORE_ID]}; - dbStats.push_back(std::move(storeInfo)); - } - } - delegate_->CloseKvStore(nbDelegate); + return 0; } -int32_t KvStoreDataService::OnUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) +int32_t KvStoreDataService::OnUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) { features_.ForEachCopies( [bundleName, user, index, tokenId](const auto &, sptr &value) { - value->OnAppUninstall(bundleName, user, index, tokenId); + value->OnAppUpdate(bundleName, user, index, tokenId); return false; }); return 0; diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index fae1dbac481000ad378d095995a224e78cf46253..12f949b2ef361cc6da116cfc8ecbad706d17d013 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -21,7 +21,6 @@ #include #include "account_delegate.h" -#include "constant.h" #include "dump_helper.h" #include "feature_stub_impl.h" #include "ikvstore_data_service.h" @@ -72,10 +71,14 @@ public: void OnDeviceOnline(const AppDistributedKv::DeviceInfo &info); + void OnDeviceOffline(const AppDistributedKv::DeviceInfo &info); + void OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info); int32_t OnUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); + int32_t OnUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); + private: void NotifyAccountEvent(const AccountEventInfo &eventInfo); class KvStoreClientDeathObserverImpl { @@ -119,7 +122,7 @@ private: Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId); bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); - void ResolveAutoLaunchCompatible(const StoreMetaData &meta, const std::string &identifier); + void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier); static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, DistributedDB::KvStoreNbDelegate::Option &dbOption); @@ -135,40 +138,5 @@ private: std::shared_ptr deviceInnerListener_; std::shared_ptr executors_; }; - -class DbMetaCallbackDelegateMgr : public DbMetaCallbackDelegate { -public: - using Option = DistributedDB::KvStoreNbDelegate::Option; - virtual ~DbMetaCallbackDelegateMgr() {} - - explicit DbMetaCallbackDelegateMgr(DistributedDB::KvStoreDelegateManager *delegate) - : delegate_(delegate) {} - bool GetKvStoreDiskSize(const std::string &storeId, uint64_t &size) override; - void GetKvStoreKeys(std::vector &dbStats) override; - bool IsDestruct() - { - return delegate_ == nullptr; - } - -private: - void Split(const std::string &str, const std::string &delimiter, std::vector &out) - { - size_t start; - size_t end = 0; - while ((start = str.find_first_not_of(delimiter, end)) != std::string::npos) { - end = str.find(delimiter, start); - if (end == std::string::npos) { - end = str.size(); - } - out.push_back(str.substr(start, end - start)); - } - } - - DistributedDB::KvStoreDelegateManager *delegate_ {}; - static const inline int USER_ID = 0; - static const inline int APP_ID = 1; - static const inline int STORE_ID = 2; - static const inline int VECTOR_SIZE = 2; -}; } #endif // KVSTORE_DATASERVICE_H diff --git a/services/distributeddataservice/app/src/kvstore_device_listener.cpp b/services/distributeddataservice/app/src/kvstore_device_listener.cpp index 4d155a17d4ae55efcf7db093de8e7c6ad80ba39a..be0e9a7943cd9408b05d1577a26ed1d40f36930e 100644 --- a/services/distributeddataservice/app/src/kvstore_device_listener.cpp +++ b/services/distributeddataservice/app/src/kvstore_device_listener.cpp @@ -26,6 +26,8 @@ void KvStoreDeviceListener::OnDeviceChanged( if (type == AppDistributedKv::DeviceChangeType::DEVICE_ONLINE) { kvStoreDataService_.SetCompatibleIdentify(info); kvStoreDataService_.OnDeviceOnline(info); + } else if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + kvStoreDataService_.OnDeviceOffline(info); } else if (type == AppDistributedKv::DeviceChangeType::DEVICE_ONREADY) { kvStoreDataService_.OnDeviceOnReady(info); } diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 7fb54c86a5cda403e517ca0575dcdaf15e2d9363..98d02fb551b8a7346879a0078ab670516b13f661 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -24,11 +24,10 @@ #include "bootstrap.h" #include "communication_provider.h" #include "communication_strategy.h" -#include "constant.h" #include "crypto_manager.h" #include "device_manager_adapter.h" #include "device_matrix.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "dump_helper.h" #include "eventcenter/event_center.h" #include "kvstore_data_service.h" @@ -38,6 +37,7 @@ #include "utils/anonymous.h" #include "utils/block_integer.h" #include "utils/crypto.h" +#include "utils/ref_count.h" namespace OHOS { namespace DistributedKv { @@ -108,27 +108,28 @@ void KvStoreMetaManager::InitBroadcast() void KvStoreMetaManager::InitDeviceOnline() { ZLOGI("observer matrix online event."); + using DBStatuses = std::map; EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_ONLINE, [this](const Event &event) { - const MatrixEvent &matrixEvent = static_cast(event); + auto &matrixEvent = static_cast(event); auto mask = matrixEvent.GetMask(); auto deviceId = matrixEvent.GetDeviceId(); auto store = GetMetaKvStore(); + auto onComplete = [deviceId, mask, refCount = matrixEvent.StealRefCount()](const DBStatuses &) mutable { + ZLOGD("matrix 0x%{public}08x device:%{public}s online", mask, Anonymous::Change(deviceId).c_str()); + auto finEvent = std::make_unique(DeviceMatrix::MATRIX_META_FINISHED, deviceId, mask); + finEvent->SetRefCount(std::move(refCount)); + DeviceMatrix::GetInstance().OnExchanged(deviceId, DeviceMatrix::META_STORE_MASK); + EventCenter::GetInstance().PostEvent(std::move(finEvent)); + }; if (((mask & DeviceMatrix::META_STORE_MASK) != 0) && store != nullptr) { - auto onComplete = [deviceId, mask](const std::map &) { - ZLOGI("online sync complete"); - auto event = std::make_unique(DeviceMatrix::MATRIX_META_FINISHED, deviceId, mask); - DeviceMatrix::GetInstance().OnExchanged(deviceId, DeviceMatrix::META_STORE_MASK); - EventCenter::GetInstance().PostEvent(std::move(event)); - }; auto status = store->Sync({ deviceId }, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete); if (status == OK) { return; } - ZLOGW("meta db sync error %{public}d.", status); + ZLOGW("meta online sync error 0x%{public}08x device:%{public}s %{public}d", mask, + Anonymous::Change(deviceId).c_str(), status); } - - auto finEvent = std::make_unique(DeviceMatrix::MATRIX_META_FINISHED, deviceId, mask); - EventCenter::GetInstance().PostEvent(std::move(finEvent)); + onComplete({ }); }); } @@ -156,7 +157,7 @@ void KvStoreMetaManager::InitMetaData() data.isEncrypt = false; data.storeType = KvStoreType::SINGLE_VERSION; data.schema = ""; - data.storeId = Constant::SERVICE_META_DB_NAME; + data.storeId = Bootstrap::GetInstance().GetMetaDBName(); data.account = accountId; data.uid = static_cast(uid); data.version = META_STORE_VERSION; @@ -366,7 +367,9 @@ void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(const App DeviceMatrix::GetInstance().Offline(info.uuid); break; case AppDistributedKv::DeviceChangeType::DEVICE_ONLINE: - DeviceMatrix::GetInstance().Online(info.uuid); + DeviceMatrix::GetInstance().Online(info.uuid, RefCount([deviceId = info.uuid]() { + DmAdapter::GetInstance().NotifyReadyEvent(deviceId); + })); break; default: ZLOGI("flag:%{public}d", type); @@ -394,6 +397,7 @@ size_t KvStoreMetaManager::GetSyncDataSize(const std::string &deviceId) return metaDelegate->GetSyncDataSize(deviceId); } + void KvStoreMetaManager::BindExecutor(std::shared_ptr executors) { executors_ = executors; diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index 9fb69912dea7e1fd23d9d9a9014fb3d98de92435..db977717e079bc6fc0db86bbf57f9e178548fbc7 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -83,7 +83,7 @@ private: void OnChange(const DistributedDB::KvStoreChangedData &data) override; std::map handlerMap_; private: - void HandleChanges(CHANGE_FLAG flag, const std::list &list); + void HandleChanges(CHANGE_FLAG flag, const std::list &entries); }; static constexpr int32_t RETRY_MAX_TIMES = 100; diff --git a/services/distributeddataservice/app/src/security/security.cpp b/services/distributeddataservice/app/src/security/security.cpp index 0ff95061f4be0153fab9eb1258e80207d5febbe9..61c84b149ef383c0b9d9ae6e8ce2367ffd4685a2 100644 --- a/services/distributeddataservice/app/src/security/security.cpp +++ b/services/distributeddataservice/app/src/security/security.cpp @@ -14,11 +14,10 @@ */ #include "security.h" -#include #include +#include #include #include -#include "constant.h" #include "dev_slinfo_mgr.h" #include "device_manager_adapter.h" #include "log_print.h" @@ -162,8 +161,8 @@ Sensitive Security::GetSensitiveByUuid(const std::string &uuid) const auto it = devicesUdid_.Find(uuid); if (!it.first) { executors_->Execute([this, uuid]() { - auto it = devicesUdid_.Find(uuid); - if (it.first) { + auto iter = devicesUdid_.Find(uuid); + if (iter.first) { return; } auto udid = DistributedData::DeviceManagerAdapter::GetInstance().ToUDID(uuid); diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index 3d4db8d40f9e03db9f5f769a68348d65501be79d..584fb918fc122c2d84be525506b2bec506e2eee4 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -116,8 +116,9 @@ void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegat auto syncIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId); - ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s", tuple.storeId.c_str(), - compatibleUser.c_str(), DistributedData::Serializable::Marshall(devices).c_str()); + ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s", + Anonymous::Change(tuple.storeId).c_str(), compatibleUser.c_str(), + DistributedData::Serializable::Marshall(devices).c_str()); storeDelegate->SetEqualIdentifier(syncIdentifier, devices); } diff --git a/services/distributeddataservice/app/src/task_manager.cpp b/services/distributeddataservice/app/src/task_manager.cpp index 1332fc203d99d6a8634ee8e5f2a237c4670cf245..ec06928edbcd050b2e9112248b7f242cf4c8504d 100644 --- a/services/distributeddataservice/app/src/task_manager.cpp +++ b/services/distributeddataservice/app/src/task_manager.cpp @@ -15,9 +15,8 @@ #include "task_manager.h" namespace OHOS::DistributedData { -TaskManager::TaskManager(std::shared_ptr executors) +TaskManager::TaskManager(std::shared_ptr executors) : executors_(executors) { - executors_ = executors; } TaskManager::~TaskManager() diff --git a/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/services/distributeddataservice/app/src/uninstaller/BUILD.gn index 04daeef74ee9c727d74f853a64e6476bb4b0f640..54196c83138db01c24ff501e6b04b7400148fc3d 100755 --- a/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -42,14 +42,12 @@ ohos_static_library("distributeddata_uninstaller_static") { ] external_deps = [ + "ability_base:want", "bundle_framework:appexecfwk_base", "c_utils:utils", - - # "ces:libcommonevent", - "ability_base:want", "common_event_service:cesfwk_innerkits", "dataclassification:data_transit_mgr", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp index 81072e469f43c694d6a6ddfd9457c4d238e79833..01c06c4c09e91c8532686d9cc1c62a606d1631d4 100644 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp @@ -27,7 +27,8 @@ #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "permit_delegate.h" -#include "utils/block_integer.h" +#include "cloud/cloud_info.h" +#include "utils/anonymous.h" namespace OHOS::DistributedKv { using namespace OHOS::AppDistributedKv; @@ -37,27 +38,71 @@ using namespace OHOS::DistributedData; using namespace OHOS::EventFwk; UninstallEventSubscriber::UninstallEventSubscriber(const CommonEventSubscribeInfo &info, - UninstallEventCallback callback) - : CommonEventSubscriber(info), callback_(callback) -{} + KvStoreDataService *kvStoreDataService) + : CommonEventSubscriber(info), kvStoreDataService_(kvStoreDataService) +{ + callbacks_ = { { CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED, &UninstallEventSubscriber::OnUninstall }, + { OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED, &UninstallEventSubscriber::OnUninstall }, + { CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED, &UninstallEventSubscriber::OnUpdate } }; +} void UninstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) { ZLOGI("Intent Action Rec"); Want want = event.GetWant(); std::string action = want.GetAction(); - if (action != CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED && - action != OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { - return; + auto it = callbacks_.find(action); + if (it != callbacks_.end()) { + std::string bundleName = want.GetElement().GetBundleName(); + int32_t userId = want.GetIntParam(USER_ID, -1); + int32_t appIndex = want.GetIntParam(SANDBOX_APP_INDEX, 0); + ZLOGI("bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); + (this->*(it->second))(bundleName, userId, appIndex); } +} - std::string bundleName = want.GetElement().GetBundleName(); - int32_t userId = want.GetIntParam(USER_ID, -1); - int32_t appIndex = want.GetIntParam(SANDBOX_APP_INDEX, 0); - ZLOGI("bundleName:%s, user:%d, appIndex:%d", bundleName.c_str(), userId, appIndex); - callback_(bundleName, userId, appIndex); +void UninstallEventSubscriber::OnUninstall(const std::string &bundleName, int32_t userId, int32_t appIndex) +{ + kvStoreDataService_->OnUninstall(bundleName, userId, appIndex, IPCSkeleton::GetCallingTokenID()); + std::string prefix = StoreMetaData::GetPrefix( + { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(userId), "default", bundleName }); + std::vector storeMetaData; + if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData)) { + ZLOGE("load meta failed!"); + return; + } + for (auto &meta : storeMetaData) { + if (meta.instanceId == appIndex && !meta.appId.empty() && !meta.storeId.empty()) { + ZLOGI("uninstalled bundleName:%{public}s stordId:%{public}s", bundleName.c_str(), + Anonymous::Change(meta.storeId).c_str()); + MetaDataManager::GetInstance().DelMeta(meta.GetKey()); + 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()); + } + } } +void UninstallEventSubscriber::OnUpdate(const std::string &bundleName, int32_t userId, int32_t appIndex) +{ + kvStoreDataService_->OnUpdate(bundleName, userId, appIndex, IPCSkeleton::GetCallingTokenID()); + std::string prefix = StoreMetaData::GetPrefix( + { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(userId), "default", bundleName }); + std::vector storeMetaData; + if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData)) { + ZLOGE("load meta failed!"); + return; + } + for (auto &meta : storeMetaData) { + if (meta.instanceId == appIndex && !meta.appId.empty() && !meta.storeId.empty()) { + ZLOGI("updated bundleName:%{public}s, stordId:%{public}s", bundleName.c_str(), + Anonymous::Change(meta.storeId).c_str()); + MetaDataManager::GetInstance().DelMeta(CloudInfo::GetSchemaKey(meta), true); + } + } +} UninstallerImpl::~UninstallerImpl() { ZLOGD("destruct"); @@ -84,34 +129,16 @@ Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService, std::shared MatchingSkills matchingSkills; matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); CommonEventSubscribeInfo info(matchingSkills); - auto callback = [kvStoreDataService](const std::string &bundleName, int32_t userId, int32_t appIndex) { - kvStoreDataService->OnUninstall(bundleName, userId, appIndex, IPCSkeleton::GetCallingTokenID()); - std::string prefix = StoreMetaData::GetPrefix({ DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, - std::to_string(userId), "default", bundleName }); - std::vector storeMetaData; - if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData)) { - ZLOGE("load meta failed!"); - return; - } - for (auto &meta : storeMetaData) { - if (meta.instanceId == appIndex && !meta.appId.empty() && !meta.storeId.empty()) { - ZLOGI("uninstalled bundleName:%s, stordId:%s", bundleName.c_str(), meta.storeId.c_str()); - MetaDataManager::GetInstance().DelMeta(meta.GetKey()); - 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()); - } - } - }; - auto subscriber = std::make_shared(info, callback); + + auto subscriber = std::make_shared(info, kvStoreDataService); subscriber_ = subscriber; executors_ = executors; executors_->Execute(GetTask()); return Status::SUCCESS; } + ExecutorPool::Task UninstallerImpl::GetTask() { return [this] { @@ -120,7 +147,7 @@ ExecutorPool::Task UninstallerImpl::GetTask() ZLOGI("subscribe uninstall event success"); return; } - ZLOGE("subscribe uninstall event fail, try times:%d", retryTime_); + ZLOGE("subscribe common event fail, try times:%{public}d", retryTime_); if (retryTime_++ >= RETRY_TIME) { return; } diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h index 50ec5fe33d53a09470fb5217b4bee88a1c70c9ef..3b8a3a7d7544e94f768453f1ea2b5c4535e360be 100644 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h @@ -21,12 +21,11 @@ #include "uninstaller.h" namespace OHOS::DistributedKv { -using UninstallEventCallback = std::function; - class UninstallEventSubscriber : public EventFwk::CommonEventSubscriber { public: - UninstallEventSubscriber(const EventFwk::CommonEventSubscribeInfo &info, - UninstallEventCallback callback); +using UninstallEventCallback = void (UninstallEventSubscriber::*) + (const std::string &bundleName, int32_t userId, int32_t appIndex); + UninstallEventSubscriber(const EventFwk::CommonEventSubscribeInfo &info, KvStoreDataService *kvStoreDataService); ~UninstallEventSubscriber() {} void OnReceiveEvent(const EventFwk::CommonEventData &event) override; @@ -34,10 +33,15 @@ public: private: static constexpr const char *USER_ID = "userId"; static constexpr const char *SANDBOX_APP_INDEX = "sandbox_app_index"; - UninstallEventCallback callback_; + void OnUninstall(const std::string &bundleName, int32_t userId, int32_t appIndex); + void OnUpdate(const std::string &bundleName, int32_t userId, int32_t appIndex); + std::map callbacks_; + KvStoreDataService *kvStoreDataService_; }; + class UninstallerImpl : public Uninstaller { public: + UninstallerImpl() = default; ~UninstallerImpl(); Status Init(KvStoreDataService *kvStoreDataService, std::shared_ptr executors) override; @@ -47,10 +51,10 @@ public: private: static constexpr int32_t RETRY_TIME = 300; static constexpr int32_t RETRY_INTERVAL = 100; - int32_t retryTime_; + int32_t retryTime_ = 0; ExecutorPool::Task GetTask(); std::shared_ptr subscriber_ {}; - std::shared_ptr executors_; + std::shared_ptr executors_ {}; }; } // namespace OHOS::DistributedKv #endif // DISTRIBUTEDDATAMGR_UNINSTALLER_IMPL_H diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index 3ce6b41dd8e7d85ef5a82b764a513797a1eb192d..f471e188e2aad5bb64b0a3904fa923d27d1aa264 100644 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -87,10 +87,10 @@ ohos_unittest("KvStoreDataServiceTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hitrace_native:libhitracechain", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -138,7 +138,7 @@ ohos_unittest("SessionManagerTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -177,7 +177,7 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", diff --git a/services/distributeddataservice/app/test/fuzztest/BUILD.gn b/services/distributeddataservice/app/test/fuzztest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d7c29a7ae886e1c2e0f1b8a4b0e3b506c6d385d1 --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/BUILD.gn @@ -0,0 +1,21 @@ +# 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. + +import("//build/ohos.gni") + +######################################################################################### +group("fuzztest") { + testonly = true + + deps = [ "dataservicestub_fuzzer:fuzztest" ] +} diff --git a/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..3e594bee1c03cdb18fbefca2eedb3b5338bb6e4e --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn @@ -0,0 +1,116 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("DataServiceStubFuzzTest") { + module_out_path = "datamgr_service/app" + + include_dirs = [ + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/config/include", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/directory/include", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/matrix/include", + "${data_service_path}/app/src", + "${data_service_path}/app/src/backup_rule/include", + "${data_service_path}/app/src/checker", + "${data_service_path}/app/src/flowctrl_manager", + "${data_service_path}/app/src/security", + "${data_service_path}/app/src/session_manager", + "${data_service_path}/app/src/uninstaller", + "${data_service_path}/framework/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/kvdb", + "${data_service_path}/adapter/include/account", + "${data_service_path}/adapter/include/permission", + "${data_service_path}/adapter/include/uninstaller", + "${data_service_path}/adapter/include/broadcaster", + "${data_service_path}/adapter/include/utils", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/adapter/include", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "${distributedfilejs_path}/interfaces/kits/js/src/mod_securitylabel", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/app/test/fuzztest/dataservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/app/src/dump_helper.cpp", + "${data_service_path}/app/src/feature_stub_impl.cpp", + "${data_service_path}/app/src/kvstore_account_observer.cpp", + "${data_service_path}/app/src/kvstore_data_service.cpp", + "${data_service_path}/app/src/kvstore_device_listener.cpp", + "${data_service_path}/app/src/kvstore_meta_manager.cpp", + "${data_service_path}/app/src/security/security.cpp", + "${data_service_path}/app/src/security/sensitive.cpp", + "${data_service_path}/app/src/session_manager/route_head_handler_impl.cpp", + "${data_service_path}/app/src/session_manager/session_manager.cpp", + "${data_service_path}/app/src/session_manager/upgrade_manager.cpp", + "${data_service_path}/app/src/task_manager.cpp", + "dataservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/broadcaster:distributeddata_broadcaster_static", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/app/src/checker:distributeddata_checker_static", + "${data_service_path}/app/src/flowctrl_manager:distributeddata_flowctrl_static", + "${data_service_path}/app/src/uninstaller:distributeddata_uninstaller_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "dataclassification:data_transit_mgr", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":DataServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/corpus/init b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.cpp b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5164c9424b81e5de3a566e98209b206d5520b4d --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.cpp @@ -0,0 +1,57 @@ +/* + * 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 "dataservicestub_fuzzer.h" + +#include +#include + +#include "kvstore_data_service.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DistributedKv; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedKv.IKvStoreDataService"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 10; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + MessageOption option; + std::shared_ptr kvStoreDataServiceStub = std::make_shared(); + kvStoreDataServiceStub->OnRemoteRequest(code, request, reply, option); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.h b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..02e3b8df3e7d6d285bb49a42ea9bf140c5914b5d --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/dataservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_DATA_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_DATA_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "dataservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_DATA_SERVICE_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/project.xml b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/app/test/unittest/kvstore_flowctrl_manager_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_flowctrl_manager_test.cpp index e2e662be9eeb8159ee15cba707b0514668e8b864..506f32c1a22a9af8b09437171980bc9744aca10f 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_flowctrl_manager_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_flowctrl_manager_test.cpp @@ -18,11 +18,11 @@ #include "flowctrl_manager/kvstore_flowctrl_manager.h" #include #include -#include "time_utils.h" - +#include using namespace testing::ext; using namespace OHOS::DistributedKv; using namespace OHOS; +using namespace std::chrono; class KvStoreFlowCtrlManagerTest : public testing::Test { public: @@ -152,11 +152,11 @@ HWTEST_F(KvStoreFlowCtrlManagerTest, KvStoreFlowCtrlManagerTest006, TestSize.Lev auto ptr = std::make_shared(OPERATION_BURST_CAPACITY, OPERATION_SUSTAINED_CAPACITY); int arr[2] = {0, 0}; uint64_t curTime = 0; - uint64_t lastTime = TimeUtils::CurrentTimeMicros(); + uint64_t lastTime = duration_cast(steady_clock::now().time_since_epoch()).count(); for (int i = 0; i < 10001; i++) { arr[ptr->IsTokenEnough()]++; while (true) { - curTime = TimeUtils::CurrentTimeMicros(); + curTime = duration_cast(steady_clock::now().time_since_epoch()).count(); if ((curTime - lastTime) > 1000) { lastTime = curTime; break; diff --git a/services/distributeddataservice/framework/BUILD.gn b/services/distributeddataservice/framework/BUILD.gn index 98a05fb2a7ba221ed61decabb569ca7715538a43..b13f8c456b23fccb3439cd14ae27e3c2a7adbed9 100644 --- a/services/distributeddataservice/framework/BUILD.gn +++ b/services/distributeddataservice/framework/BUILD.gn @@ -46,9 +46,13 @@ ohos_shared_library("distributeddatasvcfwk") { "checker/checker_manager.cpp", "cloud/asset_loader.cpp", "cloud/cloud_db.cpp", + "cloud/cloud_event.cpp", "cloud/cloud_info.cpp", "cloud/cloud_server.cpp", "cloud/schema_meta.cpp", + "cloud/subscription.cpp", + "cloud/sync_event.cpp", + "directory/directory_manager.cpp", "eventcenter/event.cpp", "eventcenter/event_center.cpp", "feature/feature_system.cpp", @@ -71,6 +75,7 @@ ohos_shared_library("distributeddatasvcfwk") { "utils/constant.cpp", "utils/converter.cpp", "utils/crypto.cpp", + "utils/ref_count.cpp", ] cflags = [ "-Wno-multichar" ] @@ -82,7 +87,11 @@ ohos_shared_library("distributeddatasvcfwk") { deps = [ "//third_party/openssl:libcrypto_shared" ] - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hilog:libhilog", + ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/services/distributeddataservice/framework/cloud/asset_loader.cpp b/services/distributeddataservice/framework/cloud/asset_loader.cpp index cef89e7db8642219fb9793838a9f64c1eb574e78..f2551e1bd8ebccd9ff7cda6db2532b94c134ce0e 100644 --- a/services/distributeddataservice/framework/cloud/asset_loader.cpp +++ b/services/distributeddataservice/framework/cloud/asset_loader.cpp @@ -15,13 +15,13 @@ #include "cloud/asset_loader.h" namespace OHOS::DistributedData { -int32_t AssetLoader::Upload(const std::vector &assets) +int32_t AssetLoader::Download(const std::string &tableName, const std::string &gid, const Value &prefix, + VBucket &assets) { return E_NOT_SUPPORT; } - -int32_t AssetLoader::Download(std::vector &assets) +int32_t AssetLoader::RemoveLocalAssets(VBucket &assets) { return E_NOT_SUPPORT; } -} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/cloud/cloud_db.cpp b/services/distributeddataservice/framework/cloud/cloud_db.cpp index dd149f8e21c61e173b0d881c490339f047e7f2fc..5a081255246cc8fe47d45fd6cb6e7645cfe782f9 100644 --- a/services/distributeddataservice/framework/cloud/cloud_db.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_db.cpp @@ -25,6 +25,11 @@ int32_t CloudDB::BatchInsert(const std::string &table, VBuckets &&values, VBucke return E_NOT_SUPPORT; } +int32_t CloudDB::BatchUpdate(const std::string &table, VBuckets &&values, VBuckets &extends) +{ + return BatchUpdate(table, std::move(values), static_cast(extends)); +} + int32_t CloudDB::BatchUpdate(const std::string &table, VBuckets &&values, const VBuckets &extends) { return E_NOT_SUPPORT; diff --git a/services/distributeddataservice/framework/cloud/cloud_event.cpp b/services/distributeddataservice/framework/cloud/cloud_event.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8146446d3a983f1a9a38632879a71367e5c4b185 --- /dev/null +++ b/services/distributeddataservice/framework/cloud/cloud_event.cpp @@ -0,0 +1,28 @@ +/* + * 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 "cloud/cloud_event.h" + +namespace OHOS::DistributedData { +CloudEvent::CloudEvent(int32_t evtId, CloudEvent::StoreInfo storeInfo) + : Event(evtId), storeInfo_(std::move(storeInfo)) +{ +} + +const CloudEvent::StoreInfo& CloudEvent::GetStoreInfo() const +{ + return storeInfo_; +} +} \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/cloud_info.cpp b/services/distributeddataservice/framework/cloud/cloud_info.cpp index f3f141ebf041cbf67732bc3eae3692aa6bfa6d01..7df8309f4f2a84a75d9d176a4789df5b52635264 100644 --- a/services/distributeddataservice/framework/cloud/cloud_info.cpp +++ b/services/distributeddataservice/framework/cloud/cloud_info.cpp @@ -44,6 +44,7 @@ bool CloudInfo::AppInfo::Marshal(Serializable::json &node) const SetValue(node[GET_NAME(bundleName)], bundleName); SetValue(node[GET_NAME(appId)], appId); SetValue(node[GET_NAME(version)], version); + SetValue(node[GET_NAME(instanceId)], instanceId); SetValue(node[GET_NAME(cloudSwitch)], cloudSwitch); return true; } @@ -53,28 +54,48 @@ bool CloudInfo::AppInfo::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(bundleName), bundleName); GetValue(node, GET_NAME(appId), appId); GetValue(node, GET_NAME(version), version); + GetValue(node, GET_NAME(instanceId), instanceId); GetValue(node, GET_NAME(cloudSwitch), cloudSwitch); return true; } std::string CloudInfo::GetKey() const { - return GetKey(INFO_PREFIX, { std::to_string(user), id }); + return GetKey(INFO_PREFIX, { std::to_string(user) }); } std::map CloudInfo::GetSchemaKey() const { std::map keys; - for (const auto &app : apps) { - const auto key = GetKey(SCHEMA_PREFIX, { std::to_string(user), id, app.bundleName }); + for (const auto &[bundle, app] : apps) { + const auto key = GetKey( + SCHEMA_PREFIX, { std::to_string(user), bundle, std::to_string(app.instanceId) }); keys.insert_or_assign(app.bundleName, key); } return keys; } -std::string CloudInfo::GetSchemaKey(std::string bundleName) const +std::string CloudInfo::GetSchemaKey(const std::string &bundleName, int32_t instanceId) const { - return GetKey(SCHEMA_PREFIX, { std::to_string(user), id, bundleName }); + return GetKey(SCHEMA_PREFIX, { std::to_string(user), bundleName, std::to_string(instanceId) }); +} + +std::string CloudInfo::GetSchemaKey(int32_t user, const std::string &bundleName, int32_t instanceId) +{ + return GetKey(SCHEMA_PREFIX, { std::to_string(user), bundleName, std::to_string(instanceId) }); +} + +std::string CloudInfo::GetSchemaPrefix(const std::string &bundleName) const +{ + if (bundleName.empty()) { + return GetKey(SCHEMA_PREFIX, { std::to_string(user) }); + } + return GetKey(SCHEMA_PREFIX, { std::to_string(user), bundleName}); +} + +std::string CloudInfo::GetSchemaKey(const StoreMetaData &meta) +{ + return GetKey(SCHEMA_PREFIX, { meta.user, meta.bundleName, std::to_string(meta.instanceId) }); } bool CloudInfo::IsValid() const @@ -82,14 +103,22 @@ bool CloudInfo::IsValid() const return !id.empty(); } -bool CloudInfo::IsExist(const std::string &bundleName) const +bool CloudInfo::Exist(const std::string &bundleName, int32_t instanceId) +{ + if (bundleName.empty()) { + return false; + } + auto it = apps.find(bundleName); + return it != apps.end() && it->second.bundleName == bundleName && it->second.instanceId == instanceId; +} + +bool CloudInfo::IsOn(const std::string &bundleName, int32_t instanceId) { - for (const auto &app : apps) { - if (app.bundleName == bundleName) { - return true; - } + if (bundleName.empty()) { + return false; } - return false; + auto it = apps.find(bundleName); + return it != apps.end() && it->second.instanceId == instanceId && it->second.cloudSwitch; } std::string CloudInfo::GetPrefix(const std::initializer_list &fields) diff --git a/services/distributeddataservice/framework/cloud/schema_meta.cpp b/services/distributeddataservice/framework/cloud/schema_meta.cpp index b6a8cd4b35ecd9d701651340a40aea9b698e867d..af5ec17aa0505cdba9236a7e54db234eb81dec30 100644 --- a/services/distributeddataservice/framework/cloud/schema_meta.cpp +++ b/services/distributeddataservice/framework/cloud/schema_meta.cpp @@ -18,6 +18,7 @@ namespace OHOS::DistributedData { bool SchemaMeta::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(version)], version); + SetValue(node[GET_NAME(bundleName)], bundleName); SetValue(node[GET_NAME(databases)], databases); return true; } @@ -25,11 +26,22 @@ bool SchemaMeta::Marshal(Serializable::json &node) const bool SchemaMeta::Unmarshal(const Serializable::json &node) { GetValue(node, GET_NAME(version), version); + GetValue(node, GET_NAME(bundleName), bundleName); GetValue(node, GET_NAME(databases), databases); return true; } -bool SchemaMeta::Database::Marshal(Serializable::json &node) const +std::vector Database::GetTableNames() const +{ + std::vector tableNames; + tableNames.reserve(tables.size()); + for (auto &table : tables) { + tableNames.push_back(table.name); + } + return tableNames; +} + +bool Database::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(name)], name); SetValue(node[GET_NAME(alias)], alias); @@ -37,7 +49,7 @@ bool SchemaMeta::Database::Marshal(Serializable::json &node) const return true; } -bool SchemaMeta::Database::Unmarshal(const Serializable::json &node) +bool Database::Unmarshal(const Serializable::json &node) { GetValue(node, GET_NAME(name), name); GetValue(node, GET_NAME(alias), alias); @@ -45,7 +57,7 @@ bool SchemaMeta::Database::Unmarshal(const Serializable::json &node) return true; } -bool SchemaMeta::Table::Marshal(Serializable::json &node) const +bool Table::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(name)], name); SetValue(node[GET_NAME(alias)], alias); @@ -53,7 +65,7 @@ bool SchemaMeta::Table::Marshal(Serializable::json &node) const return true; } -bool SchemaMeta::Table::Unmarshal(const Serializable::json &node) +bool Table::Unmarshal(const Serializable::json &node) { GetValue(node, GET_NAME(name), name); GetValue(node, GET_NAME(alias), alias); @@ -61,7 +73,7 @@ bool SchemaMeta::Table::Unmarshal(const Serializable::json &node) return true; } -bool SchemaMeta::Field::Marshal(Serializable::json &node) const +bool Field::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(colName)], colName); SetValue(node[GET_NAME(alias)], alias); @@ -71,7 +83,7 @@ bool SchemaMeta::Field::Marshal(Serializable::json &node) const return true; } -bool SchemaMeta::Field::Unmarshal(const Serializable::json &node) +bool Field::Unmarshal(const Serializable::json &node) { GetValue(node, GET_NAME(colName), colName); GetValue(node, GET_NAME(alias), alias); @@ -81,7 +93,7 @@ bool SchemaMeta::Field::Unmarshal(const Serializable::json &node) return true; } -SchemaMeta::Database SchemaMeta::GetDataBase(const std::string &storeId) +Database SchemaMeta::GetDataBase(const std::string &storeId) { for (const auto &database : databases) { if (database.name == storeId) { @@ -90,4 +102,9 @@ SchemaMeta::Database SchemaMeta::GetDataBase(const std::string &storeId) } return {}; } + +bool SchemaMeta::IsValid() const +{ + return !bundleName.empty() && !databases.empty(); +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/subscription.cpp b/services/distributeddataservice/framework/cloud/subscription.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7bddb52c3744542b623df82347c1a724238b66df --- /dev/null +++ b/services/distributeddataservice/framework/cloud/subscription.cpp @@ -0,0 +1,75 @@ +/* + * 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 "cloud/subscription.h" +#include "utils/constant.h" +namespace OHOS::DistributedData { +bool Subscription::Relation::Marshal(json &node) const +{ + SetValue(node[GET_NAME(id)], id); + SetValue(node[GET_NAME(bundleName)], bundleName); + SetValue(node[GET_NAME(relations)], relations); + return true; +} + +bool Subscription::Relation::Unmarshal(const json &node) +{ + GetValue(node, GET_NAME(id), id); + GetValue(node, GET_NAME(bundleName), bundleName); + GetValue(node, GET_NAME(relations), relations); + return true; +} + +bool Subscription::Marshal(json &node) const +{ + SetValue(node[GET_NAME(userId)], userId); + SetValue(node[GET_NAME(id)], id); + SetValue(node[GET_NAME(expiresTime)], expiresTime); + return true; +} + +bool Subscription::Unmarshal(const json &node) +{ + GetValue(node, GET_NAME(userId), userId); + GetValue(node, GET_NAME(id), id); + GetValue(node, GET_NAME(expiresTime), expiresTime); + return true; +} + +std::string Subscription::GetKey() +{ + return GetKey(userId); +} + +std::string Subscription::GetRelationKey(const std::string &bundleName) +{ + return GetRelationKey(userId, bundleName); +} + +std::string Subscription::GetKey(int32_t userId) +{ + return Constant::Join(PREFIX, Constant::KEY_SEPARATOR, { std::to_string(userId) }); +} + +std::string Subscription::GetRelationKey(int32_t userId, const std::string &bundleName) +{ + return Constant::Join(RELATION_PREFIX, Constant::KEY_SEPARATOR, { std::to_string(userId), bundleName }); +} + +std::string Subscription::GetPrefix(const std::initializer_list &fields) +{ + return Constant::Join(PREFIX, Constant::KEY_SEPARATOR, fields); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/sync_event.cpp b/services/distributeddataservice/framework/cloud/sync_event.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f165e4f74000b3006b38e45a7c3ad905cf975620 --- /dev/null +++ b/services/distributeddataservice/framework/cloud/sync_event.cpp @@ -0,0 +1,76 @@ +/* + * 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 "cloud/sync_event.h" + +namespace OHOS::DistributedData { +SyncEvent::EventInfo::EventInfo(int32_t mode, int32_t wait, bool retry, std::shared_ptr query, GenAsync async) + : retry_(retry), mode_(mode), wait_(wait), query_(std::move(query)), asyncDetail_(std::move(async)) +{ +} + +SyncEvent::EventInfo::EventInfo(SyncEvent::EventInfo &&info) noexcept +{ + operator=(std::move(info)); +} + +SyncEvent::EventInfo &SyncEvent::EventInfo::operator=(SyncEvent::EventInfo &&info) noexcept +{ + if (this == &info) { + return *this; + } + retry_ = info.retry_; + mode_ = info.mode_; + wait_ = info.wait_; + query_ = std::move(info.query_); + asyncDetail_ = std::move(info.asyncDetail_); + return *this; +} + +SyncEvent::SyncEvent(StoreInfo storeInfo, EventInfo info) + : CloudEvent(CLOUD_SYNC, std::move(storeInfo)), info_(std::move(info)) +{ +} + +SyncEvent::SyncEvent(int32_t evtId, StoreInfo storeInfo, EventInfo info) + : CloudEvent(evtId, std::move(storeInfo)), info_(std::move(info)) +{ +} + +int32_t SyncEvent::GetMode() const +{ + return info_.mode_; +} + +int32_t SyncEvent::GetWait() const +{ + return info_.wait_; +} + +bool SyncEvent::AutoRetry() const +{ + return info_.retry_; +} + +std::shared_ptr SyncEvent::GetQuery() const +{ + return info_.query_; +} + +GenAsync SyncEvent::GetAsyncDetail() const +{ + return info_.asyncDetail_; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/service/directory/src/directory_manager.cpp b/services/distributeddataservice/framework/directory/directory_manager.cpp similarity index 99% rename from services/distributeddataservice/service/directory/src/directory_manager.cpp rename to services/distributeddataservice/framework/directory/directory_manager.cpp index bba79049e25fd98a4fab5c5f06464d95d9d9433f..a3b0458bf9d2f4442e0fc905b110a9a8d9309894 100644 --- a/services/distributeddataservice/service/directory/src/directory_manager.cpp +++ b/services/distributeddataservice/framework/directory/directory_manager.cpp @@ -13,12 +13,11 @@ * limitations under the License. */ #define LOG_TAG "DirectoryManager" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include -#include - #include +#include #include "accesstoken_kit.h" #include "log_print.h" diff --git a/services/distributeddataservice/framework/feature/feature_system.cpp b/services/distributeddataservice/framework/feature/feature_system.cpp index 6bfd3d23bc4499e55ff9ef411d7973ab9a3d27ff..74907ec87597beb2d6fe8a3b52c34a00fec1809d 100644 --- a/services/distributeddataservice/framework/feature/feature_system.cpp +++ b/services/distributeddataservice/framework/feature/feature_system.cpp @@ -60,17 +60,18 @@ int32_t FeatureSystem::Feature::OnInitialize() return E_OK; } -int32_t FeatureSystem::Feature::OnExecutor(std::shared_ptr executors) +int32_t FeatureSystem::Feature::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) { return E_OK; } -int32_t FeatureSystem::Feature::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) +int32_t FeatureSystem::Feature::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, + uint32_t tokenId) { return E_OK; } -int32_t FeatureSystem::Feature::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, +int32_t FeatureSystem::Feature::OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) { return E_OK; @@ -100,5 +101,10 @@ int32_t FeatureSystem::Feature::OnReady(const std::string &device) { return E_OK; } + +int32_t FeatureSystem::Feature::OnBind(const FeatureSystem::Feature::BindInfo &bindInfo) +{ + return E_OK; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/cloud/asset_loader.h b/services/distributeddataservice/framework/include/cloud/asset_loader.h index 0df69eb0a415c5bdb72de379d5658e3c04e75289..c2d47a632856e31e273b51cf269af2bd17cae8f1 100644 --- a/services/distributeddataservice/framework/include/cloud/asset_loader.h +++ b/services/distributeddataservice/framework/include/cloud/asset_loader.h @@ -15,14 +15,16 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H #include + #include "store/general_value.h" #include "visibility.h" namespace OHOS::DistributedData { class API_EXPORT AssetLoader { public: virtual ~AssetLoader() = default; - virtual int32_t Upload(const std::vector &assets); - virtual int32_t Download(std::vector &assets); + virtual int32_t Download(const std::string &tableName, const std::string &gid, const Value &prefix, + VBucket &assets); + virtual int32_t RemoveLocalAssets(VBucket &assets); }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H diff --git a/services/distributeddataservice/framework/include/cloud/change_event.h b/services/distributeddataservice/framework/include/cloud/change_event.h new file mode 100644 index 0000000000000000000000000000000000000000..cf969698089ead7fe401812ca0d4933513a49b34 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/change_event.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CHANGE_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CHANGE_EVENT_H +#include "cloud/sync_event.h" +#include "store/general_value.h" +namespace OHOS::DistributedData { +class API_EXPORT ChangeEvent : public SyncEvent { +public: + ChangeEvent(StoreInfo storeInfo, EventInfo info) + : SyncEvent(LOCAL_CHANGE, std::move(storeInfo), std::move(info)) + { + } + ~ChangeEvent() override = default; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CHANGE_EVENT_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_db.h b/services/distributeddataservice/framework/include/cloud/cloud_db.h index 4882d8d7fef83b989eff0ca7774c15ae0b05c170..1b6f246218ac61fb2e24d41ef4798df011b71d1e 100644 --- a/services/distributeddataservice/framework/include/cloud/cloud_db.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_db.h @@ -34,6 +34,8 @@ public: virtual int32_t BatchInsert(const std::string &table, VBuckets &&values, VBuckets &extends); + virtual int32_t BatchUpdate(const std::string &table, VBuckets &&values, VBuckets &extends); + virtual int32_t BatchUpdate(const std::string &table, VBuckets &&values, const VBuckets &extends); virtual int32_t BatchDelete(const std::string &table, const VBuckets &extends); diff --git a/services/distributeddataservice/framework/include/cloud/cloud_event.h b/services/distributeddataservice/framework/include/cloud/cloud_event.h new file mode 100644 index 0000000000000000000000000000000000000000..01c2c0988942250ddcd8fa9f7819c4a7d282bba7 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/cloud_event.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H + +#include +#include "eventcenter/event.h" + +namespace OHOS::DistributedData { +class API_EXPORT CloudEvent : public Event { +public: + enum : int32_t { + FEATURE_INIT = EVT_CLOUD, + GET_SCHEMA, + LOCAL_CHANGE, + CLOUD_SYNC, + CLOUD_BUTT + }; + + struct StoreInfo { + uint32_t tokenId = 0; + std::string bundleName; + std::string storeName; + int32_t instanceId = 0; + int32_t user = 0; + }; + + CloudEvent(int32_t evtId, StoreInfo storeInfo); + ~CloudEvent() = default; + const StoreInfo& GetStoreInfo() const; + +private: + StoreInfo storeInfo_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_info.h b/services/distributeddataservice/framework/include/cloud/cloud_info.h index 5576bca8a4d6b433951e1c3ff6b3eb4000afd72b..b88e997944ead97181d5d276beaf45d621865683 100644 --- a/services/distributeddataservice/framework/include/cloud/cloud_info.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_info.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_INFO_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_INFO_H +#include "metadata/store_meta_data.h" #include "serializable/serializable.h" namespace OHOS::DistributedData { class API_EXPORT CloudInfo final : public Serializable { @@ -23,6 +24,7 @@ public: std::string bundleName = ""; std::string appId = ""; uint64_t version = 0; + int32_t instanceId = 0; bool cloudSwitch = false; bool Marshal(json &node) const override; @@ -33,13 +35,17 @@ public: uint64_t totalSpace = 0; uint64_t remainSpace = 0; bool enableCloud = false; - std::vector apps; + std::map apps; std::string GetKey() const; std::map GetSchemaKey() const; - std::string GetSchemaKey(std::string bundleName) const; + std::string GetSchemaKey(const std::string &bundleName, int32_t instanceId = 0) const; + std::string GetSchemaPrefix(const std::string &bundleName) const; + static std::string GetSchemaKey(int32_t user, const std::string &bundleName, int32_t instanceId = 0); + static std::string GetSchemaKey(const StoreMetaData &meta); bool IsValid() const; - bool IsExist(const std::string &bundleName) const; + bool Exist(const std::string &bundleName, int32_t instanceId = 0); + bool IsOn(const std::string &bundleName, int32_t instanceId = 0); static std::string GetPrefix(const std::initializer_list &field); bool Marshal(json &node) const override; diff --git a/services/distributeddataservice/framework/include/cloud/schema_meta.h b/services/distributeddataservice/framework/include/cloud/schema_meta.h index 188a013262b4877511a88c20d2499811dc9484d4..298a33938773df3e06a05e446450a1ffc7bd3fba 100644 --- a/services/distributeddataservice/framework/include/cloud/schema_meta.h +++ b/services/distributeddataservice/framework/include/cloud/schema_meta.h @@ -17,44 +17,51 @@ #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SCHEMA_META_H #include "serializable/serializable.h" namespace OHOS::DistributedData { +struct API_EXPORT Field final : public Serializable { + std::string colName; + std::string alias; + int32_t type = 0; + bool primary = false; + bool nullable = true; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; + +struct API_EXPORT Table final : public Serializable { + std::string name; + std::string alias; + std::vector fields; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; + +struct API_EXPORT Database final : public Serializable { + std::string name = ""; + std::string alias; + std::vector tables; + std::vector GetTableNames() const; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; + class API_EXPORT SchemaMeta final : public Serializable { public: + using Database = Database; + using Table = Table; + using Field = Field; static constexpr const char *DELETE_FIELD = "#_deleted"; static constexpr const char *GID_FIELD = "#_gid"; static constexpr const char *CREATE_FIELD = "#_createTime"; static constexpr const char *MODIFY_FIELD = "#_modifyTime"; static constexpr const char *CURSOR_FIELD = "#_cursor"; - struct API_EXPORT Field final : public Serializable { - std::string colName; - std::string alias; - int32_t type = 0; - bool primary = false; - bool nullable = true; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; - }; - - struct API_EXPORT Table final : public Serializable { - std::string name; - std::string alias; - std::vector fields; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; - }; - - struct API_EXPORT Database final : public Serializable { - std::string name = ""; - std::string alias; - std::vector
tables; - - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; - }; + static constexpr const char *ERROR_FIELD = "#_error"; int32_t version = 0; + std::string bundleName; std::vector databases; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; + bool IsValid() const; Database GetDataBase(const std::string &storeId); }; } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/include/cloud/subscription.h b/services/distributeddataservice/framework/include/cloud/subscription.h new file mode 100644 index 0000000000000000000000000000000000000000..c0e8dec5f5cb3f9342fc58961744a0e4e9469d65 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/subscription.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SUBSCRIPTION_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SUBSCRIPTION_H +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +struct API_EXPORT Subscription final : public Serializable { + int32_t userId = 0; + std::string id; + std::map expiresTime; + + struct API_EXPORT Relation final : public Serializable { + std::string id; + std::string bundleName; + std::map relations; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + + bool Marshal(json &node) const; + bool Unmarshal(const json &node); + std::string GetKey(); + std::string GetRelationKey(const std::string &bundleName); + static std::string GetKey(int32_t userId); + static std::string GetRelationKey(int32_t userId, const std::string &bundleName); + static std::string GetPrefix(const std::initializer_list &fields); +private: + static constexpr const char *PREFIX = "CLOUD_SUBSCRIPTION"; + static constexpr const char *RELATION_PREFIX = "CLOUD_RELATION"; + static constexpr uint64_t INVALID_TIME = 0; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SUBSCRIPTION_H diff --git a/services/distributeddataservice/framework/include/cloud/sync_event.h b/services/distributeddataservice/framework/include/cloud/sync_event.h new file mode 100644 index 0000000000000000000000000000000000000000..fb25f1a3d5bd642ed5a3a9d6a4128aefccb1f732 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/sync_event.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SYNC_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SYNC_EVENT_H +#include "cloud/cloud_event.h" +#include "store/general_value.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT SyncEvent : public CloudEvent { +public: + class EventInfo { + public: + API_EXPORT EventInfo(int32_t mode, int32_t wait, bool retry, std::shared_ptr query, GenAsync async); + API_EXPORT EventInfo(EventInfo &&info) noexcept; + EventInfo(const EventInfo &info) = default; + API_EXPORT EventInfo &operator=(EventInfo &&info) noexcept; + EventInfo &operator=(const EventInfo &info) = default; + private: + friend SyncEvent; + bool retry_ = false; + int32_t mode_ = -1; + int32_t wait_ = 0; + std::shared_ptr query_; + GenAsync asyncDetail_; + }; + SyncEvent(StoreInfo storeInfo, EventInfo info); + ~SyncEvent() override = default; + int32_t GetMode() const; + int32_t GetWait() const; + bool AutoRetry() const; + std::shared_ptr GetQuery() const; + GenAsync GetAsyncDetail() const; + +protected: + SyncEvent(int32_t evtId, StoreInfo storeInfo, EventInfo info); + +private: + EventInfo info_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SYNC_EVENT_H diff --git a/services/distributeddataservice/service/directory/include/directory_manager.h b/services/distributeddataservice/framework/include/directory/directory_manager.h similarity index 100% rename from services/distributeddataservice/service/directory/include/directory_manager.h rename to services/distributeddataservice/framework/include/directory/directory_manager.h diff --git a/services/distributeddataservice/framework/include/error/general_error.h b/services/distributeddataservice/framework/include/error/general_error.h index 8c60a916290acf7404633630ba9c36d17e213aa8..79a4433ab7f30177fda934a06b2619dc69fcea77 100644 --- a/services/distributeddataservice/framework/include/error/general_error.h +++ b/services/distributeddataservice/framework/include/error/general_error.h @@ -19,12 +19,19 @@ namespace OHOS::DistributedData { enum GeneralError : int32_t { E_OK = 0, E_ERROR, + E_NETWORK_ERROR, + E_CLOUD_DISABLED, + E_LOCKED_BY_OTHERS, + E_RECODE_LIMIT_EXCEEDED, + E_NO_SPACE_FOR_ASSET, E_BUSY, E_INVALID_ARGS, E_NOT_INIT, E_NOT_SUPPORT, E_ALREADY_CONSUMED, E_ALREADY_CLOSED, + E_UNOPENED, + E_RETRY_TIMEOUT, E_BUTT, }; } diff --git a/services/distributeddataservice/framework/include/eventcenter/event.h b/services/distributeddataservice/framework/include/eventcenter/event.h index d574e0f5b6fe55345666cbcc8d36a9f949e1e91e..27bf9df2e6c2daaf3d77ba2084b8cd16e97fb94e 100644 --- a/services/distributeddataservice/framework/include/eventcenter/event.h +++ b/services/distributeddataservice/framework/include/eventcenter/event.h @@ -27,7 +27,8 @@ public: EVT_INVALID, EVT_INITED, EVT_UPDATE, - EVT_CUSTOM = 0x1000 + EVT_CUSTOM = 0x1000, + EVT_CLOUD = 0x2000 }; API_EXPORT Event(int32_t evtId); API_EXPORT Event(Event &&) noexcept = delete; diff --git a/services/distributeddataservice/framework/include/feature/feature_system.h b/services/distributeddataservice/framework/include/feature/feature_system.h index 8aa732cfd9e78e12367d24cbc0d1665cbed560b7..d549cc6d59e1f9526c8896d324e273165fe38360 100644 --- a/services/distributeddataservice/framework/include/feature/feature_system.h +++ b/services/distributeddataservice/framework/include/feature/feature_system.h @@ -36,12 +36,18 @@ public: }; class API_EXPORT Feature { public: + struct BindInfo { + std::string selfName; + uint32_t selfTokenId; + std::shared_ptr executors; + }; virtual ~Feature(); virtual int OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply) = 0; virtual int32_t OnInitialize(); - virtual int32_t OnExecutor(std::shared_ptr executors); + virtual int32_t OnBind(const BindInfo &bindInfo); virtual int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName); virtual int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); + virtual int32_t OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); virtual int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); virtual int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account); virtual int32_t Online(const std::string &device); diff --git a/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/services/distributeddataservice/framework/include/metadata/store_meta_data.h index bb134e354f0670a4b87bd253ba57db7def0af182..e40965fd6e535787c6bef8910cfdb1326d2572f6 100644 --- a/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -70,6 +70,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT std::string GetSecretKey() const; API_EXPORT std::string GetStrategyKey() const; API_EXPORT std::string GetBackupSecretKey() const; + API_EXPORT std::string GetStoreAlias() const; API_EXPORT static std::string GetKey(const std::initializer_list &fields); API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); diff --git a/services/distributeddataservice/framework/include/serializable/serializable.h b/services/distributeddataservice/framework/include/serializable/serializable.h index 4b16f8dd3b817fdac6b2e0f8ff14d34f245cbb71..6843d643cfd925819fd585e5976751c4aae0cb85 100644 --- a/services/distributeddataservice/framework/include/serializable/serializable.h +++ b/services/distributeddataservice/framework/include/serializable/serializable.h @@ -21,6 +21,7 @@ #ifndef JSON_NOEXCEPTION #define JSON_NOEXCEPTION #endif +#include #include namespace OHOS { namespace DistributedData { @@ -32,6 +33,7 @@ public: using json = nlohmann::json; using size_type = nlohmann::json::size_type; using error_handler_t = nlohmann::detail::error_handler_t; + API_EXPORT json Marshall() const; template static std::string Marshall(T &values) @@ -63,61 +65,194 @@ public: API_EXPORT static bool SetValue(json &node, const uint32_t &value); API_EXPORT static bool SetValue(json &node, const int32_t &value); API_EXPORT static bool SetValue(json &node, const int64_t &value); + API_EXPORT static bool SetValue(json &node, const double &value); API_EXPORT static bool SetValue(json &node, const uint64_t &value); - API_EXPORT static bool SetValue(json &node, const bool &value); + // Use bool & to forbid the const T * auto convert to bool, const bool will convert to const uint32_t &value; + API_EXPORT static bool SetValue(json &node, bool &value); API_EXPORT static bool SetValue(json &node, const std::vector &value); API_EXPORT static bool SetValue(json &node, const Serializable &value); + + template + API_EXPORT static bool SetValue(json &node, const std::variant<_Types...> &input); + + template + API_EXPORT static bool GetValue(const json &node, const std::string &name, std::variant<_Types...> &value); protected: API_EXPORT ~Serializable() = default; template - static bool GetValue(const json &node, const std::string &name, T *&value) - { - auto &subNode = GetSubNode(node, name); - if (subNode.is_null()) { - return false; - } - value = new(std::nothrow) T(); - if (value == nullptr) { - return false; - } - bool result = GetValue(subNode, "", *value); - if (!result) { - delete value; - value = nullptr; - } - return result; - } + static bool GetValue(const json &node, const std::string &name, std::vector &values); + template - static bool GetValue(const json &node, const std::string &name, std::vector &values) - { - auto &subNode = GetSubNode(node, name); - if (subNode.is_null() || !subNode.is_array()) { + static bool SetValue(json &node, const std::vector &values); + + template + static bool GetValue(const json &node, const std::string &name, std::map &values); + + template + static bool SetValue(json &node, const std::map &values); + + template + static bool GetValue(const json &node, const std::string &name, T *&value); + + template + static bool SetValue(json &node, const T *value); + + template + static bool ReadVariant(const json &node, const std::string &name, uint32_t step, uint32_t index, _OutTp &output); + + template + static bool ReadVariant(const json &node, const std::string &name, uint32_t step, uint32_t index, _OutTp &output); + + template + static bool WriteVariant(json &node, uint32_t step, const _InTp &input); + + template + static bool WriteVariant(json &node, uint32_t step, const _InTp &input); + API_EXPORT static const json &GetSubNode(const json &node, const std::string &name); +}; + +template +bool Serializable::GetValue(const json &node, const std::string &name, std::vector &values) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_array()) { + return false; + } + bool result = true; + values.resize(subNode.size()); + for (size_type i = 0; i < subNode.size(); ++i) { + result = GetValue(subNode[i], "", values[i]) && result; + } + return result; +} + +template +bool Serializable::SetValue(json &node, const std::vector &values) +{ + bool result = true; + size_type i = 0; + node = json::value_t::array; + for (const auto &value : values) { + result = SetValue(node[i], value) && result; + i++; + } + return result; +} + +template +bool Serializable::GetValue(const json &node, const std::string &name, std::map &values) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_object()) { + return false; + } + bool result = true; + for (auto object = subNode.begin(); object != subNode.end(); ++object) { + result = GetValue(object.value(), "", values[object.key()]) && result; + } + return result; +} + +template +bool Serializable::SetValue(json &node, const std::map &values) +{ + bool result = true; + node = json::value_t::object; + for (const auto &[key, value] : values) { + result = SetValue(node[key], value) && result; + } + return result; +} + +template +bool Serializable::GetValue(const json &node, const std::string &name, T *&value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null()) { + return false; + } + value = new(std::nothrow) T(); + if (value == nullptr) { + return false; + } + bool result = GetValue(subNode, "", *value); + if (!result) { + delete value; + value = nullptr; + } + return result; +} + +template +bool Serializable::SetValue(json &node, const T *value) +{ + if (value == nullptr) { + return false; + } + return SetValue(node, *value); +} + +template +bool Serializable::SetValue(json &node, const std::variant<_Types...> &input) +{ + bool ret = SetValue(node[GET_NAME(type)], input.index()); + if (!ret) { + return ret; + } + return WriteVariant(node[GET_NAME(value)], 0, input); +} + +template +bool Serializable::GetValue(const json &node, const std::string &name, std::variant<_Types...> &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null()) { + return false; + } + uint32_t index; + bool ret = GetValue(subNode, GET_NAME(type), index); + if (!ret) { + return ret; + } + + return Serializable::ReadVariant(subNode, GET_NAME(value), 0, index, value); +} + +template +bool Serializable::WriteVariant(json &node, uint32_t step, const _InTp &input) +{ + return false; +} + +template +bool Serializable::ReadVariant(const json &node, const std::string &name, uint32_t step, uint32_t index, _OutTp &output) +{ + if (step == index) { + _First result; + if (!Serializable::GetValue(node, name, result)) { return false; } - bool result = true; - values.resize(subNode.size()); - for (size_type i = 0; i < subNode.size(); ++i) { - result = GetValue(subNode[i], "", values[i]) && result; - } - return result; + output = result; + return true; } + return Serializable::ReadVariant<_OutTp, _Rest...>(node, name, step + 1, index, output); +} - template - static bool SetValue(json &node, const std::vector &values) - { - bool result = true; - size_type i = 0; - node = json::value_t::array; - for (const auto &value : values) { - result = SetValue(node[i], value) && result; - i++; - } - return result; +template +bool Serializable::WriteVariant(json &node, uint32_t step, const _InTp &input) +{ + if (step == input.index()) { + return Serializable::SetValue(node, std::get<_First>(input)); } + return WriteVariant<_InTp, _Rest...>(node, step + 1, input); +} - API_EXPORT static const json &GetSubNode(const json &node, const std::string &name); -}; +template +bool Serializable::ReadVariant(const json &node, const std::string &name, uint32_t step, uint32_t index, _OutTp &output) +{ + return false; +} } // namespace DistributedData } // namespace OHOS #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_SERIALIZABLE_H diff --git a/services/distributeddataservice/framework/include/store/auto_cache.h b/services/distributeddataservice/framework/include/store/auto_cache.h index 4267a8952c661a6fd2fa0b9c191cf87b0c0289f2..e4940b91999f5be44fac8027941eb77cde54717f 100644 --- a/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/services/distributeddataservice/framework/include/store/auto_cache.h @@ -27,6 +27,7 @@ #include "store/general_watcher.h" #include "visibility.h" namespace OHOS::DistributedData { +class SchemaMeta; class AutoCache { public: using Error = GeneralError; @@ -47,6 +48,8 @@ public: API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); + API_EXPORT void CloseStore(uint32_t tokenId); + API_EXPORT void CloseExcept(const std::set &users); API_EXPORT void SetObserver(uint32_t tokenId, const std::string &storeId, const Watchers &watchers); @@ -63,8 +66,7 @@ private: bool Close(); int32_t GetUser() const; void SetObservers(const Watchers &watchers); - int32_t OnChange(Origin origin, const std::string &id) override; - int32_t OnChange(Origin origin, const std::string &id, const std::vector &values) override; + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; private: mutable Time time_; diff --git a/services/distributeddataservice/framework/include/store/cursor.h b/services/distributeddataservice/framework/include/store/cursor.h index e588c5fd65e4633671dcc911a283f9a79aed7b41..a631122e4fb68f5c0d4ceefb8e27b666aa0570d4 100644 --- a/services/distributeddataservice/framework/include/store/cursor.h +++ b/services/distributeddataservice/framework/include/store/cursor.h @@ -46,6 +46,8 @@ public: virtual int32_t Get(const std::string &col, Value &value) = 0; virtual int32_t Close() = 0; + + virtual bool IsEnd() = 0; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_CURSOR_H diff --git a/services/distributeddataservice/framework/include/store/general_store.h b/services/distributeddataservice/framework/include/store/general_store.h index 56cdcf87abe2841a12b64b9172b339118f62babe..f28df99d810d61acb881ab7a8be62bf887a107c1 100644 --- a/services/distributeddataservice/framework/include/store/general_store.h +++ b/services/distributeddataservice/framework/include/store/general_store.h @@ -23,15 +23,46 @@ #include "store/general_watcher.h" namespace OHOS::DistributedData { class CloudDB; +class AssetLoader; +struct Database; class GeneralStore { public: using Watcher = GeneralWatcher; - using Async = std::function>)>; + using DetailAsync = GenAsync; using Devices = std::vector; + enum SyncMode { + NEARBY_BEGIN, + NEARBY_PUSH = NEARBY_BEGIN, + NEARBY_PULL, + NEARBY_PULL_PUSH, + NEARBY_END, + CLOUD_BEGIN = 4, + CLOUD_TIME_FIRST = CLOUD_BEGIN, + CLOUD_NATIVE_FIRST, + CLOUD_ClOUD_FIRST, + CLOUD_END, + MODE_BUTT = CLOUD_END, + }; + enum CleanMode { + NEARBY_DATA = 0, + CLOUD_DATA, + CLOUD_INFO, + LOCAL_DATA, + }; + struct BindInfo { + BindInfo(std::shared_ptr db = nullptr, std::shared_ptr loader = nullptr) + : db_(std::move(db)), loader_(std::move(loader)) + { + } + std::shared_ptr db_; + std::shared_ptr loader_; + }; virtual ~GeneralStore() = default; - virtual int32_t Bind(std::shared_ptr cloudDb) = 0; + virtual int32_t Bind(const Database &database, BindInfo bindInfo) = 0; + + virtual bool IsBound() = 0; virtual int32_t Execute(const std::string &table, const std::string &sql) = 0; @@ -45,13 +76,19 @@ public: virtual std::shared_ptr Query(const std::string &table, GenQuery &query) = 0; - virtual int32_t Sync(const Devices &devices, int32_t mode, GenQuery &query, Async async, int32_t wait) = 0; + virtual int32_t Sync(const Devices &devices, int32_t mode, GenQuery &query, DetailAsync async, int32_t wait) = 0; + + virtual int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) = 0; virtual int32_t Watch(int32_t origin, Watcher &watcher) = 0; virtual int32_t Unwatch(int32_t origin, Watcher &watcher) = 0; virtual int32_t Close() = 0; + + virtual int32_t AddRef() = 0; + + virtual int32_t Release() = 0; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/services/distributeddataservice/framework/include/store/general_value.h b/services/distributeddataservice/framework/include/store/general_value.h index 05d4766d399bfcb496bcc2549786977c9a6a9a65..4bf696fe7860d1a056e5b86ecb6ae0352697aace 100644 --- a/services/distributeddataservice/framework/include/store/general_value.h +++ b/services/distributeddataservice/framework/include/store/general_value.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_VALUE_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_VALUE_H +#include #include #include #include @@ -24,19 +25,60 @@ #include "error/general_error.h" #include "traits.h" namespace OHOS::DistributedData { +enum GenProgress { + SYNC_BEGIN, + SYNC_IN_PROGRESS, + SYNC_FINISH, +}; + +struct GenStatistic { + uint32_t total; + uint32_t success; + uint32_t failed; + uint32_t untreated; +}; + +struct GenTableDetail { + GenStatistic upload; + GenStatistic download; +}; + +struct GenProgressDetail { + int32_t progress; + int32_t code; + std::map details; +}; + struct Asset { - uint32_t version; + enum Status : int32_t { + STATUS_UNKNOWN, + STATUS_NORMAL, + STATUS_INSERT, + STATUS_UPDATE, + STATUS_DELETE, + STATUS_ABNORMAL, + STATUS_DOWNLOADING, + STATUS_BUTT + }; + + static constexpr uint64_t NO_EXPIRES_TIME = 0; + uint32_t version = 0; + uint32_t status = STATUS_UNKNOWN; + uint64_t expiresTime = NO_EXPIRES_TIME; + std::string id; std::string name; std::string uri; std::string createTime; std::string modifyTime; std::string size; std::string hash; + std::string path; }; struct GenQuery { virtual ~GenQuery() = default; virtual bool IsEqual(uint64_t tid) = 0; + virtual std::vector GetTables() = 0; template int32_t QueryInterface(T *&query) @@ -55,7 +97,8 @@ using Value = std::variant; using VBucket = std::map; using VBuckets = std::vector; - +using GenDetails = std::map; +using GenAsync = std::function; template inline constexpr size_t TYPE_INDEX = Traits::variant_index_of_v; diff --git a/services/distributeddataservice/framework/include/store/general_watcher.h b/services/distributeddataservice/framework/include/store/general_watcher.h index 52130eab7005077596a473d6a4e2346895dae712..bcf226d6647d08b40bb8675c5d42b7d001838a45 100644 --- a/services/distributeddataservice/framework/include/store/general_watcher.h +++ b/services/distributeddataservice/framework/include/store/general_watcher.h @@ -21,24 +21,39 @@ namespace OHOS::DistributedData { class GeneralWatcher { public: - enum Origin : int32_t { - ORIGIN_CLOUD, - ORIGIN_LOCAL, - ORIGIN_REMOTE, - ORIGIN_ALL, - ORIGIN_BUTT, + struct Origin { + enum OriginType : int32_t { + ORIGIN_LOCAL, + ORIGIN_NEARBY, + ORIGIN_CLOUD, + ORIGIN_ALL, + ORIGIN_BUTT, + }; + enum DataType : int32_t { + BASIC_DATA, + ASSET_DATA, + TYPE_BUTT, + }; + int32_t origin = ORIGIN_BUTT; + int32_t dataType = BASIC_DATA; + // origin is ORIGIN_LOCAL, the id is empty + // origin is ORIGIN_NEARBY, the id is networkId; + // origin is ORIGIN_CLOUD, the id is the cloud account id + std::vector id; + std::string store; }; - enum ChangeOp : int32_t { OP_INSERT, OP_UPDATE, OP_DELETE, OP_BUTT, }; - + // PK primary key + using PRIValue = std::variant; + using PRIFields = std::map; + using ChangeInfo = std::map[OP_BUTT]>; virtual ~GeneralWatcher() = default; - virtual int32_t OnChange(Origin origin, const std::string &id) = 0; - virtual int32_t OnChange(Origin origin, const std::string &id, const std::vector &values) = 0; + virtual int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) = 0; }; } #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_WATCHER_H diff --git a/services/distributeddataservice/framework/include/utils/constant.h b/services/distributeddataservice/framework/include/utils/constant.h index 7abc92823e2d62525409f22dfc117da610bddb16..ff0dffda86d90b6ba67a86a1496cf625c2b24056 100644 --- a/services/distributeddataservice/framework/include/utils/constant.h +++ b/services/distributeddataservice/framework/include/utils/constant.h @@ -16,12 +16,13 @@ #ifndef KV_DATASERVICE_CONSTANT_H #define KV_DATASERVICE_CONSTANT_H -#include -#include #include #include #include #include +#include +#include +#include #include #include "visibility.h" @@ -41,6 +42,15 @@ public: API_EXPORT static bool NotEqual(bool first, bool second); + template + inline static constexpr bool is_pod = (std::is_standard_layout_v && std::is_trivial_v); + + template + API_EXPORT inline static std::enable_if_t && is_pod, bool> Copy(T *tag, const S *src) + { + return DCopy(reinterpret_cast(tag), sizeof(T), reinterpret_cast(src), sizeof(S)); + }; + // delete left bland in s by reference. template static void LeftTrim(T &s); @@ -53,19 +63,14 @@ public: template static void Trim(T &s); - // delete left bland in s by reference, not change raw string. - template - static T LeftTrimCopy(T s); - - // delete right bland in s by reference, not change raw string. - template - static T RightTrimCopy(T s); - // delete both left and right bland in s by reference, not change raw string. template static T TrimCopy(T s); API_EXPORT static constexpr const char *KEY_SEPARATOR = "###"; + +private: + API_EXPORT static bool DCopy(uint8_t *tag, size_t tagLen, const uint8_t *src, size_t srcLen); }; // trim from start (in place) @@ -90,22 +95,6 @@ void Constant::Trim(T &s) RightTrim(s); } -// trim from start (copying) -template -T Constant::LeftTrimCopy(T s) -{ - LeftTrim(s); - return s; -} - -// trim from end (copying) -template -T Constant::RightTrimCopy(T s) -{ - RightTrim(s); - return s; -} - // trim from both ends (copying) template T Constant::TrimCopy(T s) diff --git a/services/distributeddataservice/service/kvdb/ref_count.h b/services/distributeddataservice/framework/include/utils/ref_count.h similarity index 87% rename from services/distributeddataservice/service/kvdb/ref_count.h rename to services/distributeddataservice/framework/include/utils/ref_count.h index 89ee9dd611a737f1ea2f0fac6a861f4d59c665a1..eb868790cd583fbe76cc476c650d2bedcaf96c91 100644 --- a/services/distributeddataservice/service/kvdb/ref_count.h +++ b/services/distributeddataservice/framework/include/utils/ref_count.h @@ -18,16 +18,17 @@ #include #include #include -namespace OHOS::DistributedKv { -class RefCount final { +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT RefCount final { public: RefCount(); - explicit RefCount(std::function action); + RefCount(std::function action); RefCount(const RefCount &other); RefCount(RefCount &&other) noexcept; RefCount &operator=(const RefCount &other); RefCount &operator=(RefCount &&other) noexcept; - operator bool () const; + operator bool() const; private: std::shared_ptr ref_; diff --git a/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/services/distributeddataservice/framework/metadata/store_meta_data.cpp index d7867f890a79bae5bd763c8f15678eea40ecc782..09bcd61e7f7dc153338bd9a95274c81409387530 100644 --- a/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -18,6 +18,7 @@ #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" +#include "utils/anonymous.h" #include "utils/constant.h" namespace OHOS { namespace DistributedData { @@ -154,6 +155,11 @@ std::string StoreMetaData::GetBackupSecretKey() const return SecretKeyMetaData::GetBackupKey({ user, "default", bundleName, storeId, std::to_string(instanceId) }); } +std::string StoreMetaData::GetStoreAlias() const +{ + return Anonymous::Change(storeId); +} + std::string StoreMetaData::GetStrategyKey() const { if (instanceId == 0) { diff --git a/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp b/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp index 1725d66c06009aeaf6d6eeb7595f31c50201e7d9..4b1cdf06abdd7d5fa24fbdc1a1faff0cde9aa6d8 100644 --- a/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp +++ b/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp @@ -40,7 +40,7 @@ bool PolicyValue::IsValueEffect() const bool StoreMetaDataLocal::HasPolicy(uint32_t type) { - for (auto &policy : policies) { + for (const auto &policy : policies) { if (policy.type == type) { return true; } @@ -50,7 +50,7 @@ bool StoreMetaDataLocal::HasPolicy(uint32_t type) PolicyValue StoreMetaDataLocal::GetPolicy(uint32_t type) { - for (auto &policy : policies) { + for (const auto &policy : policies) { if (policy.type == type) { return policy; } diff --git a/services/distributeddataservice/framework/serializable/serializable.cpp b/services/distributeddataservice/framework/serializable/serializable.cpp index 509880a851e84c2958e43ab2078b3d1ab8943266..68fa96db110db7723ce66c4c3ef6fc659cf1bb1c 100644 --- a/services/distributeddataservice/framework/serializable/serializable.cpp +++ b/services/distributeddataservice/framework/serializable/serializable.cpp @@ -116,11 +116,19 @@ bool Serializable::GetValue(const json &node, const std::string &name, uint64_t bool Serializable::GetValue(const json &node, const std::string &name, bool &value) { auto &subNode = GetSubNode(node, name); - if (subNode.is_null() || !subNode.is_boolean()) { - return false; + if (subNode.is_boolean()) { + subNode.get_to(value); + return true; } - subNode.get_to(value); - return true; + + if (subNode.is_number_unsigned()) { + uint32_t number = 0; + subNode.get_to(number); + value = number != 0; + return true; + } + + return false; } bool Serializable::GetValue(const json &node, const std::string &name, std::vector &value) @@ -166,13 +174,19 @@ bool Serializable::SetValue(json &node, const int64_t &value) return true; } +bool Serializable::SetValue(json &node, const double &value) +{ + node = value; + return true; +} + bool Serializable::SetValue(json &node, const uint64_t &value) { node = value; return true; } -bool Serializable::SetValue(json &node, const bool &value) +bool Serializable::SetValue(json &node, bool &value) { node = value; return true; diff --git a/services/distributeddataservice/framework/store/auto_cache.cpp b/services/distributeddataservice/framework/store/auto_cache.cpp index edeb10cd4351959518a6a725befcaae441715890..8b443036fa7589b51a843ccaef7cb5a85faca738 100644 --- a/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/services/distributeddataservice/framework/store/auto_cache.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "AutoCache" #include "store/auto_cache.h" +#include "utils/anonymous.h" #include "log_print.h" namespace OHOS::DistributedData { @@ -55,7 +56,7 @@ AutoCache::~AutoCache() AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers &watchers) { Store store; - if (meta.storeType >= MAX_CREATOR_NUM || !creators_[meta.storeType]) { + if (meta.storeType >= MAX_CREATOR_NUM || meta.storeType < 0 || !creators_[meta.storeType]) { return store; } @@ -63,7 +64,9 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & [this, &meta, &watchers, &store](auto &, std::map &stores) -> bool { auto it = stores.find(meta.storeId); if (it != stores.end()) { - it->second.SetObservers(watchers); + if (!watchers.empty()) { + it->second.SetObservers(watchers); + } store = it->second; return !stores.empty(); } @@ -91,6 +94,11 @@ void AutoCache::CloseStore(uint32_t tokenId, const std::string &storeId) }); } +void AutoCache::CloseStore(uint32_t tokenId) +{ + stores_.Erase(tokenId); +} + void AutoCache::CloseExcept(const std::set &users) { stores_.EraseIf([&users](const auto &tokenId, std::map &delegates) { @@ -113,7 +121,8 @@ void AutoCache::CloseExcept(const std::set &users) void AutoCache::SetObserver(uint32_t tokenId, const std::string &storeId, const AutoCache::Watchers &watchers) { stores_.ComputeIfPresent(tokenId, [&storeId, &watchers](auto &key, auto &stores) { - ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, storeId.c_str(), watchers.size()); + ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, Anonymous::Change(storeId).c_str(), + watchers.size()); auto it = stores.find(storeId); if (it != stores.end()) { it->second.SetObservers(watchers); @@ -143,15 +152,16 @@ AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, { time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); if (store_ != nullptr) { - store_->Watch(ORIGIN_ALL, *this); + store_->Watch(Origin::ORIGIN_ALL, *this); } } AutoCache::Delegate::~Delegate() { if (store_ != nullptr) { - store_->Unwatch(ORIGIN_ALL, *this); + store_->Unwatch(Origin::ORIGIN_ALL, *this); store_->Close(); + store_->Release(); store_ = nullptr; } } @@ -159,7 +169,11 @@ AutoCache::Delegate::~Delegate() AutoCache::Delegate::operator Store() { time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); - return Store(store_, [](GeneralStore *) {}); + if (store_ != nullptr) { + store_->AddRef(); + return Store(store_, [](GeneralStore *store) { store->Release(); }); + } + return nullptr; } bool AutoCache::Delegate::operator<(const AutoCache::Time &time) const @@ -171,14 +185,13 @@ bool AutoCache::Delegate::Close() { std::unique_lock lock(mutex_); if (store_ != nullptr) { - store_->Unwatch(ORIGIN_ALL, *this); - } - - auto status = store_->Close(); - if (status == Error::E_BUSY) { - return false; + store_->Unwatch(Origin::ORIGIN_ALL, *this); + auto status = store_->Close(); + if (status == Error::E_BUSY) { + return false; + } + store_ = nullptr; } - store_ = nullptr; return true; } @@ -193,34 +206,20 @@ int32_t AutoCache::Delegate::GetUser() const return user_; } -int32_t AutoCache::Delegate::OnChange(Origin origin, const std::string &id) -{ - Watchers watchers; - { - std::unique_lock lock(mutex_); - watchers = watchers_; - } - for (auto watcher : watchers) { - if (watcher == nullptr) { - continue; - } - watcher->OnChange(origin, id); - } - return Error::E_OK; -} - -int32_t AutoCache::Delegate::OnChange(Origin origin, const std::string &id, const std::vector &values) +int32_t AutoCache::Delegate::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) { Watchers watchers; { std::unique_lock lock(mutex_); watchers = watchers_; } - for (auto watcher : watchers) { + size_t remain = watchers.size(); + for (auto &watcher : watchers) { + remain--; if (watcher == nullptr) { continue; } - watcher->OnChange(origin, id, values); + watcher->OnChange(origin, primaryFields, (remain != 0) ? ChangeInfo(values) : std::move(values)); } return Error::E_OK; } diff --git a/services/distributeddataservice/framework/test/BUILD.gn b/services/distributeddataservice/framework/test/BUILD.gn index 1e2ccfa56878f30e7d2cf6cbccd3e45f39836add..ba13118563d60acb0ca051e54f4ee6b8a91e2e58 100644 --- a/services/distributeddataservice/framework/test/BUILD.gn +++ b/services/distributeddataservice/framework/test/BUILD.gn @@ -37,7 +37,7 @@ ohos_unittest("CheckerManagerTest") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -60,7 +60,7 @@ ohos_unittest("EventCenterTest") { external_deps = [ "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -83,7 +83,7 @@ ohos_unittest("SerializableTest") { "ability_base:base", "ability_base:want", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] diff --git a/services/distributeddataservice/framework/test/serializable_test.cpp b/services/distributeddataservice/framework/test/serializable_test.cpp index 95c0154b447b485fbe04080e012199b58ce0f6ce..3729a6e4327aaaae06a9aeab244fa22a9cbd8cb5 100644 --- a/services/distributeddataservice/framework/test/serializable_test.cpp +++ b/services/distributeddataservice/framework/test/serializable_test.cpp @@ -159,3 +159,79 @@ HWTEST_F(SerializableTest, GetMutilVal, TestSize.Level2) normal1.Unmarshall(jstr); ASSERT_TRUE(normalEx == normal1) << normal1.name; } + +/** +* @tc.name: GetMap +* @tc.desc: mutil value case. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Sven Wang +*/ +HWTEST_F(SerializableTest, GetMap, TestSize.Level2) +{ + ZLOGI("SerializableSuite GetMapVals begin."); + std::map marshData; + NormalEx normalEx; + normalEx.normals = { Normal() }; + normalEx.name = "normalEx"; + marshData.insert(std::pair{ "test1", normalEx }); + auto jsonData = NormalEx::Marshall(marshData); + + std::map unmarshData; + NormalEx::Unmarshall(jsonData, unmarshData); + ASSERT_TRUE((marshData["test1"] == unmarshData["test1"])) << jsonData; +} + +/** +* @tc.name: GetMapInStruct +* @tc.desc: mutil value case. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Sven Wang +*/ +HWTEST_F(SerializableTest, GetMapInStruct, TestSize.Level2) +{ + struct TestMeta : public Serializable { + std::map data; + std::map *index = nullptr; + std::vector> others; + ~TestMeta() + { + delete index; + index = nullptr; + } + bool Marshal(json &node) const + { + SetValue(node[GET_NAME(data)], data); + SetValue(node[GET_NAME(index)], index); + SetValue(node[GET_NAME(others)], others); + return true; + } + + bool Unmarshal(const json &node) + { + GetValue(node, GET_NAME(data), data); + GetValue(node, GET_NAME(index), index); + GetValue(node, GET_NAME(others), others); + return true; + } + }; + ZLOGI("SerializableSuite GetMapVals begin."); + TestMeta marData; + NormalEx normalEx; + normalEx.normals = { Normal() }; + normalEx.name = "normalEx"; + marData.data.insert(std::pair{ "test1", normalEx }); + marData.others.push_back({ std::pair{ "test2", normalEx } }); + marData.index = new (std::nothrow) std::map; + ASSERT_NE(marData.index, nullptr); + marData.index->insert(std::pair{ "test1", true }); + marData.index->insert(std::pair{ "test2", true }); + auto jsonData = NormalEx::Marshall(marData); + TestMeta unmarData; + NormalEx::Unmarshall(jsonData, unmarData); + ASSERT_TRUE((marData.data == unmarData.data)) << jsonData; + ASSERT_TRUE((marData.others == unmarData.others)) << jsonData; + ASSERT_NE(unmarData.index, nullptr); + ASSERT_TRUE((*marData.index == *unmarData.index)) << jsonData; +} \ No newline at end of file diff --git a/services/distributeddataservice/framework/utils/constant.cpp b/services/distributeddataservice/framework/utils/constant.cpp index 1f327be961ae11e225e5e9d9db7b49b8bc68eb87..efc99c062d0a9ac0cf185e4e1282557cdfe1046c 100644 --- a/services/distributeddataservice/framework/utils/constant.cpp +++ b/services/distributeddataservice/framework/utils/constant.cpp @@ -14,12 +14,9 @@ */ #define LOG_TAG "Constant" #include "utils/constant.h" - -#include -#include #include -#include #include "log_print.h" +#include "securec.h" namespace OHOS { namespace DistributedData { @@ -85,5 +82,14 @@ bool Constant::IsBackground(pid_t pid) } return false; } + +bool Constant::DCopy(uint8_t *tag, size_t tagLen, const uint8_t *src, size_t srcLen) +{ + if (tagLen != srcLen || tag == nullptr || src == nullptr) { + return false; + } + auto ret = memcpy_s(tag, tagLen, src, srcLen); + return ret == EOK; +} } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/service/kvdb/ref_count.cpp b/services/distributeddataservice/framework/utils/ref_count.cpp similarity index 95% rename from services/distributeddataservice/service/kvdb/ref_count.cpp rename to services/distributeddataservice/framework/utils/ref_count.cpp index fb36dcdb541a74cc3699a0ebee3efe3ee22e75f8..977c817e7ffcdd366f44c115de0254efa16d2298 100644 --- a/services/distributeddataservice/service/kvdb/ref_count.cpp +++ b/services/distributeddataservice/framework/utils/ref_count.cpp @@ -13,8 +13,8 @@ * limitations under the License. */ -#include "ref_count.h" -namespace OHOS::DistributedKv { +#include "utils/ref_count.h" +namespace OHOS::DistributedData { RefCount::RefCount() { } diff --git a/services/distributeddataservice/sa_profile/1301.json b/services/distributeddataservice/sa_profile/1301.json new file mode 100644 index 0000000000000000000000000000000000000000..a625ee9fc05a4cb7ff9154c1bedadc2c7533adf4 --- /dev/null +++ b/services/distributeddataservice/sa_profile/1301.json @@ -0,0 +1,12 @@ +{ + "process": "distributeddata", + "systemability": [ + { + "name": 1301, + "libpath": "libdistributeddataservice.z.so", + "run-on-create": true, + "distributed": false, + "dump_level": 1 + } + ] +} \ No newline at end of file diff --git a/services/distributeddataservice/sa_profile/1301.xml b/services/distributeddataservice/sa_profile/1301.xml deleted file mode 100644 index dd59c9ed78399f7fbf4e2cd64817be5fedba930c..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/sa_profile/1301.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - distributeddata - - 1301 - libdistributeddataservice.z.so - true - false - 1 - - - diff --git a/services/distributeddataservice/service/BUILD.gn b/services/distributeddataservice/service/BUILD.gn index b6360e93f6999b9b8469ac88793f6630d44c1707..ff073e3ea39fe45351ee84c70e909b2e4b584501 100644 --- a/services/distributeddataservice/service/BUILD.gn +++ b/services/distributeddataservice/service/BUILD.gn @@ -16,19 +16,19 @@ import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") group("build_module") { deps = [ ":distributeddatasvc" ] + + if (datamgr_service_udmf) { + deps += [ "${data_service_path}/service/udmf:udmf_server" ] + } } config("module_public_config") { visibility = [ ":*" ] include_dirs = [ "backup/include", "bootstrap/include", + "cloud", "config/include", "crypto/include", - "data_share", - "data_share/strategies", - "data_share/common", - "data_share/data", - "directory/include", "kvdb", "matrix/include", "object", @@ -53,11 +53,16 @@ config("module_public_config") { ohos_shared_library("distributeddatasvc") { include_dirs = [ "../../../../data_object/frameworks/innerkitsimpl/include", + "../../../../relational_store/interfaces/inner_api/cloud_data/include", + "../../../../relational_store/interfaces/inner_api/rdb/include", "${kv_store_distributeddb_path}", ] sources = [ "backup/src/backup_manager.cpp", "bootstrap/src/bootstrap.cpp", + "cloud/cloud_service_impl.cpp", + "cloud/cloud_service_stub.cpp", + "cloud/sync_manager.cpp", "config/src/config_factory.cpp", "config/src/model/backup_config.cpp", "config/src/model/checker_config.cpp", @@ -67,44 +72,12 @@ ohos_shared_library("distributeddatasvc") { "config/src/model/network_config.cpp", "config/src/model/protocol_config.cpp", "crypto/src/crypto_manager.cpp", - "data_share/common/bundle_mgr_proxy.cpp", - "data_share/common/db_delegate.cpp", - "data_share/common/div_strategy.cpp", - "data_share/common/kv_delegate.cpp", - "data_share/common/rdb_delegate.cpp", - "data_share/common/seq_strategy.cpp", - "data_share/common/uri_utils.cpp", - "data_share/data_share_obs_proxy.cpp", - "data_share/data_share_service_impl.cpp", - "data_share/data_share_service_stub.cpp", - "data_share/data_share_types_util.cpp", - "data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", - "data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", - "data_share/strategies/delete_strategy.cpp", - "data_share/strategies/general/check_is_data_proxy_strategy.cpp", - "data_share/strategies/general/check_is_single_app_strategy.cpp", - "data_share/strategies/general/connect_extension_strategy.cpp", - "data_share/strategies/general/empty_strategy.cpp", - "data_share/strategies/general/load_config_common_strategy.cpp", - "data_share/strategies/general/load_config_data_info_strategy.cpp", - "data_share/strategies/general/load_config_from_bundle_info_strategy.cpp", - "data_share/strategies/general/permission_strategy.cpp", - "data_share/strategies/general/process_single_app_user_cross_strategy.cpp", - "data_share/strategies/get_data_strategy.cpp", - "data_share/strategies/insert_strategy.cpp", - "data_share/strategies/publish_strategy.cpp", - "data_share/strategies/query_strategy.cpp", - "data_share/strategies/subscribe_strategy.cpp", - "data_share/strategies/update_strategy.cpp", - "directory/src/directory_manager.cpp", "kvdb/auth_delegate.cpp", - "kvdb/executor_factory.cpp", "kvdb/kvdb_exporter.cpp", "kvdb/kvdb_service_impl.cpp", "kvdb/kvdb_service_stub.cpp", "kvdb/kvstore_sync_manager.cpp", "kvdb/query_helper.cpp", - "kvdb/ref_count.cpp", "kvdb/store_cache.cpp", "kvdb/upgrade.cpp", "kvdb/user_delegate.cpp", @@ -116,13 +89,21 @@ ohos_shared_library("distributeddatasvc") { "object/object_service_impl.cpp", "object/object_service_stub.cpp", "permission/src/permit_delegate.cpp", + "rdb/rdb_asset_loader.cpp", + "rdb/rdb_cloud.cpp", + "rdb/rdb_cloud_data_translate.cpp", + "rdb/rdb_cursor.cpp", + "rdb/rdb_general_store.cpp", "rdb/rdb_notifier_proxy.cpp", + "rdb/rdb_query.cpp", "rdb/rdb_result_set_impl.cpp", "rdb/rdb_result_set_stub.cpp", "rdb/rdb_service_impl.cpp", "rdb/rdb_service_stub.cpp", "rdb/rdb_store_observer_impl.cpp", "rdb/rdb_syncer.cpp", + "rdb/rdb_watcher.cpp", + "rdb/value_proxy.cpp", ] cflags = [ "-Wno-multichar" ] @@ -138,26 +119,16 @@ ohos_shared_library("distributeddatasvc") { ] external_deps = [ - "ability_base:want", - "ability_base:zuri", - "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", + "access_token:libtokenid_sdk", "c_utils:utils", - "data_share:datashare_common", "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", "relational_store:native_rdb", - "relational_store:rdb_bms_adapter", - "relational_store:rdb_data_share_adapter", - "resource_management:global_resmgr", - "samgr:samgr_proxy", ] subsystem_name = "distributeddatamgr" diff --git a/services/distributeddataservice/service/backup/src/backup_manager.cpp b/services/distributeddataservice/service/backup/src/backup_manager.cpp index 5c52cbd735a4d0c3591d586aea8f2c5198580c2a..0c05825c427ac1cf17fd5b12eff25a091d43fdb0 100644 --- a/services/distributeddataservice/service/backup/src/backup_manager.cpp +++ b/services/distributeddataservice/service/backup/src/backup_manager.cpp @@ -18,10 +18,11 @@ #include #include #include + #include "backuprule/backup_rule_manager.h" -#include "device_manager_adapter.h" #include "crypto_manager.h" -#include "directory_manager.h" +#include "device_manager_adapter.h" +#include "directory/directory_manager.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "types.h" @@ -289,7 +290,7 @@ void BackupManager::CopyFile(const std::string &oldPath, const std::string &newP fout.open(newPath, std::ios_base::out | std::ios_base::trunc); } char buf[COPY_SIZE] = {0}; - while (!fin.eof()) { + while (fin.good()) { fin.read(buf, COPY_SIZE); fout.write(buf, fin.gcount()); } diff --git a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 6cdd57ab27b92b1b04055b99e303713c68c66183..8f958cf3a47531883641e53cfec1e70dd490a6b2 100644 --- a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -16,11 +16,12 @@ #include "bootstrap.h" #include -#include "backuprule/backup_rule_manager.h" + #include "backup_manager.h" +#include "backuprule/backup_rule_manager.h" #include "checker/checker_manager.h" #include "config_factory.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "log_print.h" namespace OHOS { namespace DistributedData { diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d2567dbceed3d58e80e48872d3756cb29379159 --- /dev/null +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -0,0 +1,552 @@ +/* + * 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. + */ + +#define LOG_TAG "CloudServiceImpl" + +#include "cloud_service_impl.h" +#include "accesstoken_kit.h" +#include "account/account_delegate.h" +#include "checker/checker_manager.h" +#include "cloud/cloud_server.h" +#include "communicator/device_manager_adapter.h" +#include "eventcenter/event_center.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "rdb_cloud_data_translate.h" +#include "runtime_config.h" +#include "store/auto_cache.h" +#include "utils/anonymous.h" +#include "sync_manager.h" +namespace OHOS::CloudData { +using namespace DistributedData; +using namespace std::chrono; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using Account = OHOS::DistributedKv::AccountDelegate; +using AccessTokenKit = Security::AccessToken::AccessTokenKit; +constexpr std::string_view NET_UUID = "netUuid"; +__attribute__((used)) CloudServiceImpl::Factory CloudServiceImpl::factory_; +const CloudServiceImpl::Work CloudServiceImpl::HANDLERS[WORK_BUTT] = { + &CloudServiceImpl::DoSubscribe, + &CloudServiceImpl::UpdateCloudInfo, + &CloudServiceImpl::UpdateSchema, +}; + +CloudServiceImpl::Factory::Factory() noexcept +{ + FeatureSystem::GetInstance().RegisterCreator( + CloudServiceImpl::SERVICE_NAME, + [this]() { + if (product_ == nullptr) { + product_ = std::make_shared(); + } + return product_; + }, + FeatureSystem::BIND_NOW); +} + +CloudServiceImpl::Factory::~Factory() {} + +CloudServiceImpl::CloudServiceImpl() +{ + EventCenter::GetInstance().Subscribe(CloudEvent::GET_SCHEMA, [this](const Event &event) { + GetSchema(event); + }); +} + +int32_t CloudServiceImpl::EnableCloud(const std::string &id, const std::map &switches) +{ + CloudInfo cloudInfo; + auto status = GetCloudInfo(IPCSkeleton::GetCallingTokenID(), id, cloudInfo); + if (status != SUCCESS) { + return status; + } + cloudInfo.enableCloud = true; + for (const auto &[bundle, value] : switches) { + if (!cloudInfo.Exist(bundle)) { + continue; + } + cloudInfo.apps[bundle].cloudSwitch = (value == SWITCH_ON); + } + if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { + return ERROR; + } + Execute(GetCloudTask(0, cloudInfo.user)); + syncManager_.DoCloudSync({ cloudInfo.user }); + return SUCCESS; +} + +int32_t CloudServiceImpl::DisableCloud(const std::string &id) +{ + CloudInfo cloudInfo; + auto status = GetCloudInfo(IPCSkeleton::GetCallingTokenID(), id, cloudInfo); + if (status != SUCCESS) { + return status; + } + cloudInfo.enableCloud = false; + if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { + return ERROR; + } + Execute(GetCloudTask(0, cloudInfo.user)); + syncManager_.StopCloudSync(cloudInfo.user); + return SUCCESS; +} + +int32_t CloudServiceImpl::ChangeAppSwitch(const std::string &id, const std::string &bundleName, int32_t appSwitch) +{ + CloudInfo cloudInfo; + auto status = GetCloudInfo(IPCSkeleton::GetCallingTokenID(), id, cloudInfo); + if (status != SUCCESS) { + return status; + } + if (!cloudInfo.Exist(bundleName)) { + ZLOGE("bundleName:%{public}s", bundleName.c_str()); + return INVALID_ARGUMENT; + } + cloudInfo.apps[bundleName].cloudSwitch = (appSwitch == SWITCH_ON); + if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { + return ERROR; + } + Execute(GetCloudTask(0, cloudInfo.user)); + if (cloudInfo.enableCloud && appSwitch == SWITCH_ON) { + syncManager_.DoCloudSync({ cloudInfo.user, bundleName }); + } + return SUCCESS; +} + +int32_t CloudServiceImpl::DoClean(CloudInfo &cloudInfo, const std::map &actions) +{ + syncManager_.StopCloudSync(cloudInfo.user); + auto keys = cloudInfo.GetSchemaKey(); + for (const auto &[bundle, action] : actions) { + if (!cloudInfo.Exist(bundle)) { + continue; + } + SchemaMeta schemaMeta; + if (!MetaDataManager::GetInstance().LoadMeta(keys[bundle], schemaMeta, true)) { + ZLOGE("failed, no schema meta:bundleName:%{public}s", bundle.c_str()); + return ERROR; + } + for (const auto &database : schemaMeta.databases) { + // action + StoreMetaData meta; + meta.bundleName = schemaMeta.bundleName; + meta.storeId = database.name; + meta.user = std::to_string(cloudInfo.user); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + meta.instanceId = cloudInfo.apps[bundle].instanceId; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + ZLOGE("failed, no store meta bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + continue; + } + AutoCache::Store store = SyncManager::GetStore(meta, cloudInfo.user, false); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + return ERROR; + } + auto status = store->Clean({}, action, ""); + if (status != E_OK) { + ZLOGW("remove device data status:%{public}d, user:%{pubilc}d, bundleName:%{public}s, " + "storeId:%{public}s", + status, static_cast(cloudInfo.user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + continue; + } + } + } + return SUCCESS; +} + +int32_t CloudServiceImpl::Clean(const std::string &id, const std::map &actions) +{ + CloudInfo cloudInfo; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + cloudInfo.user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + if (GetCloudInfoFromMeta(cloudInfo) != SUCCESS) { + ZLOGE("get cloud meta failed user:%{public}d", static_cast(cloudInfo.user)); + return ERROR; + } + if (id != cloudInfo.id) { + ZLOGE("different id, [server] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(cloudInfo.id).c_str(), + Anonymous::Change(id).c_str()); + } + return DoClean(cloudInfo, actions); +} + +int32_t CloudServiceImpl::NotifyDataChange(const std::string &id, const std::string &bundleName) +{ + CloudInfo cloudInfo; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + cloudInfo.user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + if (GetCloudInfoFromMeta(cloudInfo) != SUCCESS) { + return ERROR; + } + if (cloudInfo.id != id) { + ZLOGE("invalid args, [input] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(id).c_str(), + Anonymous::Change(cloudInfo.id).c_str()); + return INVALID_ARGUMENT; + } + if (!cloudInfo.enableCloud) { + return CLOUD_DISABLE; + } + if (!cloudInfo.Exist(bundleName)) { + ZLOGE("bundleName:%{public}s", bundleName.c_str()); + return INVALID_ARGUMENT; + } + if (!cloudInfo.apps[bundleName].cloudSwitch) { + return CLOUD_DISABLE_SWITCH; + } + syncManager_.DoCloudSync(SyncManager::SyncInfo(cloudInfo.user, bundleName)); + return SUCCESS; +} + +int32_t CloudServiceImpl::OnInitialize() +{ + DistributedDB::RuntimeConfig::SetCloudTranslate(std::make_shared()); + Execute(GetCloudTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + return E_OK; +} + +int32_t CloudServiceImpl::OnBind(const BindInfo &info) +{ + if (executor_ != nullptr || info.executors == nullptr) { + return E_INVALID_ARGS; + } + + executor_ = std::move(info.executors); + syncManager_.Bind(executor_); + return E_OK; +} + +int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) +{ + int32_t userId = atoi(user.c_str()); + if (code == static_cast(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) { + Execute(GetCloudTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + } + syncManager_.StopCloudSync(userId); + return E_OK; +} + +int32_t CloudServiceImpl::Online(const std::string &device) +{ + if (device != NET_UUID) { + ZLOGI("Not network online"); + return SUCCESS; + } + std::vector users; + Account::GetInstance()->QueryUsers(users); + if (users.empty()) { + return SUCCESS; + } + auto it = users.begin(); + syncManager_.DoCloudSync({ *it }); + return SUCCESS; +} + +int32_t CloudServiceImpl::Offline(const std::string &device) +{ + if (device != NET_UUID) { + ZLOGI("Not network offline"); + return SUCCESS; + } + std::vector users; + Account::GetInstance()->QueryUsers(users); + if (users.empty()) { + return SUCCESS; + } + auto it = users.begin(); + syncManager_.StopCloudSync(*it); + return SUCCESS; +} + +int32_t CloudServiceImpl::GetCloudInfo(uint32_t tokenId, const std::string &id, CloudInfo &cloudInfo) +{ + cloudInfo.user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + if (GetCloudInfoFromMeta(cloudInfo) != SUCCESS) { + auto status = GetCloudInfoFromServer(cloudInfo); + if (status != SUCCESS) { + ZLOGE("user:%{public}d", cloudInfo.user); + return status; + } + } + if (cloudInfo.id != id) { + ZLOGE("invalid args, [input] id:%{public}s, [exist] id:%{public}s", Anonymous::Change(id).c_str(), + Anonymous::Change(cloudInfo.id).c_str()); + return INVALID_ARGUMENT; + } + return SUCCESS; +} + +int32_t CloudServiceImpl::GetCloudInfoFromMeta(CloudInfo &cloudInfo) +{ + if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true)) { + ZLOGE("no exist meta, user:%{public}d", cloudInfo.user); + return ERROR; + } + return SUCCESS; +} + +int32_t CloudServiceImpl::GetCloudInfoFromServer(CloudInfo &cloudInfo) +{ + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return NOT_SUPPORT; + } + cloudInfo = instance->GetServerInfo(cloudInfo.user); + if (!cloudInfo.IsValid()) { + ZLOGE("cloud is empty, user%{public}d", cloudInfo.user); + return ERROR; + } + return SUCCESS; +} + +bool CloudServiceImpl::UpdateCloudInfo(int32_t user) +{ + CloudInfo cloudInfo; + cloudInfo.user = user; + if (GetCloudInfoFromServer(cloudInfo) != SUCCESS) { + ZLOGE("failed, user:%{public}d", user); + return false; + } + CloudInfo oldInfo; + if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), oldInfo, true)) { + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + return true; + } + if (oldInfo.id != cloudInfo.id) { + ZLOGE("different id, [server] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(cloudInfo.id).c_str(), + Anonymous::Change(oldInfo.id).c_str()); + std::map actions; + for (auto &[bundle, app] : cloudInfo.apps) { + actions[bundle] = CLEAR_CLOUD_INFO; + } + DoClean(oldInfo, actions); + } + if (cloudInfo.enableCloud) { + for (auto &[bundle, app] : cloudInfo.apps) { + if (app.cloudSwitch && !oldInfo.apps[bundle].cloudSwitch) { + syncManager_.DoCloudSync({ cloudInfo.user, bundle }); + } + } + } + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + return true; +} + +bool CloudServiceImpl::UpdateSchema(int32_t user) +{ + CloudInfo cloudInfo; + cloudInfo.user = user; + if (GetCloudInfoFromServer(cloudInfo) != SUCCESS) { + ZLOGE("failed, user:%{public}d", user); + return false; + } + auto keys = cloudInfo.GetSchemaKey(); + for (const auto &[bundle, key] : keys) { + SchemaMeta schemaMeta; + if (MetaDataManager::GetInstance().LoadMeta(key, schemaMeta, true)) { + continue; + } + if (GetAppSchema(cloudInfo.user, bundle, schemaMeta) != SUCCESS) { + return false; + } + MetaDataManager::GetInstance().SaveMeta(key, schemaMeta, true); + } + return true; +} + +int32_t CloudServiceImpl::GetAppSchema(int32_t user, const std::string &bundleName, SchemaMeta &schemaMeta) +{ + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return SERVER_UNAVAILABLE; + } + schemaMeta = instance->GetAppSchema(user, bundleName); + return SUCCESS; +} + +CloudServiceImpl::Tasks CloudServiceImpl::GetCloudTask( + int32_t retry, int32_t user, const std::initializer_list &works) +{ + Tasks tasks; + tasks.reserve(works.size() + 1); + for (auto work : works) { + tasks.push_back(GenTask(retry, user, work)); + } + tasks.push_back(GenTask(retry, user, WORK_SUB)); + return tasks; +} + +ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, AsyncWork work) +{ + return [this, retry, user, work]() -> void { + auto executor = executor_; + if (retry >= RETRY_TIMES || executor == nullptr) { + return; + } + + bool finished = true; + std::vector users; + if (user == 0) { + auto account = Account::GetInstance(); + finished = account == nullptr ? false : account->QueryUsers(users); + } else { + users.push_back(user); + } + + for (auto user : users) { + finished = (this->*HANDLERS[work])(user) && finished; + } + if (!finished) { + executor->Schedule(std::chrono::seconds(RETRY_INTERVAL), GenTask(retry + 1, user, work)); + } + }; +} + +SchemaMeta CloudServiceImpl::GetSchemaMeta(int32_t userId, const std::string &bundleName, int32_t instanceId) +{ + SchemaMeta schemaMeta; + CloudInfo cloudInfo = GetCloudInfo(userId); + if (!cloudInfo.IsValid()) { + // GetCloudInfo has print the log info. so we don`t need print again. + return schemaMeta; + } + + if (!bundleName.empty() && !cloudInfo.Exist(bundleName, instanceId)) { + ZLOGD("bundleName:%{public}s instanceId:%{public}d is not exist", bundleName.c_str(), instanceId); + return schemaMeta; + } + std::string schemaKey = cloudInfo.GetSchemaKey(bundleName, instanceId); + if (MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { + return schemaMeta; + } + + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return schemaMeta; + } + schemaMeta = instance->GetAppSchema(userId, bundleName); + if (!schemaMeta.IsValid()) { + ZLOGE("download schema from cloud failed, user:%{public}d, bundleName:%{public}s", userId, bundleName.c_str()); + } + MetaDataManager::GetInstance().SaveMeta(schemaKey, schemaMeta, true); + return schemaMeta; +} + +CloudInfo CloudServiceImpl::GetCloudInfo(int32_t userId) +{ + CloudInfo cloudInfo; + cloudInfo.user = userId; + if (MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true)) { + return cloudInfo; + } + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return cloudInfo; + } + + cloudInfo = instance->GetServerInfo(userId); + if (!cloudInfo.IsValid()) { + ZLOGE("no cloud info %{public}d", userId); + return cloudInfo; + } + + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + return cloudInfo; +} + +int32_t CloudServiceImpl::OnAppUninstall( + const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) +{ + (void)tokenId; + MetaDataManager::GetInstance().DelMeta(Subscription::GetRelationKey(user, bundleName), true); + MetaDataManager::GetInstance().DelMeta(CloudInfo::GetSchemaKey(user, bundleName, index), true); + return E_OK; +} + +void CloudServiceImpl::GetSchema(const Event &event) +{ + auto &rdbEvent = static_cast(event); + auto &storeInfo = rdbEvent.GetStoreInfo(); + ZLOGD("Start GetSchema, bundleName:%{public}s, storeName:%{public}s, instanceId:%{public}d", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.instanceId); + GetSchemaMeta(storeInfo.user, storeInfo.bundleName, storeInfo.instanceId); +} + +bool CloudServiceImpl::DoSubscribe(int32_t user) +{ + Subscription sub; + sub.userId = user; + MetaDataManager::GetInstance().LoadMeta(sub.GetKey(), sub, true); + if (CloudServer::GetInstance() == nullptr) { + ZLOGI("not support cloud server"); + return true; + } + + CloudInfo cloudInfo; + cloudInfo.user = sub.userId; + auto exits = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true); + if (!exits) { + ZLOGW("error, there is no cloud info for user(%{public}d)", sub.userId); + return false; + } + + ZLOGD("begin cloud:%{public}d user:%{public}d apps:%{public}zu", cloudInfo.enableCloud, sub.userId, + cloudInfo.apps.size()); + auto onThreshold = duration_cast((system_clock::now() + hours(EXPIRE_INTERVAL)).time_since_epoch()); + auto offThreshold = duration_cast(system_clock::now().time_since_epoch()); + std::map> subDbs; + std::map> unsubDbs; + for (auto &[bundle, app] : cloudInfo.apps) { + auto enabled = cloudInfo.enableCloud && app.cloudSwitch; + auto &dbs = enabled ? subDbs : unsubDbs; + auto it = sub.expiresTime.find(bundle); + // cloud is enabled, but the subscription won't expire + if (enabled && (it != sub.expiresTime.end() && it->second >= static_cast(onThreshold.count()))) { + continue; + } + // cloud is disabled, we don't care the subscription which was expired or didn't subscribe. + if (!enabled && (it == sub.expiresTime.end() || it->second <= static_cast(offThreshold.count()))) { + continue; + } + + SchemaMeta schemaMeta; + exits = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(bundle), schemaMeta, true); + if (exits) { + dbs.insert_or_assign(bundle, std::move(schemaMeta.databases)); + } + } + + ZLOGI("cloud switch:%{public}d user%{public}d, sub:%{public}zu, unsub:%{public}zu", cloudInfo.enableCloud, + sub.userId, subDbs.size(), unsubDbs.size()); + ZLOGD("Subscribe user%{public}d details:%{public}s", sub.userId, Serializable::Marshall(subDbs).c_str()); + ZLOGD("Unsubscribe user%{public}d details:%{public}s", sub.userId, Serializable::Marshall(unsubDbs).c_str()); + CloudServer::GetInstance()->Subscribe(sub.userId, subDbs); + CloudServer::GetInstance()->Unsubscribe(sub.userId, unsubDbs); + return subDbs.empty() && unsubDbs.empty(); +} + +void CloudServiceImpl::Execute(Tasks tasks) +{ + for (auto &task : tasks) { + auto executor = executor_; + if (executor == nullptr) { + return; + } + executor->Execute(std::move(task)); + } +} +} // namespace OHOS::CloudData \ No newline at end of file diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.h b/services/distributeddataservice/service/cloud/cloud_service_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..93803ab38b71e2c647e3ba4bb500905a213caa7c --- /dev/null +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_IMPL_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_IMPL_H + +#include +#include "cloud/cloud_event.h" +#include "cloud/cloud_info.h" +#include "cloud/schema_meta.h" +#include "cloud/subscription.h" +#include "cloud_service_stub.h" +#include "sync_manager.h" +namespace OHOS::CloudData { +class CloudServiceImpl : public CloudServiceStub { +public: + using StoreMetaData = DistributedData::StoreMetaData; + CloudServiceImpl(); + ~CloudServiceImpl() = default; + int32_t EnableCloud(const std::string &id, const std::map &switches) override; + int32_t DisableCloud(const std::string &id) override; + int32_t ChangeAppSwitch(const std::string &id, const std::string &bundleName, int32_t appSwitch) override; + int32_t Clean(const std::string &id, const std::map &actions) override; + int32_t NotifyDataChange(const std::string &id, const std::string &bundleName) override; + int32_t OnInitialize() override; + int32_t OnBind(const BindInfo &info) override; + int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; + int32_t Online(const std::string &device) override; + int32_t Offline(const std::string &device) override; + +private: + class Factory { + public: + Factory() noexcept; + ~Factory(); + private: + std::shared_ptr product_; + }; + static Factory factory_; + + using CloudInfo = DistributedData::CloudInfo; + using SchemaMeta = DistributedData::SchemaMeta; + using Event = DistributedData::Event; + using Subscription = DistributedData::Subscription; + using Work = bool (CloudServiceImpl::*)(int32_t); + using Tasks = std::vector; + + enum AsyncWork : int32_t { + WORK_SUB = 0, + WORK_CLOUD_INFO_UPDATE, + WORK_SCHEMA_UPDATE, + WORK_BUTT, + }; + + static constexpr int32_t RETRY_TIMES = 10; + static constexpr int32_t RETRY_INTERVAL = 30; + static constexpr int32_t EXPIRE_INTERVAL = 7 * 24; // 7 day + + bool UpdateCloudInfo(int32_t user); + bool UpdateSchema(int32_t user); + SchemaMeta GetSchemaMeta(int32_t userId, const std::string &bundleName, int32_t instanceId); + CloudInfo GetCloudInfo(int32_t userId); + int32_t GetCloudInfo(uint32_t tokenId, const std::string &id, CloudInfo &cloudInfo); + int32_t GetCloudInfoFromMeta(CloudInfo &cloudInfo); + int32_t GetCloudInfoFromServer(CloudInfo &cloudInfo); + int32_t GetAppSchema(int32_t user, const std::string &bundleName, SchemaMeta &schemaMeta); + void GetSchema(const Event &event); + Tasks GetCloudTask(int32_t retry, int32_t user, const std::initializer_list &works = {}); + ExecutorPool::Task GenTask(int32_t retry, int32_t user, AsyncWork work); + void Execute(Tasks tasks); + bool DoSubscribe(int32_t user); + int32_t DoClean(CloudInfo &cloudInfo, const std::map &actions); + std::shared_ptr executor_; + SyncManager syncManager_; + static const Work HANDLERS[WORK_BUTT]; +}; +} // namespace OHOS::DistributedData + +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_IMPL_H diff --git a/services/distributeddataservice/service/cloud/cloud_service_stub.cpp b/services/distributeddataservice/service/cloud/cloud_service_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..34a65dc155c4a6fbd3098652813d7dad75e2fd3d --- /dev/null +++ b/services/distributeddataservice/service/cloud/cloud_service_stub.cpp @@ -0,0 +1,120 @@ +/* + * 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. + */ +#define LOG_TAG "CloudServiceStub" +#include "cloud_service_stub.h" + +#include "ipc_skeleton.h" +#include "itypes_util.h" +#include "log_print.h" +#include "permission/permission_validator.h" +#include "utils/anonymous.h" +#include "tokenid_kit.h" +namespace OHOS::CloudData { +using namespace DistributedData; +using namespace OHOS::Security::AccessToken; +const CloudServiceStub::Handler CloudServiceStub::HANDLERS[TRANS_BUTT] = { + &CloudServiceStub::OnEnableCloud, + &CloudServiceStub::OnDisableCloud, + &CloudServiceStub::OnChangeAppSwitch, + &CloudServiceStub::OnClean, + &CloudServiceStub::OnNotifyDataChange, +}; + +int CloudServiceStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply) +{ + ZLOGI("code:%{public}u callingPid:%{public}u", code, IPCSkeleton::GetCallingPid()); + std::u16string local = CloudServiceStub::GetDescriptor(); + std::u16string remote = data.ReadInterfaceToken(); + if (local != remote) { + ZLOGE("local is not equal to remote"); + return -1; + } + + if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] == nullptr) { + ZLOGE("not support code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT); + return -1; + } + + if (!TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { + ZLOGE("permission denied! code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT); + auto result = static_cast(PERMISSION_DENIED); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; + } + + if (!DistributedKv::PermissionValidator::GetInstance().IsCloudConfigPermit(IPCSkeleton::GetCallingTokenID())) { + ZLOGE("cloud config permission denied! code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT); + auto result = static_cast(CLOUD_CONFIG_PERMISSION_DENIED); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; + } + + std::string id; + if (!ITypesUtil::Unmarshal(data, id)) { + ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + return (this->*HANDLERS[code])(id, data, reply); +} + +int32_t CloudServiceStub::OnEnableCloud(const std::string &id, MessageParcel &data, MessageParcel &reply) +{ + std::map switches; + if (!ITypesUtil::Unmarshal(data, switches)) { + ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto result = EnableCloud(id, switches); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t CloudServiceStub::OnDisableCloud(const std::string &id, MessageParcel &data, MessageParcel &reply) +{ + auto result = DisableCloud(id); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t CloudServiceStub::OnChangeAppSwitch(const std::string &id, MessageParcel &data, MessageParcel &reply) +{ + std::string bundleName; + int32_t appSwitch = SWITCH_OFF; + if (!ITypesUtil::Unmarshal(data, bundleName, appSwitch)) { + ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto result = ChangeAppSwitch(id, bundleName, appSwitch); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t CloudServiceStub::OnClean(const std::string &id, MessageParcel &data, MessageParcel &reply) +{ + std::map actions; + if (!ITypesUtil::Unmarshal(data, actions)) { + ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto result = Clean(id, actions); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t CloudServiceStub::OnNotifyDataChange(const std::string &id, MessageParcel &data, MessageParcel &reply) +{ + std::string bundleName; + if (!ITypesUtil::Unmarshal(data, bundleName)) { + ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto result = NotifyDataChange(id, bundleName); + return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR; +} +} // namespace OHOS::CloudData diff --git a/services/distributeddataservice/service/cloud/cloud_service_stub.h b/services/distributeddataservice/service/cloud/cloud_service_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..4175015d2731ca380b02874ab4af692502cd22d9 --- /dev/null +++ b/services/distributeddataservice/service/cloud/cloud_service_stub.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_STUB_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_STUB_H +#include "cloud_service.h" +#include "feature/feature_system.h" +#include "iremote_broker.h" +namespace OHOS::CloudData { +class CloudServiceStub : public CloudService, public DistributedData::FeatureSystem::Feature { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CloudData.CloudServer"); + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; + +private: + using Handler = int32_t (CloudServiceStub::*)(const std::string &id, MessageParcel &data, MessageParcel &reply); + int32_t OnEnableCloud(const std::string &id, MessageParcel &data, MessageParcel &reply); + int32_t OnDisableCloud(const std::string &id, MessageParcel &data, MessageParcel &reply); + int32_t OnChangeAppSwitch(const std::string &id, MessageParcel &data, MessageParcel &reply); + int32_t OnClean(const std::string &id, MessageParcel &data, MessageParcel &reply); + int32_t OnNotifyDataChange(const std::string &id, MessageParcel &data, MessageParcel &reply); + static const Handler HANDLERS[TRANS_BUTT]; +}; +} // namespace OHOS::CloudData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_STUB_H diff --git a/services/distributeddataservice/service/cloud/sync_manager.cpp b/services/distributeddataservice/service/cloud/sync_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf2064d505d1b3abee9d1933f0f4114433ff7ff3 --- /dev/null +++ b/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -0,0 +1,376 @@ +/* + * 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. + */ +#define LOG_TAG "SyncManager" +#include "sync_manager.h" + +#include "cloud/cloud_info.h" +#include "cloud/cloud_server.h" +#include "cloud/schema_meta.h" +#include "cloud/sync_event.h" +#include "device_manager_adapter.h" +#include "eventcenter/event_center.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "store/auto_cache.h" +#include "utils/anonymous.h" +namespace OHOS::CloudData { +using namespace DistributedData; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using Defer = EventCenter::Defer; +std::atomic SyncManager::genId_ = 0; +SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const Store &store, const Tables &tables) + : user_(user), bundleName_(bundleName) +{ + if (!store.empty()) { + tables_[store] = tables; + } + syncId_ = SyncManager::GenerateId(user); +} + +SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores) + : user_(user), bundleName_(bundleName) +{ + for (auto &store : stores) { + tables_[store] = {}; + } + syncId_ = SyncManager::GenerateId(user); +} + +SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables) + : user_(user), bundleName_(bundleName), tables_(tables) +{ + tables_ = tables; + syncId_ = SyncManager::GenerateId(user); +} + +void SyncManager::SyncInfo::SetMode(int32_t mode) +{ + mode_ = mode; +} + +void SyncManager::SyncInfo::SetWait(int32_t wait) +{ + wait_ = wait; +} + +void SyncManager::SyncInfo::SetAsyncDetail(GenAsync asyncDetail) +{ + async_ = std::move(asyncDetail); +} + +void SyncManager::SyncInfo::SetQuery(std::shared_ptr query) +{ + query_ = query; +} + +void SyncManager::SyncInfo::SetError(int32_t code) const +{ + if (async_) { + GenDetails details; + auto &detail = details[id_]; + detail.progress = SYNC_FINISH; + detail.code = code; + async_(std::move(details)); + } +} + +std::shared_ptr SyncManager::SyncInfo::GenerateQuery(const std::string &store, const Tables &tables) +{ + if (query_ != nullptr) { + return query_; + } + class SyncQuery final : public GenQuery { + public: + explicit SyncQuery(const std::vector &tables) : tables_(tables) + { + } + + bool IsEqual(uint64_t tid) override + { + return false; + } + + std::vector GetTables() override + { + return tables_; + } + + private: + std::vector tables_; + }; + auto &syncTables = tables_[store]; + return std::make_shared(syncTables.empty() ? tables : syncTables); +} + +SyncManager::SyncManager() +{ + EventCenter::GetInstance().Subscribe(CloudEvent::LOCAL_CHANGE, GetClientChangeHandler()); +} + +SyncManager::~SyncManager() +{ + if (executor_ != nullptr) { + actives_.ForEachCopies([this](auto &syncId, auto &taskId) { + executor_->Remove(taskId); + return false; + }); + executor_ = nullptr; + } +} + +int32_t SyncManager::Bind(std::shared_ptr executor) +{ + executor_ = executor; + return E_OK; +} + +int32_t SyncManager::DoCloudSync(SyncInfo syncInfo) +{ + if (executor_ == nullptr) { + return E_NOT_INIT; + } + + actives_.Compute(GenerateId(syncInfo.user_), [this, &syncInfo](const uint64_t &key, TaskId &taskId) mutable { + taskId = executor_->Execute(GetSyncTask(0, true, GenSyncRef(key), std::move(syncInfo))); + return true; + }); + + return E_OK; +} + +int32_t SyncManager::StopCloudSync(int32_t user) +{ + if (executor_ == nullptr) { + return E_NOT_INIT; + } + actives_.ForEachCopies([this, user](auto &syncId, auto &taskId) { + if (Compare(syncId, user) == 0) { + executor_->Remove(taskId); + } + return false; + }); + return E_OK; +} + +ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount ref, SyncInfo &&syncInfo) +{ + times++; + return [this, times, retry, ref = std::move(ref), info = std::move(syncInfo)]() mutable { + activeInfos_.Erase(info.syncId_); + CloudInfo cloud; + cloud.user = info.user_; + if (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true)) { + info.SetError(E_CLOUD_DISABLED); + ZLOGE("no cloud info for user:%{public}d", info.user_); + return; + } + + if (!cloud.enableCloud || (info.id_ != SyncInfo::DEFAULT_ID && cloud.id != info.id_) || + (!info.bundleName_.empty() && !cloud.IsOn(info.bundleName_))) { + info.SetError(E_CLOUD_DISABLED); + return; + } + + if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + info.SetError(E_NETWORK_ERROR); + return; + } + + std::vector schemas; + auto key = cloud.GetSchemaPrefix(info.bundleName_); + auto retryer = GetRetryer(times, info); + if (!MetaDataManager::GetInstance().LoadMeta(key, schemas, true)) { + UpdateSchema(info); + retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT); + return; + } + + Defer defer(GetSyncHandler(std::move(retryer)), CloudEvent::CLOUD_SYNC); + for (auto &schema : schemas) { + if (!cloud.IsOn(schema.bundleName)) { + continue; + } + + for (const auto &database : schema.databases) { + CloudEvent::StoreInfo storeInfo; + storeInfo.bundleName = schema.bundleName; + storeInfo.user = cloud.user; + storeInfo.storeName = database.name; + storeInfo.instanceId = cloud.apps[schema.bundleName].instanceId; + auto query = info.GenerateQuery(database.name, database.GetTableNames()); + auto evt = std::make_unique(std::move(storeInfo), + SyncEvent::EventInfo { info.mode_, info.wait_, retry, std::move(query), info.async_ }); + EventCenter::GetInstance().PostEvent(std::move(evt)); + } + } + }; +} + +std::function SyncManager::GetSyncHandler(Retryer retryer) +{ + return [retryer](const Event &event) { + auto &evt = static_cast(event); + auto &storeInfo = evt.GetStoreInfo(); + StoreMetaData meta; + meta.storeId = storeInfo.storeName; + meta.bundleName = storeInfo.bundleName; + meta.user = std::to_string(storeInfo.user); + meta.instanceId = storeInfo.instanceId; + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + ZLOGE("failed, no store meta bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + return; + } + auto store = GetStore(meta, storeInfo.user); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + return; + } + + ZLOGD("database:<%{public}d:%{public}s:%{public}s> sync start", storeInfo.user, storeInfo.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + auto status = store->Sync({ SyncInfo::DEFAULT_ID }, evt.GetMode(), *(evt.GetQuery()), evt.AutoRetry() + ? [retryer](const GenDetails &details) { + if (details.empty()) { + ZLOGE("retry, details empty"); + return; + } + int32_t code = details.begin()->second.code; + retryer(code == E_LOCKED_BY_OTHERS ? LOCKED_INTERVAL : RETRY_INTERVAL, code); + } + : evt.GetAsyncDetail(), evt.GetWait()); + GenAsync async = evt.GetAsyncDetail(); + if (status != E_OK && async) { + GenDetails details; + auto &detail = details[SyncInfo::DEFAULT_ID]; + detail.progress = SYNC_FINISH; + detail.code = status; + async(std::move(details)); + } + }; +} + +std::function SyncManager::GetClientChangeHandler() +{ + return [this](const Event &event) { + auto &evt = static_cast(event); + auto store = evt.GetStoreInfo(); + SyncInfo syncInfo(store.user, store.bundleName, store.storeName); + syncInfo.SetMode(evt.GetMode()); + syncInfo.SetWait(evt.GetWait()); + syncInfo.SetAsyncDetail(evt.GetAsyncDetail()); + syncInfo.SetQuery(evt.GetQuery()); + auto times = evt.AutoRetry() ? RETRY_TIMES - CLIENT_RETRY_TIMES : RETRY_TIMES; + auto task = GetSyncTask(times, evt.AutoRetry(), RefCount(), std::move(syncInfo)); + task(); + }; +} + +SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &syncInfo) +{ + if (times >= RETRY_TIMES) { + return [info = SyncInfo(syncInfo)](Duration, int32_t code) mutable { + if (code == E_OK) { + return true; + } + info.SetError(code); + return true; + }; + } + return [this, times, info = SyncInfo(syncInfo)](Duration interval, int32_t code) mutable { + if (code == E_OK) { + return true; + } + + activeInfos_.ComputeIfAbsent(info.syncId_, [this, times, interval, &info](uint64_t key) mutable { + auto syncId = GenerateId(info.user_); + actives_.Compute(syncId, [this, times, interval, &info](const uint64_t &key, TaskId &value) mutable { + value = executor_->Schedule(interval, GetSyncTask(times, true, GenSyncRef(key), std::move(info))); + return true; + }); + return syncId; + }); + return true; + }; +} + +uint64_t SyncManager::GenerateId(int32_t user) +{ + uint64_t syncId = static_cast(user) & 0xFFFFFFFF; + return (syncId << MV_BIT) | (++genId_); +} + +RefCount SyncManager::GenSyncRef(uint64_t syncId) +{ + return RefCount([syncId, this]() { + actives_.Erase(syncId); + }); +} + +int32_t SyncManager::Compare(uint64_t syncId, int32_t user) +{ + uint64_t inner = static_cast(user) & 0xFFFFFFFF; + return (syncId & USER_MARK) == (inner << MV_BIT); +} + +void SyncManager::UpdateSchema(const SyncManager::SyncInfo &syncInfo) +{ + CloudEvent::StoreInfo storeInfo; + storeInfo.user = syncInfo.user_; + storeInfo.bundleName = syncInfo.bundleName_; + EventCenter::GetInstance().PostEvent(std::make_unique(CloudEvent::GET_SCHEMA, storeInfo)); +} + +AutoCache::Store SyncManager::GetStore(const StoreMetaData &meta, int32_t user, bool mustBind) +{ + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + ZLOGD("not support cloud sync"); + return nullptr; + } + + auto store = AutoCache::GetInstance().GetStore(meta, {}); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + return nullptr; + } + + if (!store->IsBound()) { + CloudInfo info; + info.user = user; + SchemaMeta schemaMeta; + std::string schemaKey = info.GetSchemaKey(meta.bundleName, meta.instanceId); + if (!MetaDataManager::GetInstance().LoadMeta(std::move(schemaKey), schemaMeta, true)) { + ZLOGE("failed, no schema bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + return nullptr; + } + auto dbMeta = schemaMeta.GetDataBase(meta.storeId); + auto cloudDB = instance->ConnectCloudDB(meta.tokenId, dbMeta); + auto assetLoader = instance->ConnectAssetLoader(meta.tokenId, dbMeta); + if (mustBind && (cloudDB == nullptr || assetLoader == nullptr)) { + ZLOGE("failed, no cloud DB <0x%{public}x %{public}s<->%{public}s>", meta.tokenId, dbMeta.name.c_str(), + dbMeta.alias.c_str()); + return nullptr; + } + + if (cloudDB != nullptr || assetLoader != nullptr) { + store->Bind(dbMeta, { std::move(cloudDB), std::move(assetLoader) }); + } + } + return store; +} +} // namespace OHOS::CloudData \ No newline at end of file diff --git a/services/distributeddataservice/service/cloud/sync_manager.h b/services/distributeddataservice/service/cloud/sync_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..5f19611d598e45c9abe87e25ad5fbea9ad0bc2d1 --- /dev/null +++ b/services/distributeddataservice/service/cloud/sync_manager.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H +#include "eventcenter/event.h" +#include "executor_pool.h" +#include "store/auto_cache.h" +#include "store/general_store.h" +#include "store/general_value.h" +#include "utils/ref_count.h" +#include "concurrent_map.h" +namespace OHOS::CloudData { +class SyncManager { +public: + using GenAsync = DistributedData::GenAsync; + using GenStore = DistributedData::GeneralStore; + using GenQuery = DistributedData::GenQuery; + using RefCount = DistributedData::RefCount; + using AutoCache = DistributedData::AutoCache; + using StoreMetaData = DistributedData::StoreMetaData; + static AutoCache::Store GetStore(const StoreMetaData &meta, int32_t user, bool mustBind = true); + class SyncInfo final { + public: + using Store = std::string; + using Stores = std::vector; + using Tables = std::vector; + using MutliStoreTables = std::map; + SyncInfo(int32_t user, const std::string &bundleName = "", const Store &store = "", const Tables &tables = {}); + SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores); + SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables); + void SetMode(int32_t mode); + void SetWait(int32_t wait); + void SetAsyncDetail(GenAsync asyncDetail); + void SetQuery(std::shared_ptr query); + void SetError(int32_t code) const; + std::shared_ptr GenerateQuery(const std::string &store, const Tables &tables); + inline static constexpr const char *DEFAULT_ID = "default"; + + private: + friend SyncManager; + uint64_t syncId_ = 0; + int32_t mode_ = GenStore::CLOUD_TIME_FIRST; + int32_t user_ = 0; + int32_t wait_ = 0; + std::string id_ = DEFAULT_ID; + std::string bundleName_; + std::map> tables_; + GenAsync async_; + std::shared_ptr query_; + }; + SyncManager(); + ~SyncManager(); + int32_t Bind(std::shared_ptr executor); + int32_t DoCloudSync(SyncInfo syncInfo); + int32_t StopCloudSync(int32_t user = 0); + +private: + using Event = DistributedData::Event; + using Task = ExecutorPool::Task; + using TaskId = ExecutorPool::TaskId; + using Duration = ExecutorPool::Duration; + using Retryer = std::function; + + static constexpr ExecutorPool::Duration RETRY_INTERVAL = std::chrono::seconds(10); // second + static constexpr ExecutorPool::Duration LOCKED_INTERVAL = std::chrono::seconds(30); // second + static constexpr int32_t RETRY_TIMES = 6; // normal retry + static constexpr int32_t CLIENT_RETRY_TIMES = 3; // normal retry + static constexpr uint64_t USER_MARK = 0xFFFFFFFF00000000; // high 32 bit + static constexpr int32_t MV_BIT = 32; + + Task GetSyncTask(int32_t times, bool retry, RefCount ref, SyncInfo &&syncInfo); + void UpdateSchema(const SyncInfo &syncInfo); + std::function GetSyncHandler(Retryer retryer); + std::function GetClientChangeHandler(); + Retryer GetRetryer(int32_t times, const SyncInfo &syncInfo); + static uint64_t GenerateId(int32_t user); + RefCount GenSyncRef(uint64_t syncId); + int32_t Compare(uint64_t syncId, int32_t user); + + static std::atomic genId_; + std::shared_ptr executor_; + ConcurrentMap actives_; + ConcurrentMap activeInfos_; +}; +} // namespace OHOS::CloudData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H diff --git a/services/distributeddataservice/service/config/include/model/directory_config.h b/services/distributeddataservice/service/config/include/model/directory_config.h index baa7b05c6f37b6cba71afda5357d2394e6a09a03..034224999aea26e3220458857f877e2aa544cb5f 100644 --- a/services/distributeddataservice/service/config/include/model/directory_config.h +++ b/services/distributeddataservice/service/config/include/model/directory_config.h @@ -15,7 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_DIRECTORY_CONFIG_H #define OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_DIRECTORY_CONFIG_H -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "serializable/serializable.h" namespace OHOS { namespace DistributedData { diff --git a/services/distributeddataservice/service/data_share/BUILD.gn b/services/distributeddataservice/service/data_share/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..33b972ab893cdd8b3f735ea2380b0dabe536f904 --- /dev/null +++ b/services/distributeddataservice/service/data_share/BUILD.gn @@ -0,0 +1,115 @@ +# 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. +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") +import("datamgr_service_data_share.gni") +config("module_public_config") { + visibility = [ ":*" ] + include_dirs = [ + ".", + "strategies", + "common", + "data", + "//third_party/json/single_include", + "../../adapter/include", + "../../app/src", + "../../framework/include", + "${datashare_path}/frameworks/native/common/include", + "${datashare_path}/interfaces/inner_api/common/include", + "${datashare_path}/interfaces/inner_api/consumer/include", + ] +} +group("build_module") { + deps = [ ":data_share_service" ] +} +ohos_shared_library("data_share_service") { + sources = [ + "common/app_connect_manager.cpp", + "common/bundle_mgr_proxy.cpp", + "common/db_delegate.cpp", + "common/div_strategy.cpp", + "common/extension_connect_adaptor.cpp", + "common/extension_mgr_proxy.cpp", + "common/kv_delegate.cpp", + "common/rdb_delegate.cpp", + "common/scheduler_manager.cpp", + "common/seq_strategy.cpp", + "common/uri_utils.cpp", + "data/published_data.cpp", + "data/resultset_json_formatter.cpp", + "data/template_data.cpp", + "data_share_obs_proxy.cpp", + "data_share_service_impl.cpp", + "data_share_service_stub.cpp", + "data_share_types_util.cpp", + "strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", + "strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", + "strategies/delete_strategy.cpp", + "strategies/general/check_is_data_proxy_strategy.cpp", + "strategies/general/check_is_single_app_strategy.cpp", + "strategies/general/cross_permission_strategy.cpp", + "strategies/general/empty_strategy.cpp", + "strategies/general/load_config_common_strategy.cpp", + "strategies/general/load_config_data_info_strategy.cpp", + "strategies/general/load_config_from_bundle_info_strategy.cpp", + "strategies/general/permission_strategy.cpp", + "strategies/general/process_single_app_user_cross_strategy.cpp", + "strategies/get_data_strategy.cpp", + "strategies/insert_strategy.cpp", + "strategies/publish_strategy.cpp", + "strategies/query_strategy.cpp", + "strategies/rdb_notify_strategy.cpp", + "strategies/subscribe_strategy.cpp", + "strategies/template_strategy.cpp", + "strategies/update_strategy.cpp", + "subscriber_managers/published_data_subscriber_manager.cpp", + "subscriber_managers/rdb_subscriber_manager.cpp", + ] + cflags = [ "-Wno-multichar" ] + + cflags_cc = [ "-fvisibility=hidden" ] + + configs = [ ":module_public_config" ] + + deps = [ + "${gaussrd_path}:gaussdb_rd", + "../../adapter:distributeddata_adapter", + "../../adapter/utils:distributeddata_utils_static", + "../../framework:distributeddatasvcfwk", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "data_share:datashare_common", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "ipc:ipc_core", + "relational_store:native_rdb", + "relational_store:rdb_bms_adapter", + "relational_store:rdb_data_share_adapter", + "samgr:samgr_proxy", + ] + subsystem_name = "distributeddatamgr" + + part_name = "datamgr_service" +} diff --git a/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp b/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edd6df8c37b69ddb8275771ed2c227f12cbbfe7a --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp @@ -0,0 +1,58 @@ +/* + * 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. + */ +#define LOG_TAG "AppConnectManager" +#include "app_connect_manager.h" +#include "log_print.h" + +namespace OHOS::DataShare { +ConcurrentMap *> AppConnectManager::blockCache_; +bool AppConnectManager::Wait(const std::string &bundleName, + int maxWaitTime, std::function connect, std::function disconnect) +{ + BlockData block(maxWaitTime, false); + auto result = blockCache_.ComputeIfAbsent(bundleName, [&block](const std::string &key) { + return █ + }); + if (!result) { + ZLOGE("is running %{public}s", bundleName.c_str()); + return false; + } + ZLOGI("start connect %{public}s", bundleName.c_str()); + result = connect(); + if (!result) { + ZLOGE("connect failed %{public}s", bundleName.c_str()); + blockCache_.Erase(bundleName); + return false; + } + result = block.GetValue(); + ZLOGI("end wait %{public}s", bundleName.c_str()); + blockCache_.Erase(bundleName); + disconnect(); + return result; +} + +void AppConnectManager::Notify(const std::string &bundleName) +{ + ZLOGI("notify %{public}s", bundleName.c_str()); + blockCache_.ComputeIfPresent(bundleName, [&bundleName](const std::string &key, BlockData *value) { + if (value == nullptr) { + ZLOGI("nullptr %{public}s", bundleName.c_str()); + return false; + } + value->SetValue(true); + return true; + }); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/app_connect_manager.h b/services/distributeddataservice/service/data_share/common/app_connect_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..3c447f7792cf97d26b0cfcfde088eb39a90dbe9f --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/app_connect_manager.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_APP_CONNECT_MANAGER_H +#define DATASHARESERVICE_APP_CONNECT_MANAGER_H + +#include +#include + +#include "block_data.h" +#include "concurrent_map.h" + +namespace OHOS::DataShare { +class AppConnectManager { +public: + static bool Wait(const std::string &bundleName, int maxWaitTime, std::function connect, + std::function disconnect); + static void Notify(const std::string &bundleName); + +private: + static ConcurrentMap *> blockCache_; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/services/distributeddataservice/service/data_share/common/callback_impl.h b/services/distributeddataservice/service/data_share/common/callback_impl.h index 072379099a943957520b1f265e414e6cdab62cb9..451f375fa18526d6ac8afeb9425276ed9ee526ad 100644 --- a/services/distributeddataservice/service/data_share/common/callback_impl.h +++ b/services/distributeddataservice/service/data_share/common/callback_impl.h @@ -16,13 +16,12 @@ #define DATASHARESERVICE_CALLBACK_IMPL_H #include "ability_connect_callback_stub.h" -#include "ability_manager_client.h" #include "block_data.h" namespace OHOS::DataShare { class CallbackImpl : public AAFwk::AbilityConnectionStub { public: - CallbackImpl(BlockData &data) : data_(data) {} + explicit CallbackImpl(BlockData &data) : data_(data) {} void OnAbilityConnectDone( const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override { diff --git a/services/distributeddataservice/service/data_share/common/context.h b/services/distributeddataservice/service/data_share/common/context.h index d506e4b1651146aec3236c1d766b1afad0e25a59..59b2e9a197feebf28f2ed799bd153a9e80986eb3 100644 --- a/services/distributeddataservice/service/data_share/common/context.h +++ b/services/distributeddataservice/service/data_share/common/context.h @@ -38,7 +38,7 @@ public: std::string uri; int32_t currentUserId = -1; std::string permission; - uint32_t callerTokenId = -1; + uint32_t callerTokenId = 0; std::string callerBundleName; std::string calledBundleName; std::string calledModuleName; @@ -48,6 +48,8 @@ public: int version = -1; int errCode = -1; bool isRead = false; + bool isAllowCrossPer = false; // can cross permission check, for special SA + bool needAutoLoadCallerBundleName = false; AccessSystemMode accessSystemMode = AccessSystemMode::UNDEFINED; OHOS::AppExecFwk::BundleInfo bundleInfo; std::string type = "rdb"; diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 97e451bc2ce054bdd42f98b6d281b04897bcfb3b..5cf07278a5753b048b3c8e814f705a08705657a5 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -16,44 +16,43 @@ #include "db_delegate.h" #include "kv_delegate.h" +#include "log_print.h" #include "rdb_delegate.h" namespace OHOS::DataShare { -std::shared_ptr DBDelegate::Create(const std::string &dir, int version) +std::shared_ptr DBDelegate::Create(const std::string &dir, int version, bool registerFunction) { - return std::make_shared(dir, version); + return std::make_shared(dir, version, registerFunction); } -std::shared_ptr KvDBDelegate::GetInstance(bool reInit, const std::string &dir) +std::shared_ptr KvDBDelegate::GetInstance( + bool reInit, const std::string &dir, const std::shared_ptr &executors) { static std::shared_ptr delegate = nullptr; static std::mutex mutex; std::lock_guard lock(mutex); if (delegate == nullptr || reInit) { - delegate = std::make_shared(dir); + delegate = std::make_shared(dir, executors); } return delegate; } -bool KvData::Marshal(DistributedData::Serializable::json &node) const -{ - auto ret = SetValue(node, *GetId()); - if (HasVersion()) { - ret &= SetValue(node, GetVersion()); - } - return ret & SetValue(node, GetValue()); -} - bool Id::Marshal(DistributedData::Serializable::json &node) const { - return SetValue(node[GET_NAME(_id)], _id); + auto ret = false; + if (userId == INVALID_USER) { + ret = SetValue(node[GET_NAME(_id)], _id); + } else { + ret = SetValue(node[GET_NAME(_id)], _id + "_" + std::to_string(userId)); + } + return ret; } bool Id::Unmarshal(const DistributedData::Serializable::json &node) { - return GetValue(node, GET_NAME(_id), _id); + return false; } -Id::Id(const std::string &id) : _id(id) {} +Id::Id(const std::string &id, const int32_t userId) : _id(id), userId(userId) {} VersionData::VersionData(int version) : version(version) {} @@ -66,4 +65,11 @@ bool VersionData::Marshal(DistributedData::Serializable::json &node) const { return SetValue(node[GET_NAME(version)], version); } + +const std::string &KvData::GetId() const +{ + return id; +} + +KvData::KvData(const Id &id) : id(DistributedData::Serializable::Marshall(id)) {} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.h b/services/distributeddataservice/service/data_share/common/db_delegate.h index e6ec2721c78b4a8972bdf5420d7b9cfd7ef2409f..373521d6e51cb79569f83799a7e85427eaa171b5 100644 --- a/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -18,42 +18,45 @@ #include +#include "abs_shared_result_set.h" #include "concurrent_map.h" #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" +#include "executor_pool.h" #include "result_set.h" #include "serializable/serializable.h" namespace OHOS::DataShare { class DBDelegate { public: - static std::shared_ptr Create(const std::string &dir, int version); + static std::shared_ptr Create(const std::string &dir, int version, bool registerFunction = true); virtual int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) = 0; virtual std::shared_ptr Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; - virtual std::shared_ptr Query( + virtual std::string Query( const std::string &sql, const std::vector &selectionArgs = std::vector()) = 0; - virtual int ExecuteSql(const std::string &sql) = 0; + virtual std::shared_ptr QuerySql(const std::string &sql) = 0; }; -struct RdbStoreContext { - RdbStoreContext(const std::string &dir, int version) : dir(dir), version(version) {} - std::string dir; - int version; -}; - -struct Id final: public DistributedData::Serializable { - explicit Id(const std::string &id); +class Id : public DistributedData::Serializable { +public: + static constexpr int INVALID_USER = -1; + Id(const std::string &id, const int32_t userId); ~Id() = default; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; + operator std::string() + { + return DistributedData::Serializable::Marshall(*this); + } private: std::string _id; + int32_t userId; }; class VersionData : public DistributedData::Serializable { @@ -61,12 +64,11 @@ public: explicit VersionData(int version); bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; - VersionData &operator=(int inputVersion) + virtual void SetVersion(int ver) { - version = inputVersion; - return *this; + version = ver; }; - operator int() + virtual int GetVersion() const { return version; }; @@ -75,22 +77,27 @@ private: int version; }; -struct KvData : public DistributedData::Serializable { - virtual std::shared_ptr GetId() const = 0; +class KvData { +public: + explicit KvData(const Id &id); + const std::string &GetId() const; virtual bool HasVersion() const = 0; - virtual VersionData GetVersion() const = 0; - virtual const Serializable &GetValue() const = 0; - bool Marshal(json &node) const override; + virtual int GetVersion() const = 0; + virtual std::string GetValue() const = 0; + +private: + std::string id; }; class KvDBDelegate { public: static constexpr const char *TEMPLATE_TABLE = "template_"; static constexpr const char *DATA_TABLE = "data_"; - static std::shared_ptr GetInstance(bool reInit = false, const std::string &dir = ""); + static std::shared_ptr GetInstance( + bool reInit = false, const std::string &dir = "", const std::shared_ptr &executors = nullptr); virtual ~KvDBDelegate() = default; virtual int32_t Upsert(const std::string &collectionName, const KvData &value) = 0; - virtual int32_t DeleteById(const std::string &collectionName, const Id &id) = 0; + virtual int32_t Delete(const std::string &collectionName, const std::string &filter) = 0; virtual int32_t Get(const std::string &collectionName, const Id &id, std::string &value) = 0; virtual int32_t Get(const std::string &collectionName, const std::string &filter, const std::string &projection, std::string &result) = 0; diff --git a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp similarity index 47% rename from services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp rename to services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp index eecd0c38089df7b3c6689e9f05069c71d9ec5278..a0deba23e9859a342af0a42f719259b37cb2b9ad 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp +++ b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp @@ -12,36 +12,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "ConnectExtensionStrategy" +#define LOG_TAG "ExtensionConnectAdaptor" -#include "connect_extension_strategy.h" +#include "extension_connect_adaptor.h" #include -#include "log_print.h" + +#include "app_connect_manager.h" #include "callback_impl.h" +#include "extension_mgr_proxy.h" +#include "log_print.h" namespace OHOS::DataShare { -bool ConnectExtensionStrategy::operator()(std::shared_ptr context) +bool ExtensionConnectAdaptor::Connect(std::shared_ptr context) { - for (auto &extension: context->bundleInfo.extensionInfos) { + for (auto const &extension : context->bundleInfo.extensionInfos) { if (extension.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - return Connect(context); + return DoConnect(context); } } return false; } -ConnectExtensionStrategy::ConnectExtensionStrategy() : data_(1) {} +ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(1) {} -bool ConnectExtensionStrategy::Connect(std::shared_ptr context) +bool ExtensionConnectAdaptor::DoConnect(std::shared_ptr context) { - std::lock_guard lock(mutex_); - AAFwk::Want want; - want.SetUri(context->uri); data_.Clear(); - sptr callback = new CallbackImpl(data_); + callback_ = new (std::nothrow) CallbackImpl(data_); + if (callback_ == nullptr) { + ZLOGE("new failed"); + return false; + } ZLOGI("Start connect %{public}s", context->uri.c_str()); - ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, callback, nullptr); + ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(context->uri, callback_->AsObject(), nullptr); if (ret != ERR_OK) { ZLOGE("connect ability failed, ret = %{public}d", ret); return false; @@ -50,35 +54,35 @@ bool ConnectExtensionStrategy::Connect(std::shared_ptr context) if (result) { ZLOGI("connect ability ended successfully"); } - data_.Clear(); - AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(callback); - if (!data_.GetValue()) { - ZLOGI("disconnect ability ended successfully"); - } return result; } -bool ConnectExtensionStrategy::Execute( - std::shared_ptr context, std::function isFinished, int maxWaitTimeMs) +bool ExtensionConnectAdaptor::TryAndWait(std::shared_ptr context, int maxWaitTime) { - ConnectExtensionStrategy strategy; - if (!strategy(context)) { - return false; - } - if (isFinished == nullptr) { - return true; + ExtensionConnectAdaptor strategy; + return AppConnectManager::Wait( + context->calledBundleName, maxWaitTime, + [&context, &strategy]() { + return strategy.Connect(context); + }, + [&strategy]() { + strategy.Disconnect(); + return true; + }); +} + +void ExtensionConnectAdaptor::Disconnect() +{ + if (callback_ == nullptr) { + ZLOGE("callback null"); + return; } - int waitTime = 0; - static constexpr int retryTime = 500; - while (!isFinished()) { - if (waitTime > maxWaitTimeMs) { - ZLOGE("cannot finish work"); - return false; - } - ZLOGI("has wait %{public}d ms", waitTime); - std::this_thread::sleep_for(std::chrono::milliseconds(retryTime)); - waitTime += retryTime; + data_.Clear(); + ZLOGI("Start disconnect"); + ExtensionMgrProxy::GetInstance()->DisConnect(callback_->AsObject()); + if (!data_.GetValue()) { + ZLOGI("disconnect ability ended successfully"); } - return true; + callback_ = nullptr; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h new file mode 100644 index 0000000000000000000000000000000000000000..7ada7d5668ce285bbbf686622f646b0a810c4314 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_EXTENSION_CONNECT_ADAPTOR_H +#define DATASHARESERVICE_EXTENSION_CONNECT_ADAPTOR_H + +#include "ability_connect_callback_interface.h" +#include "block_data.h" +#include "context.h" +namespace OHOS::DataShare { +class ExtensionConnectAdaptor { +public: + static bool TryAndWait(std::shared_ptr context, int maxWaitTime = 2); + ExtensionConnectAdaptor(); + +private: + bool Connect(std::shared_ptr context); + void Disconnect(); + bool DoConnect(std::shared_ptr context); + BlockData data_; + sptr callback_ = nullptr; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6081f85bebf6dfcc41cdec17cab8b23761360b9 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#define LOG_TAG "AppConnectManager" +#include "extension_mgr_proxy.h" + +#include "app_connect_manager.h" +#include "extension_ability_info.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "log_print.h" +#include "system_ability_definition.h" +#include "want.h" +namespace OHOS::DataShare { +void ExtensionMgrProxy::OnProxyDied() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; + proxy_ = nullptr; +} + +ExtensionMgrProxy::~ExtensionMgrProxy() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } +} + +std::shared_ptr ExtensionMgrProxy::GetInstance() +{ + static std::shared_ptr proxy = std::make_shared(); + return proxy; +} + +bool ExtensionMgrProxy::Connect( + const std::string &uri, const sptr &connect, const sptr &callerToken) +{ + AAFwk::Want want; + want.SetUri(uri); + std::lock_guard lock(mutex_); + if (ConnectSA()) { + return proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); + } + return false; +} + +bool ExtensionMgrProxy::ConnectSA() +{ + if (proxy_ != nullptr) { + return true; + } + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + ZLOGE("Failed to get system ability mgr."); + return false; + } + + sa_ = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (sa_ == nullptr) { + ZLOGE("Failed to GetSystemAbility."); + return false; + } + deathRecipient_ = new (std::nothrow) ExtensionMgrProxy::ServiceDeathRecipient(weak_from_this()); + if (deathRecipient_ == nullptr) { + ZLOGE("deathRecipient alloc failed."); + return false; + } + sa_->AddDeathRecipient(deathRecipient_); + proxy_ = new (std::nothrow)Proxy(sa_); + if (proxy_ == nullptr) { + ZLOGE("proxy_ null, new failed"); + return false; + } + return true; +} + +bool ExtensionMgrProxy::DisConnect(sptr connect) +{ + std::lock_guard lock(mutex_); + if (ConnectSA()) { + return proxy_->DisconnectAbility(connect); + } + return false; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..d107cde68d21696105e62896b178c7bd950020a7 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_EXTENSION_PROXY_H +#define DATASHARESERVICE_EXTENSION_PROXY_H + +#include +#include + +#include "extension_manager_proxy.h" +namespace OHOS::DataShare { +class ExtensionMgrProxy final : public std::enable_shared_from_this { +public: + // do not use + ExtensionMgrProxy() = default; + ~ExtensionMgrProxy(); + static std::shared_ptr GetInstance(); + bool Connect(const std::string &uri, const sptr &connect, const sptr &callerToken); + bool DisConnect(sptr connect); +private: + using Proxy = AAFwk::ExtensionManagerProxy; + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit ServiceDeathRecipient(std::weak_ptr owner) : owner_(owner) + { + } + void OnRemoteDied(const wptr &object) override + { + auto owner = owner_.lock(); + if (owner != nullptr) { + owner->OnProxyDied(); + } + } + + private: + std::weak_ptr owner_; + }; + void OnProxyDied(); + bool ConnectSA(); + std::mutex mutex_; + sptr sa_; + sptr proxy_; + sptr deathRecipient_; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.cpp b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp index cbbb3fcd6ee97b82ae3552dece03f1ca4e84264d..9e36164adaed8b19c14a2ccf6743d041f5f5cc3a 100644 --- a/services/distributeddataservice/service/data_share/common/kv_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp @@ -14,50 +14,123 @@ */ #define LOG_TAG "KvAdaptor" #include "kv_delegate.h" + #include "datashare_errno.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" +#include "grd_base/grd_error.h" +#include "grd_document/grd_document_api.h" #include "ipc_skeleton.h" #include "log_print.h" namespace OHOS::DataShare { +constexpr int WAIT_TIME = 30; int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string &filter, const std::string &value) { + std::lock_guard lock(mutex_); + if (!Init()) { + ZLOGE("init failed, %{public}s", collectionName.c_str()); + return E_ERROR; + } + int count = GRD_UpsertDoc(db_, collectionName.c_str(), filter.c_str(), value.c_str(), 0); + if (count <= 0) { + ZLOGE("GRD_UpSertDoc failed,status %{public}d", count); + return count; + } + Flush(); return E_OK; } -int64_t KvDelegate::Delete(const std::string &collectionName, const std::string &filter) +int32_t KvDelegate::Delete(const std::string &collectionName, const std::string &filter) { + std::lock_guard lock(mutex_); + if (!Init()) { + ZLOGE("init failed, %{public}s", collectionName.c_str()); + return E_ERROR; + } + std::vector queryResults; + + int32_t status = GetBatch(collectionName, filter, "{\"id_\": true}", queryResults); + if (status != E_OK) { + ZLOGE("db GetBatch failed, %{public}s %{public}d", filter.c_str(), status); + return status; + } + for (auto &result : queryResults) { + auto count = GRD_DeleteDoc(db_, collectionName.c_str(), result.c_str(), 0); + if (count < 0) { + ZLOGE("GRD_UpSertDoc failed,status %{public}d %{public}s", count, result.c_str()); + continue; + } + } + Flush(); + if (queryResults.size() > 0) { + ZLOGI("Delete, %{public}s, count %{public}zu", collectionName.c_str(), queryResults.size()); + } return E_OK; } bool KvDelegate::Init() { if (isInitDone_) { + if (executors_ != nullptr) { + executors_->Reset(taskId_, std::chrono::seconds(WAIT_TIME)); + } return true; } + int status = GRD_DBOpen( + (path_ + "/dataShare.db").c_str(), nullptr, GRD_DB_OPEN_CREATE | GRD_DB_OPEN_CHECK_FOR_ABNORMAL, &db_); + if (status != GRD_OK || db_ == nullptr) { + ZLOGE("GRD_DBOpen failed,status %{public}d", status); + return false; + } + if (executors_ != nullptr) { + taskId_ = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this]() { + std::lock_guard lock(mutex_); + GRD_DBClose(db_, GRD_DB_CLOSE); + db_ = nullptr; + isInitDone_ = false; + taskId_ = ExecutorPool::INVALID_TASK_ID; + }); + } + status = GRD_CreateCollection(db_, TEMPLATE_TABLE, nullptr, 0); + if (status != GRD_OK) { + ZLOGE("GRD_CreateCollection template table failed,status %{public}d", status); + return false; + } + + status = GRD_CreateCollection(db_, DATA_TABLE, nullptr, 0); + if (status != GRD_OK) { + ZLOGE("GRD_CreateCollection data table failed,status %{public}d", status); + return false; + } isInitDone_ = true; return true; } +KvDelegate::~KvDelegate() +{ + std::lock_guard lock(mutex_); + if (isInitDone_) { + int status = GRD_DBClose(db_, 0); + if (status != GRD_OK) { + ZLOGE("GRD_DBClose failed,status %{public}d", status); + } + } +} + int32_t KvDelegate::Upsert(const std::string &collectionName, const KvData &value) { - std::string id = DistributedData::Serializable::Marshall(*value.GetId()); + std::string id = value.GetId(); if (value.HasVersion() && value.GetVersion() != 0) { int version = -1; if (GetVersion(collectionName, id, version)) { if (value.GetVersion() <= version) { ZLOGE("GetVersion failed,%{public}s id %{private}s %{public}d %{public}d", collectionName.c_str(), - id.c_str(), static_cast(value.GetVersion()), version); + id.c_str(), value.GetVersion(), version); return E_VERSION_NOT_NEWER; } } } - return Upsert(collectionName, id, DistributedData::Serializable::Marshall(value.GetValue())); -} - -int32_t KvDelegate::DeleteById(const std::string &collectionName, const Id &id) -{ - return Delete(collectionName, DistributedData::Serializable::Marshall(id)); + return Upsert(collectionName, id, value.GetValue()); } int32_t KvDelegate::Get(const std::string &collectionName, const Id &id, std::string &value) @@ -65,9 +138,9 @@ int32_t KvDelegate::Get(const std::string &collectionName, const Id &id, std::st std::string filter = DistributedData::Serializable::Marshall(id); if (Get(collectionName, filter, "{}", value) != E_OK) { ZLOGE("Get failed, %{public}s %{public}s", collectionName.c_str(), filter.c_str()); - return false; + return E_ERROR; } - return true; + return E_OK; } bool KvDelegate::GetVersion(const std::string &collectionName, const std::string &filter, int &version) @@ -82,25 +155,88 @@ bool KvDelegate::GetVersion(const std::string &collectionName, const std::string ZLOGE("Unmarshall failed,data %{public}s", value.c_str()); return false; } - version = data; + version = data.GetVersion(); return true; } int32_t KvDelegate::Get( const std::string &collectionName, const std::string &filter, const std::string &projection, std::string &result) { + std::lock_guard lock(mutex_); + if (!Init()) { + ZLOGE("init failed, %{public}s", collectionName.c_str()); + return E_ERROR; + } + Query query; + query.filter = filter.c_str(); + query.projection = projection.c_str(); + GRD_ResultSet *resultSet = nullptr; + int status = GRD_FindDoc(db_, collectionName.c_str(), query, 0, &resultSet); + if (status != GRD_OK || resultSet == nullptr) { + ZLOGE("GRD_FindDoc failed,status %{public}d", status); + return status; + } + status = GRD_Next(resultSet); + if (status != GRD_OK) { + GRD_FreeResultSet(resultSet); + ZLOGE("GRD_Next failed,status %{public}d", status); + return status; + } + char *value = nullptr; + status = GRD_GetValue(resultSet, &value); + if (status != GRD_OK || value == nullptr) { + GRD_FreeResultSet(resultSet); + ZLOGE("GRD_GetValue failed,status %{public}d", status); + return status; + } + result = value; + GRD_FreeValue(value); + GRD_FreeResultSet(resultSet); return E_OK; } void KvDelegate::Flush() { + int status = GRD_Flush(db_, GRD_DB_FLUSH_ASYNC); + if (status != GRD_OK) { + ZLOGE("GRD_Flush failed,status %{public}d", status); + } } int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, std::vector &result) { + std::lock_guard lock(mutex_); + if (!Init()) { + ZLOGE("init failed, %{public}s", collectionName.c_str()); + return E_ERROR; + } + Query query; + query.filter = filter.c_str(); + query.projection = projection.c_str(); + GRD_ResultSet *resultSet; + int status = GRD_FindDoc(db_, collectionName.c_str(), query, GRD_DOC_ID_DISPLAY, &resultSet); + if (status != GRD_OK || resultSet == nullptr) { + ZLOGE("GRD_UpSertDoc failed,status %{public}d", status); + return status; + } + char *value = nullptr; + while (GRD_Next(resultSet) == GRD_OK) { + status = GRD_GetValue(resultSet, &value); + if (status != GRD_OK || value == nullptr) { + GRD_FreeResultSet(resultSet); + ZLOGE("GRD_GetValue failed,status %{public}d", status); + return status; + } + result.emplace_back(value); + GRD_FreeValue(value); + } + GRD_FreeResultSet(resultSet); return E_OK; } -KvDelegate::KvDelegate(const std::string &path) : path_(path) {} +KvDelegate::KvDelegate(const std::string &path, const std::shared_ptr &executors) + : path_(path), executors_(executors) +{ +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.h b/services/distributeddataservice/service/data_share/common/kv_delegate.h index fe11133734d8e6102a2b7619fb18e04302d6908b..e3d19e08c05494f4b95f8f69798145115a15cc95 100644 --- a/services/distributeddataservice/service/data_share/common/kv_delegate.h +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.h @@ -20,13 +20,16 @@ #include #include "db_delegate.h" +#include "executor_pool.h" +#include "grd_base/grd_db_api.h" namespace OHOS::DataShare { class KvDelegate final : public KvDBDelegate { public: - explicit KvDelegate(const std::string &path); + KvDelegate(const std::string &path, const std::shared_ptr &executors); + ~KvDelegate() override; int32_t Upsert(const std::string &collectionName, const KvData &value) override; - int32_t DeleteById(const std::string &collectionName, const Id &id) override; + int32_t Delete(const std::string &collectionName, const std::string &filter) override; int32_t Get(const std::string &collectionName, const Id &id, std::string &value) override; int32_t Get(const std::string &collectionName, const std::string &filter, const std::string &projection, @@ -38,10 +41,13 @@ private: bool Init(); bool GetVersion(const std::string &collectionName, const std::string &filter, int &version); int64_t Upsert(const std::string &collectionName, const std::string &filter, const std::string &value); - int64_t Delete(const std::string &collectionName, const std::string &filter); void Flush(); + std::recursive_mutex mutex_; std::string path_; + GRD_DB *db_ = nullptr; bool isInitDone_ = false; + std::shared_ptr executors_ = nullptr; + ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_KV_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index a5e6ad2177a3481882e1555589af42d5c718678b..308d17f4d27cace9ceb9c778b4cf51e0e4dddd79 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -15,16 +15,48 @@ #define LOG_TAG "RdbAdaptor" #include "rdb_delegate.h" +#include "resultset_json_formatter.h" #include "log_print.h" +#include "rdb_utils.h" +#include "scheduler_manager.h" #include "utils/anonymous.h" namespace OHOS::DataShare { constexpr static int32_t MAX_RESULTSET_COUNT = 16; std::atomic RdbDelegate::resultSetCount = 0; -RdbDelegate::RdbDelegate(const std::string &dir, int version) +enum REMIND_TIMER_ARGS : int32_t { + ARG_DB_PATH = 0, + ARG_VERSION, + ARG_URI, + ARG_SUBSCRIBER_ID, + ARG_BUNDLE_NAME, + ARG_USER_ID, + ARG_TIME, + ARGS_SIZE +}; +std::string RemindTimerFunc(const std::vector &args) +{ + size_t size = args.size(); + if (size != ARGS_SIZE) { + ZLOGE("RemindTimerFunc args size error, %{public}zu", size); + return ""; + } + std::string dbPath = args[ARG_DB_PATH]; + int version = std::strtol(args[ARG_VERSION].c_str(), nullptr, 0); + Key key(args[ARG_URI], std::strtoll(args[ARG_SUBSCRIBER_ID].c_str(), nullptr, 0), args[ARG_BUNDLE_NAME]); + int64_t reminderTime = std::strtoll(args[ARG_TIME].c_str(), nullptr, 0); + int32_t userId = std::strtol(args[ARG_USER_ID].c_str(), nullptr, 0); + SchedulerManager::GetInstance().SetTimer(dbPath, userId, version, key, reminderTime); + return args[ARG_TIME]; +} + +RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunction) { RdbStoreConfig config(dir); config.SetCreateNecessary(false); + if (registerFunction) { + config.SetScalarFunction("remindTimer", ARGS_SIZE, RemindTimerFunc); + } DefaultOpenCallback callback; store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_); if (errCode_ != E_OK) { @@ -77,9 +109,8 @@ int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredica } return changeCount; } -std::shared_ptr RdbDelegate::Query( - const std::string &tableName, const DataSharePredicates &predicates, - const std::vector &columns, int &errCode) +std::shared_ptr RdbDelegate::Query(const std::string &tableName, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) { if (store_ == nullptr) { ZLOGE("store is null"); @@ -108,27 +139,27 @@ std::shared_ptr RdbDelegate::Query( }); } -std::shared_ptr RdbDelegate::Query( - const std::string &sql, const std::vector &selectionArgs) +std::string RdbDelegate::Query(const std::string &sql, const std::vector &selectionArgs) { if (store_ == nullptr) { ZLOGE("store is null"); - return nullptr; + return ""; } - std::shared_ptr resultSet = store_->QueryByStep(sql, selectionArgs); + auto resultSet = store_->QueryByStep(sql, selectionArgs); if (resultSet == nullptr) { ZLOGE("Query failed %{private}s", sql.c_str()); - return nullptr; + return ""; } - return nullptr; + ResultSetJsonFormatter formatter(std::move(resultSet)); + return DistributedData::Serializable::Marshall(formatter); } -int RdbDelegate::ExecuteSql(const std::string &sql) +std::shared_ptr RdbDelegate::QuerySql(const std::string &sql) { if (store_ == nullptr) { ZLOGE("store is null"); - return -1; + return nullptr; } - return store_->ExecuteSql(sql); + return store_->QuerySql(sql); } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/services/distributeddataservice/service/data_share/common/rdb_delegate.h index b8fdcd9243664c21db37af4ee18dc489a94b46ae..02093dce577d19fabb3b94d4373e542534d6f1be 100644 --- a/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,21 +31,20 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const std::string &dir, int version); + explicit RdbDelegate(const std::string &dir, int version, bool registerFunction); int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) override; std::shared_ptr Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) override; - std::shared_ptr Query( - const std::string &sql, const std::vector &selectionArgs) override; - int ExecuteSql(const std::string &sql) override; + std::string Query(const std::string &sql, const std::vector &selectionArgs) override; + std::shared_ptr QuerySql(const std::string &sql) override; private: static std::atomic resultSetCount; std::shared_ptr store_; - int errCode_; + int errCode_ = E_OK; }; class DefaultOpenCallback : public RdbOpenCallback { public: diff --git a/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp b/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8152a7d0bc6a4ffaebfcd7f6aba9ebed58f5ea37 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp @@ -0,0 +1,197 @@ +/* + * 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. + */ +#define LOG_TAG "SchedulerManager" + +#include "scheduler_manager.h" + +#include "log_print.h" +#include "uri_utils.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +SchedulerManager &SchedulerManager::GetInstance() +{ + static SchedulerManager instance; + return instance; +} + +void SchedulerManager::Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version) +{ + if (!URIUtils::IsDataProxyURI(uri)) { + return; + } + auto delegate = DBDelegate::Create(rdbDir, version, true); + if (delegate == nullptr) { + ZLOGE("malloc fail %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + return; + } + std::vector keys = RdbSubscriberManager::GetInstance().GetKeysByUri(uri); + for (auto const &key : keys) { + ExecuteSchedulerSQL(rdbDir, userId, version, key, delegate); + } +} + +void SchedulerManager::Execute(const Key &key, const int32_t userId, const std::string &rdbDir, int version) +{ + auto delegate = DBDelegate::Create(rdbDir, version, true); + if (delegate == nullptr) { + ZLOGE("malloc fail %{public}s", DistributedData::Anonymous::Change(key.uri).c_str()); + return; + } + ExecuteSchedulerSQL(rdbDir, userId, version, key, delegate); +} + +void SchedulerManager::SetTimer( + const std::string &dbPath, const int32_t userId, int version, const Key &key, int64_t reminderTime) +{ + std::lock_guard lock(mutex_); + if (executor_ == nullptr) { + ZLOGE("executor_ is nullptr"); + return; + } + // reminder time must is in future + auto now = time(nullptr); + if (reminderTime <= now) { + ZLOGE("reminderTime is not in future, %{public}" PRId64 "%{public}" PRId64, reminderTime, now); + return; + } + auto duration = std::chrono::seconds(reminderTime - now); + ZLOGI("reminderTime will notify in %{public}" PRId64 " seconds", reminderTime - now); + auto it = timerCache_.find(key); + if (it != timerCache_.end()) { + // has current timer, reset time + ZLOGD("has current taskId, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is %{public}s", + key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + executor_->Reset(it->second, duration); + return; + } + // not find task in map, create new timer + auto taskId = executor_->Schedule(duration, [key, dbPath, version, userId, this]() { + ZLOGI("schedule notify start, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is " + "%{public}s", key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + timerCache_.erase(key); + // 1. execute schedulerSQL in next time + Execute(key, userId, dbPath, version); + // 2. notify + RdbSubscriberManager::GetInstance().EmitByKey(key, userId, dbPath, version); + }); + if (taskId == ExecutorPool::INVALID_TASK_ID) { + ZLOGE("create timer failed, over the max capacity"); + return; + } + ZLOGI("create new task success, uri is %{public}s, subscriberId is %{public}" PRId64 ", bundleName is %{public}s", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + timerCache_.emplace(key, taskId); +} + +void SchedulerManager::ExecuteSchedulerSQL(const std::string &rdbDir, const int32_t userId, int version, const Key &key, + std::shared_ptr delegate) +{ + Template tpl; + if (!TemplateManager::GetInstance().Get(key, userId, tpl)) { + ZLOGE("template undefined, %{public}s, %{public}" PRId64 ", %{public}s", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + return; + } + if (tpl.scheduler_.empty()) { + ZLOGW("template scheduler_ empty, %{public}s, %{public}" PRId64 ", %{public}s", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + return; + } + GenRemindTimerFuncParams(rdbDir, userId, version, key, tpl.scheduler_); + auto resultSet = delegate->QuerySql(tpl.scheduler_); + if (resultSet == nullptr) { + ZLOGE("resultSet is nullptr, %{public}s, %{public}" PRId64 ", %{public}s", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + return; + } + int count; + int errCode = resultSet->GetRowCount(count); + if (errCode != E_OK || count == 0) { + ZLOGE("GetRowCount error, %{public}s, %{public}" PRId64 ", %{public}s, errorCode is %{public}d, count is " + "%{public}d", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str(), errCode, + count); + return; + } + errCode = resultSet->GoToFirstRow(); + if (errCode != E_OK) { + ZLOGE("GoToFirstRow error, %{public}s, %{public}" PRId64 ", %{public}s, errCode is %{public}d", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str(), errCode); + } +} + +void SchedulerManager::GenRemindTimerFuncParams( + const std::string &rdbDir, const int32_t userId, int version, const Key &key, std::string &schedulerSQL) +{ + auto index = schedulerSQL.find(REMIND_TIMER_FUNC); + if (index == std::string::npos) { + ZLOGW("not find remindTimer, sql is %{public}s", schedulerSQL.c_str()); + return; + } + index += REMIND_TIMER_FUNC_LEN; + std::string keyStr = "'" + rdbDir + "', " + std::to_string(version) + ", '" + key.uri + "', " + + std::to_string(key.subscriberId) + ", '" + key.bundleName + "', " + std::to_string(userId) + + ", "; + schedulerSQL.insert(index, keyStr); + return; +} + +void SchedulerManager::RemoveTimer(const Key &key) +{ + std::lock_guard lock(mutex_); + if (executor_ == nullptr) { + ZLOGE("executor_ is nullptr"); + return; + } + auto it = timerCache_.find(key); + if (it != timerCache_.end()) { + ZLOGD("RemoveTimer %{public}s %{public}s %{public}" PRId64, + DistributedData::Anonymous::Change(key.uri).c_str(), key.bundleName.c_str(), key.subscriberId); + executor_->Remove(it->second); + timerCache_.erase(key); + } +} + +void SchedulerManager::ClearTimer() +{ + ZLOGI("Clear all timer"); + std::lock_guard lock(mutex_); + if (executor_ == nullptr) { + ZLOGE("executor_ is nullptr"); + return; + } + auto it = timerCache_.begin(); + while (it != timerCache_.end()) { + executor_->Remove(it->second); + it = timerCache_.erase(it); + } +} + +void SchedulerManager::SetExecutorPool(std::shared_ptr executor) +{ + executor_ = executor; +} + +void SchedulerManager::ReExecuteAll() +{ + std::lock_guard lock(mutex_); + for (auto &item : timerCache_) { + // restart in 200ms + executor_->Reset(item.second, std::chrono::milliseconds(200)); + } +} +} // namespace OHOS::DataShare + diff --git a/services/distributeddataservice/service/data_share/common/scheduler_manager.h b/services/distributeddataservice/service/data_share/common/scheduler_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..939da9705989f30cfd9809dfb591df250b121249 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/scheduler_manager.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCHEDULER_MANAGER_H +#define SCHEDULER_MANAGER_H + +#include + +#include "db_delegate.h" +#include "executor_pool.h" +#include "subscriber_managers/rdb_subscriber_manager.h" + +namespace OHOS::DataShare { +class SchedulerManager { +public: + static SchedulerManager &GetInstance(); + void Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version); + void Execute(const Key &key, const int32_t userId, const std::string &rdbDir, int version); + void ReExecuteAll(); + void SetTimer(const std::string &dbPath, const int32_t userId, int version, const Key &key, int64_t reminderTime); + void RemoveTimer(const Key &key); + void ClearTimer(); + void SetExecutorPool(std::shared_ptr executor); + +private: + static constexpr const char *REMIND_TIMER_FUNC = "remindTimer("; + static constexpr int REMIND_TIMER_FUNC_LEN = 12; + SchedulerManager() = default; + ~SchedulerManager() = default; + static void GenRemindTimerFuncParams(const std::string &rdbDir, const int32_t userId, int version, const Key &key, + std::string &schedulerSQL); + void ExecuteSchedulerSQL(const std::string &rdbDir, const int32_t userId, int version, const Key &key, + std::shared_ptr delegate); + + std::mutex mutex_; + std::map timerCache_; + std::shared_ptr executor_ = nullptr; +}; +} // namespace OHOS::DataShare +#endif // SCHEDULER_MANAGER_H diff --git a/services/distributeddataservice/service/data_share/common/seq_strategy.cpp b/services/distributeddataservice/service/data_share/common/seq_strategy.cpp index 62700398eba0db2c1cde8705202175c3f46d1e2b..08bb71eb536cfa612b5507fd94e1e06b416994e9 100644 --- a/services/distributeddataservice/service/data_share/common/seq_strategy.cpp +++ b/services/distributeddataservice/service/data_share/common/seq_strategy.cpp @@ -28,11 +28,12 @@ bool SeqStrategy::operator()(std::shared_ptr context) } bool SeqStrategy::Init(std::initializer_list strategies) { - for (auto &item: strategies) { + for (const auto &item: strategies) { if (item == nullptr) { - actions_.clear(); return false; } + } + for (const auto &item: strategies) { actions_.emplace_back(item); } return true; diff --git a/services/distributeddataservice/service/data_share/common/uri_utils.cpp b/services/distributeddataservice/service/data_share/common/uri_utils.cpp index 5d6a4ffb134aa9ffa4bcfcd068f927d9047bf4f8..84b3ec7ab8abbe41dcb3ddb2d26387f4b28dcba1 100644 --- a/services/distributeddataservice/service/data_share/common/uri_utils.cpp +++ b/services/distributeddataservice/service/data_share/common/uri_utils.cpp @@ -22,6 +22,9 @@ #include "utils/anonymous.h" namespace OHOS::DataShare { +constexpr const char USER_PARAM[] = "user"; +constexpr const char TOKEN_ID_PARAM[] = "srcToken"; +constexpr const char DST_BUNDLE_NAME_PARAM[] = "dstBundleName"; bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo) { Uri uriTemp(uri); @@ -60,18 +63,41 @@ bool URIUtils::GetBundleNameFromProxyURI(const std::string &uri, std::string &bu return true; } -bool URIUtils::GetUserIdFromProxyURI(const std::string &uri, int32_t &user) +bool URIUtils::GetInfoFromProxyURI( + const std::string &uri, int32_t &user, uint32_t &callerTokenId, std::string &calledBundleName) { - Uri uriTemp(uri); - std::vector splitUri; - SplitStr(uriTemp.GetQuery(), "=", splitUri); - for (auto iter = splitUri.begin(); iter < splitUri.end(); iter++) { - if (*iter == "user" && iter + 1 < splitUri.end()) { - const char *value = (iter + 1)->c_str(); - user = atoi(value); - return true; + auto queryPos = uri.find_last_of('?'); + if (queryPos == std::string::npos) { + return true; + } + std::string query = uri.substr(queryPos + 1); + std::string::size_type pos = 0; + std::string::size_type nextPos; + std::string::size_type valueStartPos; + while (pos != std::string::npos) { + valueStartPos = query.find_first_of('=', pos); + if (valueStartPos == std::string::npos) { + ZLOGE("parse failed %{public}s", query.c_str()); + return false; } + valueStartPos += 1; + nextPos = query.find_first_of('&', pos); + std::string value = (nextPos == std::string::npos ? query.substr(valueStartPos) + : query.substr(valueStartPos, nextPos - valueStartPos)); + if (!value.empty()) { + if (query.compare(pos, sizeof(USER_PARAM) - 1, USER_PARAM) == 0) { + user = std::stoi(value); + } else if (query.compare(pos, sizeof(TOKEN_ID_PARAM) - 1, TOKEN_ID_PARAM) == 0) { + callerTokenId = std::stoul(value); + } else if (query.compare(pos, sizeof(DST_BUNDLE_NAME_PARAM) - 1, DST_BUNDLE_NAME_PARAM) == 0) { + calledBundleName = value; + } + } + if (nextPos == std::string::npos) { + break; + } + pos = nextPos + 1; } - return false; + return true; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/uri_utils.h b/services/distributeddataservice/service/data_share/common/uri_utils.h index 0bf62d160229a79abfaaddf3700ca4b32407eeff..4bfca5c43b3ccf8e97a2ed7fb70cb4b1bfcac90d 100644 --- a/services/distributeddataservice/service/data_share/common/uri_utils.h +++ b/services/distributeddataservice/service/data_share/common/uri_utils.h @@ -29,11 +29,12 @@ class URIUtils { public: static bool GetInfoFromURI(const std::string &uri, UriInfo &uriInfo); static bool GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName); - static bool GetUserIdFromProxyURI(const std::string &uri, int32_t &user); + static bool GetInfoFromProxyURI( + const std::string &uri, int32_t &user, uint32_t &callerTokenId, std::string &calledBundleName); static bool IsDataProxyURI(const std::string &uri); static constexpr const char *DATA_SHARE_SCHEMA = "datashare:///";; static constexpr const char DATA_PROXY_SCHEMA[] = "datashareproxy://"; - static constexpr int DATA_PROXY_SCHEMA_LEN = sizeof(DATA_PROXY_SCHEMA); + static constexpr int DATA_PROXY_SCHEMA_LEN = sizeof(DATA_PROXY_SCHEMA) - 1; private: enum PATH_PARAM : int32_t { diff --git a/services/distributeddataservice/service/data_share/data/published_data.cpp b/services/distributeddataservice/service/data_share/data/published_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..416b27c9e08e7d6ce24b24376540bb017c095c04 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/published_data.cpp @@ -0,0 +1,227 @@ +/* + * 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. + */ +#define LOG_TAG "PublishedData" +#include "published_data.h" + +#include "log_print.h" +#include "subscriber_managers/published_data_subscriber_manager.h" + +namespace OHOS::DataShare { +bool PublishedData::HasVersion() const +{ + return true; +} + +int PublishedData::GetVersion() const +{ + return value.GetVersion(); +} + +std::string PublishedData::GetValue() const +{ + return DistributedData::Serializable::Marshall(value); +} + +PublishedData::PublishedData(const PublishedDataNode &node, const int version) : PublishedData(node) +{ + value.SetVersion(version); +} + +PublishedData::PublishedData(const PublishedDataNode &node) + : KvData(Id(GenId(node.key, node.bundleName, node.subscriberId), node.userId)), value(node) +{ +} + +std::vector PublishedData::Query(const std::string &bundleName, int32_t userId) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return std::vector(); + } + std::vector queryResults; + int32_t status = delegate->GetBatch(KvDBDelegate::DATA_TABLE, + "{\"bundleName\":\"" + bundleName + "\", \"userId\": " + std::to_string(userId) + "}", "{}", queryResults); + if (status != E_OK) { + ZLOGE("db GetBatch failed, %{public}s %{public}d", bundleName.c_str(), status); + return std::vector(); + } + std::vector results; + for (auto &result : queryResults) { + PublishedDataNode data; + if (PublishedDataNode::Unmarshall(result, data)) { + results.emplace_back(data, userId); + } + } + return results; +} + +bool PublishedDataNode::Marshal(DistributedData::Serializable::json &node) const +{ + bool ret = SetValue(node[GET_NAME(key)], key); + ret = ret && SetValue(node[GET_NAME(bundleName)], bundleName); + ret = ret && SetValue(node[GET_NAME(subscriberId)], subscriberId); + ret = ret && SetValue(node[GET_NAME(value)], value); + ret = ret && SetValue(node[GET_NAME(timestamp)], timestamp); + ret = ret && SetValue(node[GET_NAME(userId)], userId); + return ret && VersionData::Marshal(node); +} + +bool PublishedDataNode::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(key), key); + ret = ret && GetValue(node, GET_NAME(bundleName), bundleName); + ret = ret && GetValue(node, GET_NAME(subscriberId), subscriberId); + if (ret) { + GetValue(node, GET_NAME(value), value); + VersionData::Unmarshal(node); + } + ret = ret && GetValue(node, GET_NAME(timestamp), timestamp); + ret = ret && GetValue(node, GET_NAME(userId), userId); + return ret; +} + +PublishedDataNode::PublishedDataNode(const std::string &key, const std::string &bundleName, int64_t subscriberId, + const int32_t userId, const Data &value) + : VersionData(-1), key(key), bundleName(bundleName), subscriberId(subscriberId), value(std::move(value)), + userId(userId) +{ + auto now = time(nullptr); + if (now > 0) { + timestamp = now; + } +} + +PublishedDataNode::PublishedDataNode() : VersionData(-1) {} + +int32_t PublishedData::Query(const std::string &filter, PublishedDataNode::Data &publishedData) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return E_ERROR; + } + std::string queryResult; + int32_t status = delegate->Get(KvDBDelegate::DATA_TABLE, filter, "{}", queryResult); + if (status != E_OK) { + ZLOGE("db Get failed, %{public}s %{public}d", filter.c_str(), status); + return status; + } + PublishedDataNode data; + if (!PublishedDataNode::Unmarshall(queryResult, data)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return E_ERROR; + } + publishedData = std::move(data.value); + return E_OK; +} + +std::string PublishedData::GenId(const std::string &key, const std::string &bundleName, int64_t subscriberId) +{ + return key + "_" + std::to_string(subscriberId) + "_" + bundleName; +} + +void PublishedData::Delete(const std::string &bundleName, const int32_t userId) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return; + } + int32_t status = delegate->Delete(KvDBDelegate::DATA_TABLE, + "{\"bundleName\":\"" + bundleName + "\", \"userId\": " + std::to_string(userId) + "}"); + if (status != E_OK) { + ZLOGE("db Delete failed, %{public}s %{public}d", bundleName.c_str(), status); + } +} + +void PublishedData::ClearAging() +{ + // published data is valid in 240 hours + auto lastValidData = + std::chrono::system_clock::now() - std::chrono::duration_cast(std::chrono::hours(240)); + auto lastValidTime = std::chrono::system_clock::to_time_t(lastValidData); + if (lastValidTime <= 0) { + return; + } + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return; + } + std::vector queryResults; + int32_t status = delegate->GetBatch(KvDBDelegate::DATA_TABLE, "{}", + "{\"id_\": true, \"timestamp\": true, \"key\": true, \"bundleName\": true, \"subscriberId\": true, " + "\"userId\": true}", + queryResults); + if (status != E_OK) { + ZLOGE("db GetBatch failed %{public}d", status); + return; + } + int32_t agingSize = 0; + for (auto &result : queryResults) { + PublishedDataNode data; + if (!PublishedDataNode::Unmarshall(result, data)) { + ZLOGE("Unmarshall %{public}s failed", result.c_str()); + continue; + } + if (data.timestamp < lastValidTime && PublishedDataSubscriberManager::GetInstance() + .GetCount(PublishedDataKey(data.key, data.bundleName, data.subscriberId)) == 0) { + status = delegate->Delete(KvDBDelegate::DATA_TABLE, + Id(PublishedData::GenId(data.key, data.bundleName, data.subscriberId), data.userId)); + if (status != E_OK) { + ZLOGE("db Delete failed, %{public}s %{public}s", data.key.c_str(), data.bundleName.c_str()); + } + agingSize++; + } + } + if (agingSize > 0) { + ZLOGI("aging count %{public}d", agingSize); + } + return; +} + +void PublishedData::UpdateTimestamp( + const std::string &key, const std::string &bundleName, int64_t subscriberId, const int32_t userId) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return; + } + std::string queryResult; + int32_t status = + delegate->Get(KvDBDelegate::DATA_TABLE, Id(GenId(key, bundleName, subscriberId), userId), queryResult); + if (status != E_OK) { + ZLOGE("db Get failed, %{private}s %{public}d", queryResult.c_str(), status); + return; + } + PublishedDataNode data; + if (!PublishedDataNode::Unmarshall(queryResult, data)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return; + } + auto now = time(nullptr); + if (now <= 0) { + ZLOGE("time failed"); + return; + } + data.timestamp = now; + status = delegate->Upsert(KvDBDelegate::DATA_TABLE, PublishedData(data)); + if (status == E_OK) { + ZLOGI("update timestamp %{private}s", data.key.c_str()); + } +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data/published_data.h b/services/distributeddataservice/service/data_share/data/published_data.h new file mode 100644 index 0000000000000000000000000000000000000000..cff038a3bf972267ceb9219043839cf1aacd0e2b --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/published_data.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_PUBLISHED_DATA_H +#define DATASHARESERVICE_PUBLISHED_DATA_H + +#include "db_delegate.h" +#include "serializable/serializable.h" + +namespace OHOS::DataShare { +class PublishedDataNode final : public VersionData { +public: + using Data = std::variant, std::string>; + PublishedDataNode(); + PublishedDataNode(const std::string &key, const std::string &bundleName, int64_t subscriberId, + const int32_t userId, const Data &value); + ~PublishedDataNode() = default; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + std::string key; + std::string bundleName; + int64_t subscriberId; + Data value; + int32_t userId = Id::INVALID_USER; + std::time_t timestamp = 0; +}; + +class PublishedData final : public KvData { +public: + explicit PublishedData(const PublishedDataNode &node); + static std::vector Query(const std::string &bundleName, int32_t userId); + static void Delete(const std::string &bundleName, const int32_t userId); + static void UpdateTimestamp( + const std::string &key, const std::string &bundleName, int64_t subscriberId, const int32_t userId); + static void ClearAging(); + static int32_t Query(const std::string &filter, PublishedDataNode::Data &publishedData); + static std::string GenId(const std::string &key, const std::string &bundleName, int64_t subscriberId); + PublishedData(const PublishedDataNode &node, const int version); + ~PublishedData() = default; + bool HasVersion() const override; + int GetVersion() const override; + std::string GetValue() const override; + friend class GetDataStrategy; + +private: + PublishedDataNode value; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp b/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5bdfa4a721ef829efd413156ce670003c1ff79b6 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ +#define LOG_TAG "ResultSetJsonFormatter" +#include "resultset_json_formatter.h" + +#include "log_print.h" +#include "rdb_errno.h" + +namespace OHOS::DataShare { +bool ResultSetJsonFormatter::Marshal(json &node) const +{ + node = json::array(); + int columnCount = 0; + auto result = resultSet->GetColumnCount(columnCount); + if (result != NativeRdb::E_OK) { + ZLOGE("GetColumnCount err, %{public}d", result); + return false; + } + while (resultSet->GoToNextRow() == NativeRdb::E_OK) { + if (!MarshalRow(node, columnCount)) { + ZLOGE("MarshalRow err"); + return false; + } + } + return true; +} + +bool ResultSetJsonFormatter::Unmarshal(const DistributedData::Serializable::json &node) +{ + return false; +} + +bool ResultSetJsonFormatter::MarshalRow(DistributedData::Serializable::json &node, int columnCount) const +{ + using namespace NativeRdb; + json result; + std::string columnName; + NativeRdb::ColumnType type; + for (int i = 0; i < columnCount; i++) { + if (resultSet->GetColumnType(i, type) != E_OK) { + ZLOGE("GetColumnType err %{public}d", i); + return false; + } + if (resultSet->GetColumnName(i, columnName) != E_OK) { + ZLOGE("GetColumnName err %{public}d", i); + return false; + } + switch (type) { + case ColumnType::TYPE_INTEGER: + int64_t value; + resultSet->GetLong(i, value); + SetValue(result[columnName], value); + break; + case ColumnType::TYPE_FLOAT: + double dValue; + resultSet->GetDouble(i, dValue); + SetValue(result[columnName], dValue); + break; + case ColumnType::TYPE_NULL: + result[columnName] = nullptr; + break; + case ColumnType::TYPE_STRING: { + std::string stringValue; + resultSet->GetString(i, stringValue); + SetValue(result[columnName], stringValue); + break; + } + case ColumnType::TYPE_BLOB: { + std::vector blobValue; + resultSet->GetBlob(i, blobValue); + SetValue(result[columnName], blobValue); + break; + } + default: + ZLOGE("unknow type %{public}d", type); + return false; + } + } + node.push_back(result); + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data/resultset_json_formatter.h b/services/distributeddataservice/service/data_share/data/resultset_json_formatter.h new file mode 100644 index 0000000000000000000000000000000000000000..2903aeeea2a2b9e63d686470f5cb8253a175cbf8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/resultset_json_formatter.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_RESULTSET_JSON_FORMATTER_H +#define DATASHARESERVICE_RESULTSET_JSON_FORMATTER_H + +#include "datashare_template.h" +#include "rdb_utils.h" +#include "serializable/serializable.h" + +namespace OHOS::DataShare { +class ResultSetJsonFormatter final : public DistributedData::Serializable { +public: + explicit ResultSetJsonFormatter(const std::shared_ptr &resultSet) : resultSet(resultSet) {} + ~ResultSetJsonFormatter() {} + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + +private: + bool MarshalRow(json &node, int columnCount) const; + std::shared_ptr resultSet; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_RESULTSET_JSON_FORMATTER_H diff --git a/services/distributeddataservice/service/data_share/data/template_data.cpp b/services/distributeddataservice/service/data_share/data/template_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4236f4d7b370f28199c9e7f443bd267756cced00 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/template_data.cpp @@ -0,0 +1,192 @@ +/* + * 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. + */ +#define LOG_TAG "TemplateData" +#include "template_data.h" +#include "log_print.h" +namespace OHOS::DataShare { +bool TemplateNode::Marshal(DistributedData::Serializable::json &node) const +{ + bool ret = SetValue(node[GET_NAME(predicates)], predicates); + ret = ret && SetValue(node[GET_NAME(scheduler)], scheduler); + return ret; +} + +bool TemplateNode::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(predicates), predicates); + return ret && GetValue(node, GET_NAME(scheduler), scheduler); +} + +TemplateNode::TemplateNode(const Template &tpl) : scheduler(tpl.scheduler_) +{ + for (auto &item:tpl.predicates_) { + predicates.emplace_back(item.key_, item.selectSql_); + } +} + +Template TemplateNode::ToTemplate() const +{ + std::vector nodes; + for (const auto &predicate: predicates) { + nodes.emplace_back(predicate.key, predicate.selectSql); + } + return Template(nodes, scheduler); +} + +bool TemplateRootNode::Marshal(DistributedData::Serializable::json &node) const +{ + bool ret = SetValue(node[GET_NAME(uri)], uri); + ret = ret && SetValue(node[GET_NAME(bundleName)], bundleName); + ret = ret && SetValue(node[GET_NAME(subscriberId)], subscriberId); + ret = ret && SetValue(node[GET_NAME(userId)], userId); + ret = ret && SetValue(node[GET_NAME(templat)], tpl); + return ret; +} + +bool TemplateRootNode::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(uri), uri); + ret = ret && GetValue(node, GET_NAME(bundleName), bundleName); + ret = ret && GetValue(node, GET_NAME(subscriberId), subscriberId); + ret = ret && GetValue(node, GET_NAME(userId), userId); + ret = ret && GetValue(node, GET_NAME(templat), tpl); + return ret; +} + +TemplateRootNode::TemplateRootNode(const std::string &uri, const std::string &bundleName, const int64_t subscriberId, + const int32_t userId, const Template &tpl) + : uri(uri), bundleName(bundleName), subscriberId(subscriberId), userId(userId), tpl(tpl) +{ +} + +bool TemplateData::HasVersion() const +{ + return false; +} + +std::string TemplateData::GetValue() const +{ + return DistributedData::Serializable::Marshall(value); +} + +TemplateData::TemplateData( + const std::string &uri, const std::string &bundleName, int64_t subscriberId, int32_t userId, const Template &tpl) + :KvData(Id(GenId(uri, bundleName, subscriberId), userId)), value(uri, bundleName, subscriberId, userId, tpl) +{ +} + +int TemplateData::GetVersion() const +{ + return 0; +} + +std::string TemplateData::GenId(const std::string &uri, const std::string &bundleName, int64_t subscriberId) +{ + return uri + "_" + std::to_string(subscriberId) + "_" + bundleName; +} + +int32_t TemplateData::Query(const std::string &filter, Template &aTemplate) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return E_ERROR; + } + std::string queryResult; + int32_t status = delegate->Get(KvDBDelegate::TEMPLATE_TABLE, filter, "{}", queryResult); + if (status != E_OK) { + ZLOGE("db Get failed, %{public}s %{public}d", filter.c_str(), status); + return status; + } + TemplateRootNode data; + if (!DistributedData::Serializable::Unmarshall(queryResult, data)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return E_ERROR; + } + aTemplate = data.ToTemplate(); + return E_OK; +} + +bool TemplateData::Delete(const std::string &bundleName, const int32_t userId) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return false; + } + auto status = delegate->Delete(KvDBDelegate::TEMPLATE_TABLE, + "{\"bundleName\":\"" + bundleName + "\", \"userId\": " + std::to_string(userId) + "}"); + if (status != E_OK) { + ZLOGE("db DeleteById failed, %{public}d", status); + return false; + } + return true; +} + +bool TemplateData::Add(const std::string &uri, const int32_t userId, const std::string &bundleName, + const int64_t subscriberId, const Template &aTemplate) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return false; + } + TemplateData data(uri, bundleName, subscriberId, userId, aTemplate); + auto status = delegate->Upsert(KvDBDelegate::TEMPLATE_TABLE, data); + if (status != E_OK) { + ZLOGE("db Upsert failed, %{public}d", status); + return false; + } + return true; +} + +bool TemplateData::Delete( + const std::string &uri, const int32_t userId, const std::string &bundleName, const int64_t subscriberId) +{ + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return false; + } + auto status = delegate->Delete(KvDBDelegate::TEMPLATE_TABLE, + static_cast(Id(TemplateData::GenId(uri, bundleName, subscriberId), userId))); + if (status != E_OK) { + ZLOGE("db DeleteById failed, %{public}d", status); + return false; + } + return true; +} + +Template TemplateRootNode::ToTemplate() const +{ + return tpl.ToTemplate(); +} + +PredicatesNode::PredicatesNode(const std::string &key, const std::string &selectSql) : key(key), selectSql(selectSql) +{ +} +bool PredicatesNode::Marshal(DistributedData::Serializable::json &node) const +{ + bool ret = SetValue(node[GET_NAME(key)], key); + ret = ret && SetValue(node[GET_NAME(selectSql)], selectSql); + return ret; +} +bool PredicatesNode::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(key), key); + ret = ret && GetValue(node, GET_NAME(selectSql), selectSql); + return ret; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data/template_data.h b/services/distributeddataservice/service/data_share/data/template_data.h new file mode 100644 index 0000000000000000000000000000000000000000..06b482b51bc1f573126f8d8e191716fe7e5fe8d3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data/template_data.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_TEMPLATE_DATA_H +#define DATASHARESERVICE_TEMPLATE_DATA_H + +#include "datashare_template.h" +#include "db_delegate.h" +#include "serializable/serializable.h" + +namespace OHOS::DataShare { +struct PredicatesNode final: public DistributedData::Serializable { + PredicatesNode() = default; + PredicatesNode(const std::string &key, const std::string &selectSql); + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + std::string key; + std::string selectSql; +}; +struct TemplateNode final: public DistributedData::Serializable { + TemplateNode() = default; + explicit TemplateNode(const Template &tpl); + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + Template ToTemplate() const; +private: + std::vector predicates; + std::string scheduler; +}; + +struct TemplateRootNode final: public DistributedData::Serializable { + TemplateRootNode() = default; + TemplateRootNode(const std::string &uri, const std::string &bundleName, const int64_t subscriberId, + const int32_t userId, const Template &tpl); + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + Template ToTemplate() const; +private: + std::string uri; + std::string bundleName; + int64_t subscriberId; + int32_t userId; + TemplateNode tpl; +}; + +struct TemplateData final : public KvData { + TemplateData(const std::string &uri, const std::string &bundleName, int64_t subscriberId, int32_t userId, + const Template &tpl); + static int32_t Query(const std::string &filter, Template &aTemplate); + static std::string GenId(const std::string &uri, const std::string &bundleName, int64_t subscriberId); + static bool Delete(const std::string &bundleName, const int32_t userId); + static bool Add(const std::string &uri, const int32_t userId, const std::string &bundleName, + const int64_t subscriberId, const Template &aTemplate); + static bool Delete( + const std::string &uri, const int32_t userId, const std::string &bundleName, const int64_t subscriberId); + bool HasVersion() const override; + int GetVersion() const override; + std::string GetValue() const override; + +private: + TemplateRootNode value; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 833de07f0c05d65f67c74a6c8066a784bf4d7232..cb1e2cd40a15b92d1da2cf07a7f91d92010961f4 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -19,21 +19,20 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" -#include "bootstrap.h" +#include "app_connect_manager.h" +#include "common_event_manager.h" +#include "common_event_support.h" #include "dataobs_mgr_client.h" #include "datashare_errno.h" #include "datashare_template.h" -#include "delete_strategy.h" -#include "directory_manager.h" -#include "get_data_strategy.h" +#include "directory/directory_manager.h" #include "hap_token_info.h" -#include "insert_strategy.h" #include "ipc_skeleton.h" #include "log_print.h" -#include "publish_strategy.h" -#include "query_strategy.h" -#include "subscribe_strategy.h" -#include "update_strategy.h" +#include "matching_skills.h" +#include "scheduler_manager.h" +#include "subscriber_managers/published_data_subscriber_manager.h" +#include "template_data.h" #include "utils/anonymous.h" namespace OHOS::DataShare { @@ -52,10 +51,10 @@ int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValu { ZLOGD("Insert enter."); auto context = std::make_shared(uri); - auto ret = InsertStrategy::Execute(context, valuesBucket); + auto ret = insertStrategy_.Execute(context, valuesBucket); if (ret) { NotifyChange(uri); - return ret; + RdbSubscriberManager::GetInstance().Emit(uri, context); } return ret; } @@ -81,10 +80,10 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred { ZLOGD("Update enter."); auto context = std::make_shared(uri); - auto ret = UpdateStrategy::Execute(context, predicate, valuesBucket); + auto ret = updateStrategy_.Execute(context, predicate, valuesBucket); if (ret) { NotifyChange(uri); - return ret; + RdbSubscriberManager::GetInstance().Emit(uri, context); } return ret; } @@ -93,10 +92,10 @@ int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePred { ZLOGD("Delete enter."); auto context = std::make_shared(uri); - auto ret = DeleteStrategy::Execute(context, predicate); + auto ret = deleteStrategy_.Execute(context, predicate); if (ret) { NotifyChange(uri); - return ret; + RdbSubscriberManager::GetInstance().Emit(uri, context); } return ret; } @@ -106,35 +105,50 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin { ZLOGD("Query enter."); auto context = std::make_shared(uri); - return QueryStrategy::Execute(context, predicates, columns, errCode); + return queryStrategy_.Execute(context, predicates, columns, errCode); } int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) { + auto context = std::make_shared(uri); TemplateId tpltId; tpltId.subscriberId_ = subscriberId; if (!GetCallerBundleName(tpltId.bundleName_)) { ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } - return ERROR; + return templateStrategy_.Execute(context, [&uri, &tpltId, &tplt, &context]() -> int32_t { + auto result = TemplateManager::GetInstance().Add( + Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId, tplt); + RdbSubscriberManager::GetInstance().Emit(context->uri, context); + return result; + }); } int32_t DataShareServiceImpl::DelTemplate(const std::string &uri, const int64_t subscriberId) { + auto context = std::make_shared(uri); TemplateId tpltId; tpltId.subscriberId_ = subscriberId; if (!GetCallerBundleName(tpltId.bundleName_)) { ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } - return ERROR; + + return templateStrategy_.Execute(context, [&uri, &tpltId, &context]() -> int32_t { + return TemplateManager::GetInstance().Delete( + Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId); + }); } bool DataShareServiceImpl::GetCallerBundleName(std::string &bundleName) { auto tokenId = IPCSkeleton::GetCallingTokenID(); - if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) != Security::AccessToken::TOKEN_HAP) { + auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); + if (type == Security::AccessToken::TOKEN_NATIVE) { + return true; + } + if (type != Security::AccessToken::TOKEN_HAP) { return false; } Security::AccessToken::HapTokenInfo tokenInfo; @@ -149,18 +163,61 @@ bool DataShareServiceImpl::GetCallerBundleName(std::string &bundleName) std::vector DataShareServiceImpl::Publish(const Data &data, const std::string &bundleNameOfProvider) { - return std::vector(); + std::vector results; + std::vector publishedData; + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return results; + } + int32_t userId = -1; + PublishedData::ClearAging(); + for (const auto &item : data.datas_) { + auto context = std::make_shared(item.key_); + context->version = data.version_; + context->callerBundleName = callerBundleName; + context->calledBundleName = bundleNameOfProvider; + int32_t result = publishStrategy_.Execute(context, item); + results.emplace_back(item.key_, result); + if (result != EOK) { + ZLOGE("publish error, key is %{public}s", DistributedData::Anonymous::Change(item.key_).c_str()); + continue; + } + publishedData.emplace_back(context->uri, context->calledBundleName, item.subscriberId_); + userId = context->currentUserId; + } + if (!publishedData.empty()) { + PublishedDataSubscriberManager::GetInstance().Emit(publishedData, userId, callerBundleName); + PublishedDataSubscriberManager::GetInstance().SetObserversNotifiedOnEnabled(publishedData); + } + return results; } -Data DataShareServiceImpl::GetData(const std::string &bundleNameOfProvider) +Data DataShareServiceImpl::GetData(const std::string &bundleNameOfProvider, int &errorCode) { - return Data(); + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return Data(); + } + auto context = std::make_shared(); + context->callerBundleName = callerBundleName; + context->calledBundleName = bundleNameOfProvider; + return getDataStrategy_.Execute(context, errorCode); } std::vector DataShareServiceImpl::SubscribeRdbData( const std::vector &uris, const TemplateId &id, const sptr observer) { - return std::vector(); + std::vector results; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &observer, &context, this]() { + return RdbSubscriberManager::GetInstance().Add( + Key(context->uri, id.subscriberId_, id.bundleName_), observer, context, binderInfo_.executors); + })); + } + return results; } std::vector DataShareServiceImpl::UnsubscribeRdbData( @@ -169,8 +226,9 @@ std::vector DataShareServiceImpl::UnsubscribeRdbData( std::vector results; for (const auto &uri : uris) { auto context = std::make_shared(uri); - results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { - return true; + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() { + return RdbSubscriberManager::GetInstance().Delete( + Key(context->uri, id.subscriberId_, id.bundleName_), context->callerTokenId); })); } return results; @@ -182,8 +240,9 @@ std::vector DataShareServiceImpl::EnableRdbSubs( std::vector results; for (const auto &uri : uris) { auto context = std::make_shared(uri); - results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { - return true; + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() { + return RdbSubscriberManager::GetInstance().Enable( + Key(context->uri, id.subscriberId_, id.bundleName_), context); })); } return results; @@ -195,8 +254,9 @@ std::vector DataShareServiceImpl::DisableRdbSubs( std::vector results; for (const auto &uri : uris) { auto context = std::make_shared(uri); - results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { - return true; + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() { + return RdbSubscriberManager::GetInstance().Disable( + Key(context->uri, id.subscriberId_, id.bundleName_), context->callerTokenId); })); } return results; @@ -205,25 +265,143 @@ std::vector DataShareServiceImpl::DisableRdbSubs( std::vector DataShareServiceImpl::SubscribePublishedData(const std::vector &uris, const int64_t subscriberId, const sptr observer) { - return std::vector(); + std::vector results; + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return results; + } + std::vector publishedKeys; + int32_t result; + int32_t userId; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + PublishedDataKey key(uri, callerBundleName, subscriberId); + context->callerBundleName = callerBundleName; + context->calledBundleName = key.bundleName; + result = subscribeStrategy_.Execute(context, [&subscriberId, &observer, &context]() { + return PublishedDataSubscriberManager::GetInstance().Add( + PublishedDataKey(context->uri, context->callerBundleName, subscriberId), observer, + context->callerTokenId); + }); + results.emplace_back(uri, result); + if (result == E_OK) { + publishedKeys.emplace_back(context->uri, context->callerBundleName, subscriberId); + if (binderInfo_.executors != nullptr) { + binderInfo_.executors->Execute([context, subscriberId]() { + PublishedData::UpdateTimestamp( + context->uri, context->calledBundleName, subscriberId, context->currentUserId); + }); + } + userId = context->currentUserId; + } + } + if (!publishedKeys.empty()) { + PublishedDataSubscriberManager::GetInstance().Emit(publishedKeys, userId, callerBundleName, observer); + } + return results; } std::vector DataShareServiceImpl::UnsubscribePublishedData(const std::vector &uris, const int64_t subscriberId) { - return std::vector(); + std::vector results; + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return results; + } + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + PublishedDataKey key(uri, callerBundleName, subscriberId); + context->callerBundleName = callerBundleName; + context->calledBundleName = key.bundleName; + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&subscriberId, &context, this]() { + auto result = PublishedDataSubscriberManager::GetInstance().Delete( + PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId); + if (result == E_OK && binderInfo_.executors != nullptr) { + binderInfo_.executors->Execute([context, subscriberId]() { + PublishedData::UpdateTimestamp( + context->uri, context->calledBundleName, subscriberId, context->currentUserId); + }); + } + return result; + })); + } + return results; } std::vector DataShareServiceImpl::EnablePubSubs(const std::vector &uris, const int64_t subscriberId) { - return std::vector(); + std::vector results; + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return results; + } + std::vector publishedKeys; + int32_t result; + int32_t userId = -1; + uint32_t callerTokenId = 0; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + PublishedDataKey key(uri, callerBundleName, subscriberId); + context->callerBundleName = callerBundleName; + context->calledBundleName = key.bundleName; + result = subscribeStrategy_.Execute(context, [&subscriberId, &context]() { + return PublishedDataSubscriberManager::GetInstance().Enable( + PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId); + }); + callerTokenId = context->callerTokenId; + if (result == E_OK && binderInfo_.executors != nullptr) { + binderInfo_.executors->Execute([context, subscriberId]() { + PublishedData::UpdateTimestamp( + context->uri, context->calledBundleName, subscriberId, context->currentUserId); + }); + } + results.emplace_back(uri, result); + if (result == E_OK) { + PublishedDataKey pKey(context->uri, context->callerBundleName, subscriberId); + if (PublishedDataSubscriberManager::GetInstance().IsNotifyOnEnabled(pKey, context->callerTokenId)) { + publishedKeys.emplace_back(pKey); + } + userId = context->currentUserId; + } + } + if (!publishedKeys.empty()) { + PublishedDataSubscriberManager::GetInstance().Emit(publishedKeys, userId, callerBundleName); + } + return results; } std::vector DataShareServiceImpl::DisablePubSubs(const std::vector &uris, const int64_t subscriberId) { - return std::vector(); + std::vector results; + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return results; + } + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + PublishedDataKey key(uri, callerBundleName, subscriberId); + context->callerBundleName = callerBundleName; + context->calledBundleName = key.bundleName; + results.emplace_back(uri, subscribeStrategy_.Execute(context, [&subscriberId, &context, this]() { + auto result = PublishedDataSubscriberManager::GetInstance().Disable( + PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId); + if (result == E_OK && binderInfo_.executors != nullptr) { + binderInfo_.executors->Execute([context, subscriberId]() { + PublishedData::UpdateTimestamp( + context->uri, context->calledBundleName, subscriberId, context->currentUserId); + }); + } + return result; + })); + } + return results; } enum DataShareKvStoreType : int32_t { @@ -231,52 +409,114 @@ enum DataShareKvStoreType : int32_t { DISTRIBUTED_TYPE_BUTT }; -int32_t DataShareServiceImpl::OnInitialize() +int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo) { - auto token = IPCSkeleton::GetCallingTokenID(); + binderInfo_ = binderInfo; const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); - const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token); + const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(binderInfo.selfTokenId); DistributedData::StoreMetaData saveMeta; saveMeta.appType = "default"; saveMeta.storeId = "data_share_data_"; saveMeta.isAutoSync = false; saveMeta.isBackup = false; saveMeta.isEncrypt = false; - saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); - saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.bundleName = binderInfo.selfName; + saveMeta.appId = binderInfo.selfName; saveMeta.user = std::to_string(userId); saveMeta.account = accountId; - saveMeta.tokenId = token; + saveMeta.tokenId = binderInfo.selfTokenId; saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; saveMeta.area = 1; saveMeta.uid = IPCSkeleton::GetCallingUid(); saveMeta.storeType = DATA_SHARE_SINGLE_VERSION; saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); - KvDBDelegate::GetInstance(false, saveMeta.dataDir); + KvDBDelegate::GetInstance(false, saveMeta.dataDir, binderInfo.executors); + SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors); + SubscribeTimeChanged(); return EOK; } int32_t DataShareServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) { - auto token = IPCSkeleton::GetCallingTokenID(); - const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); - DistributedData::StoreMetaData saveMeta; - saveMeta.appType = "default"; - saveMeta.storeId = "data_share_data_"; - saveMeta.isAutoSync = false; - saveMeta.isBackup = false; - saveMeta.isEncrypt = false; - saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); - saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); - saveMeta.user = user; - saveMeta.account = account; - saveMeta.tokenId = token; - saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; - saveMeta.area = 1; - saveMeta.uid = IPCSkeleton::GetCallingUid(); - saveMeta.storeType = DATA_SHARE_SINGLE_VERSION; - saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); - KvDBDelegate::GetInstance(true, saveMeta.dataDir); + RdbSubscriberManager::GetInstance().Clear(); + PublishedDataSubscriberManager::GetInstance().Clear(); + SchedulerManager::GetInstance().ClearTimer(); + return EOK; +} + +void DataShareServiceImpl::OnConnectDone() +{ + std::string callerBundleName; + if (!GetCallerBundleName(callerBundleName)) { + ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str()); + return; + } + AppConnectManager::Notify(callerBundleName); +} + +int32_t DataShareServiceImpl::OnAppUninstall( + const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) +{ + ZLOGI("%{public}s uninstalled", bundleName.c_str()); + PublishedData::Delete(bundleName, user); + PublishedData::ClearAging(); + TemplateData::Delete(bundleName, user); + RdbHelper::ClearCache(); return EOK; } + +int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) +{ + ZLOGI("AppExit uid=%{public}d, pid=%{public}d, tokenId=0x%{public}x, bundleName=%{public}s", + uid, pid, tokenId, bundleName.c_str()); + RdbSubscriberManager::GetInstance().Delete(tokenId); + PublishedDataSubscriberManager::GetInstance().Delete(tokenId); + return EOK; +} + +void DataShareServiceImpl::NotifyObserver(const std::string &uri) +{ + ZLOGD("%{private}s try notified", uri.c_str()); + auto context = std::make_shared(uri); + if (!GetCallerBundleName(context->callerBundleName)) { + ZLOGE("get bundleName error, %{private}s", uri.c_str()); + return; + } + auto ret = rdbNotifyStrategy_.Execute(context); + if (ret) { + ZLOGI("%{private}s start notified", uri.c_str()); + RdbSubscriberManager::GetInstance().Emit(uri, context); + } +} +bool DataShareServiceImpl::SubscribeTimeChanged() +{ + ZLOGD("start"); + EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED); + EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); + subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); + timerReceiver_ = std::make_shared(subscribeInfo); + auto result = EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_); + if (!result) { + ZLOGE("SubscribeCommonEvent err"); + } + return result; +} + +void DataShareServiceImpl::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData) +{ + AAFwk::Want want = eventData.GetWant(); + std::string action = want.GetAction(); + ZLOGI("action:%{public}s.", action.c_str()); + if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED + || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) { + SchedulerManager::GetInstance().ReExecuteAll(); + } +} + +DataShareServiceImpl::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo) + : CommonEventSubscriber(subscriberInfo) +{ +} } // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.h b/services/distributeddataservice/service/data_share/data_share_service_impl.h index 6cf140308f8a71f59f64feb9e1a3855bd0b00510..46d7ca1fa91266eee3b367f3cc537e760a0e7daa 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -18,9 +18,21 @@ #include +#include "common_event_subscribe_info.h" +#include "common_event_subscriber.h" +#include "data_proxy_observer.h" #include "data_share_service_stub.h" #include "datashare_template.h" -#include "data_proxy_observer.h" +#include "db_delegate.h" +#include "delete_strategy.h" +#include "get_data_strategy.h" +#include "insert_strategy.h" +#include "publish_strategy.h" +#include "query_strategy.h" +#include "rdb_notify_strategy.h" +#include "subscribe_strategy.h" +#include "template_strategy.h" +#include "update_strategy.h" #include "uri_utils.h" #include "visibility.h" @@ -37,7 +49,7 @@ public: int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) override; int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) override; std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) override; - Data GetData(const std::string &bundleNameOfProvider) override; + Data GetData(const std::string &bundleNameOfProvider, int &errorCode) override; std::vector SubscribeRdbData(const std::vector &uris, const TemplateId &id, const sptr observer) override; std::vector UnsubscribeRdbData( @@ -54,8 +66,12 @@ public: const int64_t subscriberId) override; std::vector DisablePubSubs(const std::vector &uris, const int64_t subscriberId) override; - int32_t OnInitialize() override; + void OnConnectDone() override; + int32_t OnBind(const BindInfo &binderInfo) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; + int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) override; + void NotifyObserver(const std::string &uri) override; private: class Factory { @@ -63,16 +79,29 @@ private: Factory(); ~Factory(); }; - - enum class PermissionType { - READ_PERMISSION = 1, - WRITE_PERMISSION + class TimerReceiver : public EventFwk::CommonEventSubscriber { + public: + TimerReceiver() = default; + TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo); + virtual ~TimerReceiver() = default; + virtual void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; }; - + bool SubscribeTimeChanged(); bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); static Factory factory_; static constexpr int32_t ERROR = -1; + PublishStrategy publishStrategy_; + GetDataStrategy getDataStrategy_; + SubscribeStrategy subscribeStrategy_; + DeleteStrategy deleteStrategy_; + InsertStrategy insertStrategy_; + QueryStrategy queryStrategy_; + UpdateStrategy updateStrategy_; + TemplateStrategy templateStrategy_; + RdbNotifyStrategy rdbNotifyStrategy_; + BindInfo binderInfo_; + std::shared_ptr timerReceiver_ = nullptr; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index 023f4e757bc56ad598e4cdfdd6b667aef937ec8f..99383d0849b352dc1b020af6346195ab883ea0c7 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -163,9 +163,10 @@ int32_t DataShareServiceStub::OnRemoteGetData(MessageParcel &data, MessageParcel ZLOGW("read device list failed."); return -1; } - ZLOGE("hanlu bundleName %{public}s", bundleName.c_str()); - auto results = GetData(bundleName); - if (!ITypesUtil::Marshal(reply, results.datas_)) { + ZLOGI("bundleName is %{public}s", bundleName.c_str()); + int errorCode = E_OK; + auto results = GetData(bundleName, errorCode); + if (!ITypesUtil::Marshal(reply, results.datas_, errorCode)) { ZLOGE("ITypesUtil::Marshal(reply, results) failed"); return -1; } @@ -311,16 +312,33 @@ int32_t DataShareServiceStub::OnRemoteDisablePubSubs(MessageParcel &data, Messag return 0; } +int32_t DataShareServiceStub::OnRemoteNotifyConnectDone(MessageParcel &data, MessageParcel &reply) +{ + OnConnectDone(); + return 0; +} + int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) { ZLOGD("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); if (!CheckInterfaceToken(data)) { return DATA_SHARE_ERROR; } - if (code >= 0 && code < DATA_SHARE_SERVICE_CMD_MAX) { + if (code < DATA_SHARE_SERVICE_CMD_MAX) { return (this->*HANDLERS[code])(data, reply); } return -1; } + +int32_t DataShareServiceStub::OnRemoteNotifyObserver(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + if (!ITypesUtil::Unmarshal(data, uri)) { + ZLOGE("read device list failed."); + return -1; + } + NotifyObserver(uri); + return 0; +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.h b/services/distributeddataservice/service/data_share/data_share_service_stub.h index b786529f4b2d05dd9a204d64e33d0c2abd3c742e..17ac116ac1b3b4fdd04473f0a894251491bb7281 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -43,6 +43,8 @@ private: int32_t OnRemoteUnsubscribePublishedData(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteEnablePubSubs(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteDisablePubSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteNotifyConnectDone(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteNotifyObserver(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (DataShareServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[DATA_SHARE_SERVICE_CMD_MAX] = { &DataShareServiceStub::OnRemoteInsert, @@ -60,7 +62,9 @@ private: &DataShareServiceStub::OnRemoteSubscribePublishedData, &DataShareServiceStub::OnRemoteUnsubscribePublishedData, &DataShareServiceStub::OnRemoteEnablePubSubs, - &DataShareServiceStub::OnRemoteDisablePubSubs }; + &DataShareServiceStub::OnRemoteDisablePubSubs, + &DataShareServiceStub::OnRemoteNotifyConnectDone, + &DataShareServiceStub::OnRemoteNotifyObserver }; }; } // namespace DataShare } // namespace OHOS diff --git a/services/distributeddataservice/service/data_share/data_share_types_util.h b/services/distributeddataservice/service/data_share/data_share_types_util.h index 4f4ebf9b597fe64e4319f05a60aab124080e35a3..b1e0a47645dbed0f400c89226bbec5b54779e6c6 100644 --- a/services/distributeddataservice/service/data_share/data_share_types_util.h +++ b/services/distributeddataservice/service/data_share/data_share_types_util.h @@ -42,7 +42,7 @@ template<> bool Unmarshalling(PublishedDataItem &dataItem, MessageParcel &parcel); template<> -bool Marshalling(const PublishedDataItem &templateId, MessageParcel &parcel); +bool Marshalling(const PublishedDataItem &dataItem, MessageParcel &parcel); template<> bool Unmarshalling(Data &data, MessageParcel &parcel); @@ -63,7 +63,7 @@ template<> bool Marshalling(const OperationResult &operationResult, MessageParcel &parcel); template<> -bool Marshalling(const TemplateId &changeNode, MessageParcel &parcel); +bool Marshalling(const TemplateId &templateId, MessageParcel &parcel); }; #endif // DATASHARESERVICE_DATA_SHARE_TYPES_UTIL_H diff --git a/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni b/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni new file mode 100644 index 0000000000000000000000000000000000000000..5ac6d6289812f2812a4b223fd0b3fe236965ab11 --- /dev/null +++ b/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni @@ -0,0 +1,23 @@ +# 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. + +declare_args() { + gaussrd_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd" + if (defined(global_parts_info) && + defined(global_parts_info.distributeddatamgr_kv_store_lite)) { + gaussrd_path = "//foundation/distributeddatamgr/kv_store_lite/gaussdb_rd" + gaussrd_enchance = true + } else { + gaussrd_enchance = false + } +} diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h index 3ace41987600724d0deb5e1a0dd9d3e5a1643525..df29eceee066358342217af89d3b82b1f21096a9 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h @@ -31,7 +31,7 @@ public: static bool CheckCollectionName(const std::string &collectionName, std::string &formattedName, int &errCode); static int CheckFilter(JsonObject &document, std::vector> &filterPath, bool &isIdExist); static int CheckIdFormat(JsonObject &data, bool &isIdExisit); - static int CheckDocument(JsonObject &document, bool &isIdExist); + static int CheckDocument(JsonObject &documentObj, bool &isIdExist); static int CheckUpdata(JsonObject &updataObj); static int CheckProjection(JsonObject &projectionObj, std::vector> &path); }; diff --git a/services/distributeddataservice/service/data_share/idata_share_service.h b/services/distributeddataservice/service/data_share/idata_share_service.h index 6d465247baef0b92489fce5ef7baf2f5554ac850..ce2ff44b7c94ad6dd69d2754d078d1fe0b69075e 100644 --- a/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/services/distributeddataservice/service/data_share/idata_share_service.h @@ -45,6 +45,8 @@ public: DATA_SHARE_SERVICE_CMD_UNSUBSCRIBE_PUBLISHED, DATA_SHARE_SERVICE_CMD_ENABLE_SUBSCRIBE_PUBLISHED, DATA_SHARE_SERVICE_CMD_DISABLE_SUBSCRIBE_PUBLISHED, + DATA_SHARE_SERVICE_CMD_NOTIFY, + DATA_SHARE_SERVICE_CMD_NOTIFY_OBSERVERS, DATA_SHARE_SERVICE_CMD_MAX }; @@ -60,7 +62,7 @@ public: virtual int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) = 0; virtual int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) = 0; virtual std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) = 0; - virtual Data GetData(const std::string &bundleNameOfProvider) = 0; + virtual Data GetData(const std::string &bundleNameOfProvider, int &errorCode) = 0; virtual std::vector SubscribeRdbData( const std::vector &uris, const TemplateId &id, const sptr observer) = 0; virtual std::vector UnsubscribeRdbData( @@ -77,6 +79,8 @@ public: const int64_t subscriberId) = 0; virtual std::vector DisablePubSubs(const std::vector &uris, const int64_t subscriberId) = 0; + virtual void OnConnectDone() = 0; + virtual void NotifyObserver(const std::string &uri) = 0; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp index d2ad30b5cbfc5b0055c5f107008890ef310f5289..f8595c73b2c78f3e6a193193e439f71d365086ff 100644 --- a/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp @@ -31,8 +31,13 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( context->calledBundleName, context->currentUserId, context->bundleInfo)) { ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str()); + context->errCode = E_BUNDLE_NAME_NOT_EXIST; return false; } + if (context->uri.empty()) { + context->permission = "reject"; + return true; + } for (auto &hapModuleInfo : context->bundleInfo.hapModuleInfos) { auto proxyDatas = hapModuleInfo.proxyDatas; for (auto &proxyData : proxyDatas) { @@ -59,6 +64,11 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co ZLOGI("access private data, caller and called is same, go"); return true; } + // cross permission can only cross uri like weather,can not cross like datashareproxy://weather + if (context->isAllowCrossPer && !URIUtils::IsDataProxyURI(context->uri)) { + ZLOGI("access has white permission, go"); + return true; + } context->errCode = E_URI_NOT_EXIST; ZLOGI("not find DataProperties! %{private}s is private", context->uri.c_str()); return false; diff --git a/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp index 5df4f1bbce2295c8e10c75c592063c1299c262b5..9ff57d27f4db0a4da83551084f1ceb5569def94b 100644 --- a/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp @@ -53,7 +53,7 @@ bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromProfile( "/" + context->calledStoreName; std::string tableUri = storeUri + "/" + context->calledTableName; ConfigData result; - for (auto &item : profileInfo.tableConfig) { + for (auto const &item : profileInfo.tableConfig) { if (item.uri == tableUri) { result.SetCrossUserMode(ConfigData::TABLE_MATCH_PRIORITY, item.crossUserMode); continue; diff --git a/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp index 1fc64494edc4d44944d26e69dfc0d3b3ec640bce..8d0ce62424e9b6b7b06042906f6be7d3d2741493 100644 --- a/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp @@ -28,12 +28,12 @@ namespace OHOS::DataShare { int64_t DeleteStrategy::Execute(std::shared_ptr context, const DataSharePredicates &predicate) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return -1; } - if (!(*preProcess)(context)) { + if (!preProcess(context)) { ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } @@ -44,13 +44,12 @@ int64_t DeleteStrategy::Execute(std::shared_ptr context, const DataShar } return delegate->Delete(context->calledTableName, predicate); } -Strategy *DeleteStrategy::GetStrategy() + +SeqStrategy &DeleteStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow)LoadConfigCommonStrategy(), @@ -59,13 +58,13 @@ Strategy *DeleteStrategy::GetStrategy() new (std::nothrow)LoadConfigDataInfoStrategy(), new (std::nothrow)ProcessSingleAppUserCrossStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/delete_strategy.h b/services/distributeddataservice/service/data_share/strategies/delete_strategy.h index 08e98e3f6a928ffefb2a4f79e0d8900a30418b57..ce9b4539bf4a2af0925ba29058801f8ed5c78305 100644 --- a/services/distributeddataservice/service/data_share/strategies/delete_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/delete_strategy.h @@ -24,10 +24,12 @@ namespace OHOS::DataShare { class DeleteStrategy final { public: - static int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate); + int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..377bec6f2f308681b9100450136abdc8c10ebce2 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.cpp @@ -0,0 +1,38 @@ +/* + * 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. + */ +#define LOG_TAG "CrossPermissionStrategy" + +#include "cross_permission_strategy.h" + +#include "accesstoken_kit.h" +#include "log_print.h" + +namespace OHOS::DataShare { +bool CrossPermissionStrategy::operator()(std::shared_ptr context) +{ + for (const auto &permission : allowCrossPermissions_) { + int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(context->callerTokenId, permission); + if (status == Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + context->isAllowCrossPer = true; + return true; + } + } + return true; +} +CrossPermissionStrategy::CrossPermissionStrategy(std::initializer_list permissions) +{ + allowCrossPermissions_.insert(allowCrossPermissions_.end(), permissions.begin(), permissions.end()); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.h similarity index 61% rename from services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h rename to services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.h index 57d76c48e5d5f8bb6414887a3bbdd2de7259cfed..53ab7da88ab451c677beec95e9f40b2cd8acd925 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/general/cross_permission_strategy.h @@ -13,21 +13,17 @@ * limitations under the License. */ -#ifndef DATASHARESERVICE_CONNECT_EXTENSION_STRAGETY_H -#define DATASHARESERVICE_CONNECT_EXTENSION_STRAGETY_H +#ifndef DATASHARESERVICE_WHITE_PERMISSION_STRAGETY_H +#define DATASHARESERVICE_WHITE_PERMISSION_STRAGETY_H -#include "block_data.h" #include "strategy.h" namespace OHOS::DataShare { -class ConnectExtensionStrategy final : public Strategy { +class CrossPermissionStrategy final : public Strategy { public: - ConnectExtensionStrategy(); + explicit CrossPermissionStrategy(std::initializer_list permissions); bool operator()(std::shared_ptr context) override; - static bool Execute(std::shared_ptr context, std::function isFinished, int maxWaitTimeMs = 2000); private: - inline bool Connect(std::shared_ptr context); - std::mutex mutex_; - BlockData data_; + std::vector allowCrossPermissions_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp index 5f9a931d4db75893c937f2614622a09398b80c02..859bc4366e58e94065bf9e519c72393a99bcd319 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp @@ -15,7 +15,9 @@ #define LOG_TAG "LoadConfigCommonStrategy" #include "load_config_common_strategy.h" +#include "accesstoken_kit.h" #include "account/account_delegate.h" +#include "hap_token_info.h" #include "ipc_skeleton.h" #include "log_print.h" #include "uri_utils.h" @@ -23,19 +25,31 @@ namespace OHOS::DataShare { bool LoadConfigCommonStrategy::operator()(std::shared_ptr context) { - context->callerTokenId = IPCSkeleton::GetCallingTokenID(); + if (context->callerTokenId == 0) { + context->callerTokenId = IPCSkeleton::GetCallingTokenID(); + } context->currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(context->callerTokenId); - // single app, userId is in uri + // sa, userId is in uri, caller token id is from first caller tokenId if (context->currentUserId == 0) { - URIUtils::GetUserIdFromProxyURI(context->uri, context->currentUserId); + URIUtils::GetInfoFromProxyURI( + context->uri, context->currentUserId, context->callerTokenId, context->calledBundleName); + FormatUri(context->uri); + } + if (context->needAutoLoadCallerBundleName && context->callerBundleName.empty()) { + Security::AccessToken::HapTokenInfo tokenInfo; + auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(context->callerTokenId, tokenInfo); + if (result != Security::AccessToken::RET_SUCCESS) { + ZLOGE("token:0x%{public}x, result:%{public}d", context->callerTokenId, result); + return false; + } + context->callerBundleName = tokenInfo.bundleName; } - FormatUri(context->uri); return true; } void LoadConfigCommonStrategy::FormatUri(std::string &uri) { - auto pos = uri.find('?'); + auto pos = uri.find_last_of('?'); if (pos == std::string::npos) { return; } diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp index 392856216c58df5107be48f511b210857605804f..bdf75cf71bfc9117ebd2680a7f3dd3fa180409f7 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp @@ -16,8 +16,8 @@ #include "load_config_data_info_strategy.h" #include "check_is_single_app_strategy.h" -#include "connect_extension_strategy.h" #include "device_manager_adapter.h" +#include "extension_connect_adaptor.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" @@ -49,22 +49,19 @@ static bool QueryMetaData(const std::string &bundleName, const std::string &stor bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr context) { if (context->type != "rdb") { - return false; + return true; } DistributedData::StoreMetaData metaData; if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { // connect extension and retry - if (!ConnectExtensionStrategy::Execute(context, [&context, &metaData]() { - return QueryMetaData( - context->calledBundleName, context->calledStoreName, metaData, context->currentUserId); - })) { + ExtensionConnectAdaptor::TryAndWait(context); + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; return false; } } context->calledSourceDir = metaData.dataDir; - context->version = metaData.version; return true; } @@ -73,16 +70,14 @@ bool LoadConfigSingleDataInfoStrategy::operator()(std::shared_ptr conte DistributedData::StoreMetaData metaData; if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { // connect extension and retry - if (!ConnectExtensionStrategy::Execute(context, [&context, &metaData]() { - return QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0); - })) { + ExtensionConnectAdaptor::TryAndWait(context); + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; return false; } } context->calledSourceDir = metaData.dataDir; - context->version = metaData.version; return true; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp index 86a4ffbae233292e822d99e809fa31035bb1477b..92fcef984abf6b43d0c336855aa75131138b1c7f 100644 --- a/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp @@ -23,9 +23,10 @@ namespace OHOS::DataShare { bool PermissionStrategy::operator()(std::shared_ptr context) { if (context->permission == "reject") { + ZLOGE("reject permission"); return false; } - if (!context->permission.empty()) { + if (!context->isAllowCrossPer && !context->permission.empty()) { int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(context->callerTokenId, context->permission); if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { diff --git a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp index 2d5e432b139bfc7e5573679faf8c74e856b88e8e..2df8047a273abbf06f888a2b168a340cfe735f6a 100644 --- a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp @@ -16,47 +16,87 @@ #include "get_data_strategy.h" -#include "general/load_config_common_strategy.h" -#include "general/permission_strategy.h" +#include "accesstoken_kit.h" #include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "general/load_config_common_strategy.h" #include "log_print.h" #include "utils/anonymous.h" namespace OHOS::DataShare { -Data GetDataStrategy::Execute(std::shared_ptr context) +Data GetDataStrategy::Execute(std::shared_ptr context, int &errorCode) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); + errorCode = E_ERROR; return Data(); } - if (!(*preProcess)(context)) { + if (!preProcess(context)) { ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + errorCode = context->errCode; return Data(); } - return Data(); + auto result = PublishedData::Query(context->calledBundleName, context->currentUserId); + Data data; + for (const auto &item:result) { + if (!CheckPermission(context, item.value.key)) { + ZLOGI("uri: %{private}s not allowed", context->uri.c_str()); + continue; + } + if (item.GetVersion() > data.version_) { + data.version_ = item.GetVersion(); + } + data.datas_.emplace_back(item.value.key, item.value.subscriberId, item.value.value); + } + return data; } -Strategy *GetDataStrategy::GetStrategy() +SeqStrategy &GetDataStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow) LoadConfigCommonStrategy(), - new (std::nothrow) LoadConfigFromDataProxyNodeStrategy(), - new (std::nothrow) PermissionStrategy() + new (std::nothrow) LoadConfigFromDataProxyNodeStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; + } + return strategies_; +} + +bool GetDataStrategy::CheckPermission(std::shared_ptr context, const std::string &key) +{ + if (context->callerBundleName == context->calledBundleName) { + ZLOGI("access private data, caller and called is same, go"); + return true; + } + for (const auto &moduleInfo : context->bundleInfo.hapModuleInfos) { + auto proxyDatas = moduleInfo.proxyDatas; + for (auto &proxyData : proxyDatas) { + if (proxyData.uri != key) { + continue; + } + if (proxyData.requiredReadPermission.empty()) { + ZLOGE("no read permission"); + return false; + } + int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken( + context->callerTokenId, proxyData.requiredReadPermission); + if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + ZLOGE("Verify permission denied! callerTokenId:%{public}u permission:%{public}s", + context->callerTokenId, proxyData.requiredReadPermission.c_str()); + return false; + } + return true; + } } - return &strategies; + return false; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h index 062f2a790e7b7253a3888a6e8ebeea52ef7e938a..076bae8df9b825091c60cc32445dc0f98ccc642e 100644 --- a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h @@ -19,15 +19,20 @@ #include #include "data_proxy_observer.h" +#include "datashare_template.h" +#include "published_data.h" #include "seq_strategy.h" namespace OHOS::DataShare { class GetDataStrategy final { public: - static Data Execute(std::shared_ptr context); + Data Execute(std::shared_ptr context, int &errorCode); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; + bool CheckPermission(std::shared_ptr context, const std::string &key); }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp index 792ead9cf5e8ce30298ac3ca9dd1579ba73f3272..3684bce5024516d39c82fa80252d5c35a73fb028 100644 --- a/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp @@ -28,12 +28,12 @@ namespace OHOS::DataShare { int64_t InsertStrategy::Execute(std::shared_ptr context, const DataShareValuesBucket &valuesBucket) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return -1; } - if (!(*preProcess)(context)) { + if (!preProcess(context)) { ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } @@ -45,13 +45,11 @@ int64_t InsertStrategy::Execute(std::shared_ptr context, const DataShar return delegate->Insert(context->calledTableName, valuesBucket); } -Strategy *InsertStrategy::GetStrategy() +SeqStrategy &InsertStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow)LoadConfigCommonStrategy(), @@ -60,13 +58,13 @@ Strategy *InsertStrategy::GetStrategy() new (std::nothrow)LoadConfigDataInfoStrategy(), new (std::nothrow)ProcessSingleAppUserCrossStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/insert_strategy.h b/services/distributeddataservice/service/data_share/strategies/insert_strategy.h index c54720183ebe593660d6cacbba44a7776356d370..61705316072293798c967dbd139030520a600559 100644 --- a/services/distributeddataservice/service/data_share/strategies/insert_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/insert_strategy.h @@ -23,10 +23,12 @@ namespace OHOS::DataShare { class InsertStrategy final { public: - static int64_t Execute(std::shared_ptr context, const DataShareValuesBucket &valuesBucket); + int64_t Execute(std::shared_ptr context, const DataShareValuesBucket &valuesBucket); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp index d658954cf5951ea758a578e90118b2875eb8921c..5c785f9e5889acaebeb62eb54c2e3f27de57e747 100644 --- a/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp @@ -17,46 +17,62 @@ #include "publish_strategy.h" #include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "general/cross_permission_strategy.h" #include "general/load_config_common_strategy.h" #include "general/permission_strategy.h" #include "log_print.h" +#include "published_data.h" #include "utils/anonymous.h" namespace OHOS::DataShare { int32_t PublishStrategy::Execute(std::shared_ptr context, const PublishedDataItem &item) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return -1; } - if (!(*preProcess)(context)) { + if (!preProcess(context)) { ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return context->errCode; + } + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return -1; + } + PublishedDataNode node( + context->uri, context->calledBundleName, item.subscriberId_, context->currentUserId, item.GetData()); + PublishedData data(node, context->version); + int32_t status = delegate->Upsert(KvDBDelegate::DATA_TABLE, data); + if (status != E_OK) { + ZLOGE("db Upsert failed, %{public}s %{public}s %{public}d", context->calledBundleName.c_str(), + DistributedData::Anonymous::Change(context->uri).c_str(), status); return -1; } - return 0; + return E_OK; } -Strategy *PublishStrategy::GetStrategy() +SeqStrategy &PublishStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } + std::initializer_list allowCrossPermissions = { "ohos.permission.WRITE_APP_PUSH_DATA" }; std::initializer_list list = { new (std::nothrow) LoadConfigCommonStrategy(), + new (std::nothrow) CrossPermissionStrategy(allowCrossPermissions), new (std::nothrow) LoadConfigFromDataProxyNodeStrategy(), new (std::nothrow) PermissionStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/publish_strategy.h b/services/distributeddataservice/service/data_share/strategies/publish_strategy.h index 70acdf7c51d123b5278e82b6b722412253da54eb..92cebcf9418f74552e53455e987175f474b73378 100644 --- a/services/distributeddataservice/service/data_share/strategies/publish_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/publish_strategy.h @@ -24,10 +24,12 @@ namespace OHOS::DataShare { class PublishStrategy final { public: - static int32_t Execute(std::shared_ptr context, const PublishedDataItem &item); + int32_t Execute(std::shared_ptr context, const PublishedDataItem &item); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp index c2e2852a71f82df94e1ec6673a54933cd4bc3b16..fc86a74840370fc463602820041f228e4ae50402 100644 --- a/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp @@ -29,12 +29,13 @@ std::shared_ptr QueryStrategy::Execute( std::shared_ptr context, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return nullptr; } - if (!(*preProcess)(context)) { + context->isRead = true; + if (!preProcess(context)) { errCode = context->errCode; ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return nullptr; @@ -47,13 +48,11 @@ std::shared_ptr QueryStrategy::Execute( return delegate->Query(context->calledTableName, predicates, columns, errCode); } -Strategy *QueryStrategy::GetStrategy() +SeqStrategy &QueryStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow)LoadConfigCommonStrategy(), @@ -62,13 +61,13 @@ Strategy *QueryStrategy::GetStrategy() new (std::nothrow)LoadConfigDataInfoStrategy(), new (std::nothrow)ProcessSingleAppUserCrossStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/query_strategy.h b/services/distributeddataservice/service/data_share/strategies/query_strategy.h index 13b0186f7dc9997aa43d3f61e2654c2c7e7dc7b2..6208089fdc0b3337e6bd18f8f6cbe107450298a4 100644 --- a/services/distributeddataservice/service/data_share/strategies/query_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/query_strategy.h @@ -24,11 +24,13 @@ namespace OHOS::DataShare { class QueryStrategy final { public: - static std::shared_ptr Execute(std::shared_ptr context, + std::shared_ptr Execute(std::shared_ptr context, const DataSharePredicates &predicates, const std::vector &columns, int &errCode); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab3c95d8711c4a94c1f24d2f49b829670394b8b8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp @@ -0,0 +1,65 @@ +/* + * 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. + */ +#define LOG_TAG "RdbNotifyStrategy" + +#include "rdb_notify_strategy.h" + +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/load_config_from_bundle_info_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +bool RdbNotifyStrategy::Execute(std::shared_ptr context) +{ + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { + ZLOGE("get strategy fail, maybe memory not enough"); + return false; + } + if (!preProcess(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return false; + } + if (context->callerBundleName != context->calledBundleName) { + ZLOGD("not your data, cannot notify, callerBundleName: %{public}s, calledBundleName: %{public}s", + context->callerBundleName.c_str(), context->calledBundleName.c_str()); + return false; + } + return true; +} + +SeqStrategy &RdbNotifyStrategy::GetStrategy() +{ + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromBundleInfoStrategy(), + new (std::nothrow)LoadConfigDataInfoStrategy() + }; + auto ret = strategies_.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return strategies_; + } + return strategies_; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.h b/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..d6678ccd741077c4c053e175890c64e9a5b8d92b --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATASHARESERVICE_RDB_NOTIFY_STRAGETY_H +#define DATASHARESERVICE_RDB_NOTIFY_STRAGETY_H + +#include + +#include "datashare_values_bucket.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class RdbNotifyStrategy final { +public: + bool Execute(std::shared_ptr context); + +private: + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp index 3835435c8772ae161b77900e8b4c1d58d3f8ce34..4b7314c88ba32cbdac295d6b30f14089464e8869 100644 --- a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp @@ -24,39 +24,40 @@ #include "utils/anonymous.h" namespace OHOS::DataShare { -int32_t SubscribeStrategy::Execute(std::shared_ptr context, std::function process) +int32_t SubscribeStrategy::Execute(std::shared_ptr context, std::function process) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return -1; } - if (!(*preProcess)(context)) { - ZLOGE("pre process fail, uri_: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + context->isRead = true; + context->needAutoLoadCallerBundleName = true; + if (!preProcess(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return context->errCode; } return process(); } -Strategy *SubscribeStrategy::GetStrategy() + +SeqStrategy &SubscribeStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow)LoadConfigCommonStrategy(), new (std::nothrow)LoadConfigFromDataProxyNodeStrategy(), new (std::nothrow)PermissionStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h index f11c4a6d9a7e746b17b8f5ed94533f77fd255a3a..3456b66cd4a798112bb168bcbf173d61c53a96de 100644 --- a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h @@ -23,10 +23,12 @@ namespace OHOS::DataShare { class SubscribeStrategy final { public: - static int32_t Execute(std::shared_ptr context, std::function process); + int32_t Execute(std::shared_ptr context, std::function process); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.cpp b/services/distributeddataservice/service/data_share/strategies/template_strategy.cpp similarity index 31% rename from services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.cpp rename to services/distributeddataservice/service/data_share/strategies/template_strategy.cpp index 52efe42d043857c24a9a44c4b35afee28f810370..fd33112a78621d6a1b38315cddd25083197b02af 100644 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.cpp +++ b/services/distributeddataservice/service/data_share/strategies/template_strategy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,49 +12,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "TemplateStrategy" -#define LOG_TAG "KvStoreThread" +#include "template_strategy.h" -#include "kv_store_thread_pool_impl.h" +#include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "datashare_errno.h" +#include "general/load_config_common_strategy.h" #include "log_print.h" -#include "pthread.h" +#include "utils/anonymous.h" -namespace OHOS { -namespace DistributedKv { -KvStoreThread::KvStoreThread(KvStoreThreadPool *threadPool, const std::string &name) +namespace OHOS::DataShare { +int32_t TemplateStrategy::Execute(std::shared_ptr context, std::function process) { - realThread_ = std::thread([this, threadPool, name]() { - // this makes me unconfortable: this lambda capture 'this' by reference, and right after this call this object - // is move-constructed, so when we call this in Run(), we are actually refer to the old object. we can still - // use all its non-virtual function, but all arguments and virtual-function are not available. - int32_t ret = pthread_setname_np(pthread_self(), name.c_str()); - if (ret != 0) { - ZLOGE("Failed to set thread name:%{public}s, ret:%{public}d.", name.c_str(), ret); - } - Run(threadPool); - }); -} - -void KvStoreThread::Run(KvStoreThreadPool *pool) -{ - if (pool == nullptr) { - ZLOGW("input param is null."); - return; + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { + ZLOGE("get strategy fail, maybe memory not enough"); + return E_ERROR; } - auto impl = reinterpret_cast(pool); - while (impl->IsRunning()) { - impl->ScheduleTask()(); + if (!preProcess(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return context->errCode; } - ZLOGW("stop"); + return process(); } -void KvStoreThread::Join() +SeqStrategy &TemplateStrategy::GetStrategy() { - realThread_.join(); + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; + } + std::initializer_list list = { + new (std::nothrow) LoadConfigCommonStrategy(), + new (std::nothrow) LoadConfigFromDataProxyNodeStrategy() + }; + auto ret = strategies_.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return strategies_; + } + return strategies_; } - -KvStoreThread::~KvStoreThread() -{} -} // namespace DistributedKv -} // namespace OHOS +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/template_strategy.h b/services/distributeddataservice/service/data_share/strategies/template_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..8443cd2d05d46ed6358afffebd88b091c4ea3343 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/template_strategy.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LDBPROJ_TEMPLATE_STRATEGY_H +#define LDBPROJ_TEMPLATE_STRATEGY_H + +#include + +#include "data_proxy_observer.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class TemplateStrategy final { +public: + int32_t Execute(std::shared_ptr context, std::function process); + +private: + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; +}; +} // namespace OHOS::DataShare +#endif // LDBPROJ_TEMPLATE_STRATEGY_H diff --git a/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp index 800832ac0925e7f3eec8c47002253afa2c4c971b..c24cd78497c2c6b2d4983baba1a8ba7fbc20b9ad 100644 --- a/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp +++ b/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp @@ -28,12 +28,12 @@ namespace OHOS::DataShare { int64_t UpdateStrategy::Execute( std::shared_ptr context, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) { - auto preProcess = GetStrategy(); - if (preProcess == nullptr) { + auto &preProcess = GetStrategy(); + if (preProcess.IsEmpty()) { ZLOGE("get strategy fail, maybe memory not enough"); return -1; } - if (!(*preProcess)(context)) { + if (!preProcess(context)) { ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } @@ -45,13 +45,11 @@ int64_t UpdateStrategy::Execute( return delegate->Update(context->calledTableName, predicate, valuesBucket); } -Strategy *UpdateStrategy::GetStrategy() +SeqStrategy &UpdateStrategy::GetStrategy() { - static std::mutex mutex; - static SeqStrategy strategies; - std::lock_guard lock(mutex); - if (!strategies.IsEmpty()) { - return &strategies; + std::lock_guard lock(mutex_); + if (!strategies_.IsEmpty()) { + return strategies_; } std::initializer_list list = { new (std::nothrow)LoadConfigCommonStrategy(), @@ -60,13 +58,13 @@ Strategy *UpdateStrategy::GetStrategy() new (std::nothrow)LoadConfigDataInfoStrategy(), new (std::nothrow)ProcessSingleAppUserCrossStrategy() }; - auto ret = strategies.Init(list); + auto ret = strategies_.Init(list); if (!ret) { std::for_each(list.begin(), list.end(), [](Strategy *item) { delete item; }); - return nullptr; + return strategies_; } - return &strategies; + return strategies_; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/update_strategy.h b/services/distributeddataservice/service/data_share/strategies/update_strategy.h index 4ee54764f2ddf4dc18cc57ac4f2edd302cb74b8b..38e4116f212d2855e1e1082ddf557c4ada85d853 100644 --- a/services/distributeddataservice/service/data_share/strategies/update_strategy.h +++ b/services/distributeddataservice/service/data_share/strategies/update_strategy.h @@ -25,11 +25,13 @@ namespace OHOS::DataShare { class UpdateStrategy final { public: - static int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate, + int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket); private: - static Strategy *GetStrategy(); + SeqStrategy &GetStrategy(); + std::mutex mutex_; + SeqStrategy strategies_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f057ed01dba97a8247b6c17de1d70768dded2d8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp @@ -0,0 +1,267 @@ +/* + * 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. + */ +#define LOG_TAG "PublishedDataSubscriberManager" + +#include "published_data_subscriber_manager.h" + +#include "general/load_config_data_info_strategy.h" +#include "log_print.h" +#include "published_data.h" +#include "uri_utils.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +PublishedDataSubscriberManager &PublishedDataSubscriberManager::GetInstance() +{ + static PublishedDataSubscriberManager manager; + return manager; +} + +int PublishedDataSubscriberManager::Add( + const PublishedDataKey &key, const sptr observer, uint32_t callerTokenId) +{ + publishedDataCache_.Compute( + key, [&observer, &callerTokenId, this](const PublishedDataKey &key, std::vector &value) { + ZLOGI("add publish subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId); + value.emplace_back(observer, callerTokenId); + return true; + }); + return E_OK; +} + +int PublishedDataSubscriberManager::Delete(const PublishedDataKey &key, uint32_t callerTokenId) +{ + auto result = + publishedDataCache_.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("delete publish subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId); + it = value.erase(it); + } else { + it++; + } + } + return !value.empty(); + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +void PublishedDataSubscriberManager::Delete(uint32_t callerTokenId) +{ + publishedDataCache_.EraseIf([&callerTokenId](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("erase start, uri is %{public}s, tokenId is 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId); + it = value.erase(it); + } else { + it++; + } + } + return value.empty(); + }); +} + +int PublishedDataSubscriberManager::Disable(const PublishedDataKey &key, uint32_t callerTokenId) +{ + auto result = + publishedDataCache_.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (it->callerTokenId == callerTokenId) { + it->enabled = false; + it->isNotifyOnEnabled = false; + } + } + return true; + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +int PublishedDataSubscriberManager::Enable(const PublishedDataKey &key, uint32_t callerTokenId) +{ + auto result = + publishedDataCache_.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (it->callerTokenId == callerTokenId) { + it->enabled = true; + } + } + return true; + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +void PublishedDataSubscriberManager::Emit(const std::vector &keys, int32_t userId, + const std::string &ownerBundleName, const sptr observer) +{ + int32_t status; + // key is bundleName, value is change node + std::map publishedResult; + std::map, std::vector> callbacks; + publishedDataCache_.ForEach([&keys, &status, &observer, &publishedResult, &callbacks, &userId, this]( + const PublishedDataKey &key, std::vector &val) { + for (auto &data : keys) { + if (key != data || publishedResult.count(key) != 0) { + continue; + } + status = PublishedData::Query( + Id(PublishedData::GenId(key.key, key.bundleName, key.subscriberId), userId), publishedResult[key]); + if (status != E_OK) { + ZLOGE("query fail %{public}s %{public}s %{public}" PRId64, data.bundleName.c_str(), data.key.c_str(), + data.subscriberId); + publishedResult.erase(key); + continue; + } + PutInto(callbacks, val, key, observer); + break; + } + return false; + }); + PublishedDataChangeNode result; + for (auto &[callback, keys] : callbacks) { + result.datas_.clear(); + for (auto &key : keys) { + if (publishedResult.count(key) != 0) { + result.datas_.emplace_back(key.key, key.subscriberId, publishedResult[key]); + } + } + if (result.datas_.empty()) { + continue; + } + result.ownerBundleName_ = ownerBundleName; + callback->OnChangeFromPublishedData(result); + } +} + +void PublishedDataSubscriberManager::PutInto( + std::map, std::vector> &callbacks, + const std::vector &val, const PublishedDataKey &key, + const sptr observer) +{ + for (auto const &callback : val) { + if (callback.enabled && callback.observer != nullptr) { + // callback the observer, others do not call + if (observer != nullptr && callback.observer != observer) { + continue; + } + callbacks[callback.observer].emplace_back(key); + } + } +} + +void PublishedDataSubscriberManager::Clear() +{ + publishedDataCache_.Clear(); +} + +int PublishedDataSubscriberManager::GetCount(const PublishedDataKey &key) +{ + int count = 0; + publishedDataCache_.ComputeIfPresent(key, [&count](const auto &key, std::vector &value) { + count = static_cast(value.size()); + return true; + }); + return count; +} + +bool PublishedDataSubscriberManager::IsNotifyOnEnabled(const PublishedDataKey &key, uint32_t callerTokenId) +{ + auto pair = publishedDataCache_.Find(key); + if (!pair.first) { + return false; + } + for (const auto &value : pair.second) { + if (value.callerTokenId == callerTokenId && value.isNotifyOnEnabled) { + return true; + } + } + return false; +} + +void PublishedDataSubscriberManager::SetObserversNotifiedOnEnabled(const std::vector &keys) +{ + for (const auto &pkey : keys) { + publishedDataCache_.ComputeIfPresent(pkey, [](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (!it->enabled) { + it->isNotifyOnEnabled = true; + } + } + return true; + }); + } +} + +PublishedDataKey::PublishedDataKey(const std::string &key, const std::string &bundle, const int64_t subscriberId) + : key(key), bundleName(bundle), subscriberId(subscriberId) +{ + /* private published data can use key as simple uri */ + /* etc: datashareproxy://{bundleName}/meeting can use meeting replaced */ + /* if key is normal uri, bundleName is from uri */ + if (URIUtils::IsDataProxyURI(key)) { + URIUtils::GetBundleNameFromProxyURI(key, bundleName); + } +} + +bool PublishedDataKey::operator<(const PublishedDataKey &rhs) const +{ + if (key < rhs.key) { + return true; + } + if (rhs.key < key) { + return false; + } + if (bundleName < rhs.bundleName) { + return true; + } + if (rhs.bundleName < bundleName) { + return false; + } + return subscriberId < rhs.subscriberId; +} + +bool PublishedDataKey::operator>(const PublishedDataKey &rhs) const +{ + return rhs < *this; +} + +bool PublishedDataKey::operator<=(const PublishedDataKey &rhs) const +{ + return !(rhs < *this); +} + +bool PublishedDataKey::operator>=(const PublishedDataKey &rhs) const +{ + return !(*this < rhs); +} + +bool PublishedDataKey::operator==(const PublishedDataKey &rhs) const +{ + return key == rhs.key && bundleName == rhs.bundleName && subscriberId == rhs.subscriberId; +} + +bool PublishedDataKey::operator!=(const PublishedDataKey &rhs) const +{ + return !(rhs == *this); +} + +PublishedDataSubscriberManager::ObserverNode::ObserverNode( + const sptr &observer, uint32_t callerTokenId) + : observer(observer), callerTokenId(callerTokenId) +{ +} +} // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..2cef1f7cdf16a75a65dc3af3dd54c961d3eb76ba --- /dev/null +++ b/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_PUBLISHED_DATA_SUBSCRIBER_MANAGER_H +#define DATASHARESERVICE_PUBLISHED_DATA_SUBSCRIBER_MANAGER_H + +#include +#include + +#include "concurrent_map.h" +#include "context.h" +#include "data_proxy_observer.h" +#include "datashare_template.h" +#include "executor_pool.h" +namespace OHOS::DataShare { +struct PublishedDataKey { + PublishedDataKey(const std::string &key, const std::string &bundleName, int64_t subscriberId); + bool operator<(const PublishedDataKey &rhs) const; + bool operator>(const PublishedDataKey &rhs) const; + bool operator<=(const PublishedDataKey &rhs) const; + bool operator>=(const PublishedDataKey &rhs) const; + bool operator==(const PublishedDataKey &rhs) const; + bool operator!=(const PublishedDataKey &rhs) const; + std::string key; + std::string bundleName; + int64_t subscriberId; +}; + +class PublishedDataSubscriberManager { +public: + static PublishedDataSubscriberManager &GetInstance(); + int Add(const PublishedDataKey &key, const sptr observer, + uint32_t callerTokenId); + int Delete(const PublishedDataKey &key, uint32_t callerTokenId); + void Delete(uint32_t callerTokenId); + int Disable(const PublishedDataKey &key, uint32_t callerTokenId); + int Enable(const PublishedDataKey &key, uint32_t callerTokenId); + void Emit(const std::vector &keys, int32_t userId, const std::string &ownerBundleName, + const sptr observer = nullptr); + void Clear(); + int GetCount(const PublishedDataKey &key); + + bool IsNotifyOnEnabled(const PublishedDataKey &key, uint32_t callerTokenId); + void SetObserversNotifiedOnEnabled(const std::vector &keys); + +private: + struct ObserverNode { + ObserverNode(const sptr &observer, uint32_t callerTokenId); + sptr observer; + uint32_t callerTokenId; + bool enabled = true; + bool isNotifyOnEnabled = false; + }; + + PublishedDataSubscriberManager() = default; + void PutInto(std::map, std::vector> &, + const std::vector &, const PublishedDataKey &, const sptr); + ConcurrentMap> publishedDataCache_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6abb222507600c4eabb432e9e126d57b3584b307 --- /dev/null +++ b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp @@ -0,0 +1,328 @@ +/* + * 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. + */ +#define LOG_TAG "RdbSubscriberManager" + +#include "rdb_subscriber_manager.h" + +#include "general/load_config_data_info_strategy.h" +#include "log_print.h" +#include "scheduler_manager.h" +#include "template_data.h" +#include "uri_utils.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +bool TemplateManager::Get(const Key &key, int32_t userId, Template &tpl) +{ + return TemplateData::Query(Id(TemplateData::GenId(key.uri, key.bundleName, key.subscriberId), userId), tpl) == E_OK; +} + +int32_t TemplateManager::Add(const Key &key, int32_t userId, const Template &tpl) +{ + auto status = TemplateData::Add(key.uri, userId, key.bundleName, key.subscriberId, tpl); + if (!status) { + ZLOGE("Add failed, %{public}d", status); + return E_ERROR; + } + return E_OK; +} + +int32_t TemplateManager::Delete(const Key &key, int32_t userId) +{ + auto status = TemplateData::Delete(key.uri, userId, key.bundleName, key.subscriberId); + if (!status) { + ZLOGE("Delete failed, %{public}d", status); + return E_ERROR; + } + SchedulerManager::GetInstance().RemoveTimer(key); + return E_OK; +} + +Key::Key(const std::string &uri, int64_t subscriberId, const std::string &bundleName) + : uri(uri), subscriberId(subscriberId), bundleName(bundleName) +{ +} + +bool Key::operator==(const Key &rhs) const +{ + return uri == rhs.uri && subscriberId == rhs.subscriberId && bundleName == rhs.bundleName; +} + +bool Key::operator!=(const Key &rhs) const +{ + return !(rhs == *this); +} +bool Key::operator<(const Key &rhs) const +{ + if (uri < rhs.uri) { + return true; + } + if (rhs.uri < uri) { + return false; + } + if (subscriberId < rhs.subscriberId) { + return true; + } + if (rhs.subscriberId < subscriberId) { + return false; + } + return bundleName < rhs.bundleName; +} +bool Key::operator>(const Key &rhs) const +{ + return rhs < *this; +} +bool Key::operator<=(const Key &rhs) const +{ + return !(rhs < *this); +} +bool Key::operator>=(const Key &rhs) const +{ + return !(*this < rhs); +} + +TemplateManager::TemplateManager() {} + +TemplateManager &TemplateManager::GetInstance() +{ + static TemplateManager manager; + return manager; +} + +RdbSubscriberManager &RdbSubscriberManager::GetInstance() +{ + static RdbSubscriberManager manager; + return manager; +} + +int RdbSubscriberManager::Add(const Key &key, const sptr observer, + std::shared_ptr context, std::shared_ptr executorPool) +{ + int result = E_OK; + rdbCache_.Compute(key, [&observer, &context, executorPool, this](const auto &key, auto &value) { + ZLOGI("add subscriber, uri %{private}s tokenId 0x%{public}x", key.uri.c_str(), context->callerTokenId); + std::vector node; + node.emplace_back(observer, context->callerTokenId); + ExecutorPool::Task task = [key, node, context, this]() { + LoadConfigDataInfoStrategy loadDataInfo; + if (loadDataInfo(context)) { + Notify(key, context->currentUserId, node, context->calledSourceDir, context->version); + } + }; + executorPool->Execute(task); + value.emplace_back(observer, context->callerTokenId); + if (GetEnableObserverCount(key) == 1) { + SchedulerManager::GetInstance().Execute( + key, context->currentUserId, context->calledSourceDir, context->version); + } + return true; + }); + return result; +} + +int RdbSubscriberManager::Delete(const Key &key, uint32_t callerTokenId) +{ + auto result = + rdbCache_.ComputeIfPresent(key, [&callerTokenId, this](const auto &key, std::vector &value) { + ZLOGI("delete subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.uri).c_str(), callerTokenId); + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("erase start"); + it = value.erase(it); + } else { + it++; + } + } + if (GetEnableObserverCount(key) == 0) { + SchedulerManager::GetInstance().RemoveTimer(key); + } + return !value.empty(); + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +void RdbSubscriberManager::Delete(uint32_t callerTokenId) +{ + rdbCache_.EraseIf([&callerTokenId, this](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("erase start, uri is %{public}s, tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.uri).c_str(), callerTokenId); + it = value.erase(it); + } else { + it++; + } + } + if (GetEnableObserverCount(key) == 0) { + SchedulerManager::GetInstance().RemoveTimer(key); + } + return value.empty(); + }); +} + +int RdbSubscriberManager::Disable(const Key &key, uint32_t callerTokenId) +{ + auto result = + rdbCache_.ComputeIfPresent(key, [&callerTokenId, this](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (it->callerTokenId == callerTokenId) { + it->enabled = false; + it->isNotifyOnEnabled = false; + } + } + return true; + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +int RdbSubscriberManager::Enable(const Key &key, std::shared_ptr context) +{ + auto result = rdbCache_.ComputeIfPresent(key, [&context, this](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (it->callerTokenId != context->callerTokenId) { + continue; + } + it->enabled = true; + if (it->isNotifyOnEnabled) { + std::vector node; + node.emplace_back(it->observer, context->callerTokenId); + LoadConfigDataInfoStrategy loadDataInfo; + if (loadDataInfo(context)) { + Notify(key, context->currentUserId, node, context->calledSourceDir, context->version); + } + } + } + return true; + }); + return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; +} + +void RdbSubscriberManager::Emit(const std::string &uri, std::shared_ptr context) +{ + if (!URIUtils::IsDataProxyURI(uri)) { + return; + } + if (context->calledSourceDir.empty()) { + LoadConfigDataInfoStrategy loadDataInfo; + loadDataInfo(context); + } + rdbCache_.ForEach([&uri, &context, this](const Key &key, std::vector &val) { + if (key.uri != uri) { + return false; + } + Notify(key, context->currentUserId, val, context->calledSourceDir, context->version); + SetObserverNotifyOnEnabled(val); + return false; + }); + SchedulerManager::GetInstance().Execute( + uri, context->currentUserId, context->calledSourceDir, context->version); +} + +void RdbSubscriberManager::SetObserverNotifyOnEnabled(std::vector &nodes) +{ + for (auto &node : nodes) { + if (!node.enabled) { + node.isNotifyOnEnabled = true; + } + } +} + +std::vector RdbSubscriberManager::GetKeysByUri(const std::string &uri) +{ + std::vector results; + rdbCache_.ForEach([&uri, &results](const Key &key, std::vector &val) { + if (key.uri != uri) { + return false; + } + results.emplace_back(key); + return false; + }); + return results; +} + +void RdbSubscriberManager::EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version) +{ + if (!URIUtils::IsDataProxyURI(key.uri)) { + return; + } + rdbCache_.ComputeIfPresent(key, [&rdbPath, &version, &userId, this](const Key &key, auto &val) { + Notify(key, userId, val, rdbPath, version); + SetObserverNotifyOnEnabled(val); + return true; + }); +} + +int RdbSubscriberManager::GetEnableObserverCount(const Key &key) +{ + auto pair = rdbCache_.Find(key); + if (!pair.first) { + return 0; + } + int count = 0; + for (const auto &observer : pair.second) { + if (observer.enabled) { + count++; + } + } + return count; +} + +int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vector &val, + const std::string &rdbDir, int rdbVersion) +{ + Template tpl; + if (!TemplateManager::GetInstance().Get(key, userId, tpl)) { + ZLOGE("template undefined, %{public}s, %{public}" PRId64 ", %{public}s", + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + return E_TEMPLATE_NOT_EXIST; + } + auto delegate = DBDelegate::Create(rdbDir, rdbVersion, true); + if (delegate == nullptr) { + ZLOGE("Create fail %{public}s %{public}s", DistributedData::Anonymous::Change(key.uri).c_str(), + key.bundleName.c_str()); + return E_ERROR; + } + RdbChangeNode changeNode; + changeNode.uri_ = key.uri; + changeNode.templateId_.subscriberId_ = key.subscriberId; + changeNode.templateId_.bundleName_ = key.bundleName; + for (const auto &predicate : tpl.predicates_) { + std::string result = delegate->Query(predicate.selectSql_); + if (result.empty()) { + continue; + } + changeNode.data_.emplace_back("{\"" + predicate.key_ + "\":" + result + "}"); + } + + ZLOGI("emit, size %{public}zu %{private}s", val.size(), changeNode.uri_.c_str()); + for (const auto &callback : val) { + if (callback.enabled && callback.observer != nullptr) { + callback.observer->OnChangeFromRdb(changeNode); + } + } + return E_OK; +} + +void RdbSubscriberManager::Clear() +{ + rdbCache_.Clear(); +} + +RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, uint32_t callerTokenId) + : observer(observer), callerTokenId(callerTokenId) +{ +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..a0636dd0eb08e7026baf811aa0ba7292242c68a9 --- /dev/null +++ b/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_RDB_SUBSCRIBER_MANAGER_H +#define DATASHARESERVICE_RDB_SUBSCRIBER_MANAGER_H + +#include +#include + +#include "concurrent_map.h" +#include "context.h" +#include "data_proxy_observer.h" +#include "datashare_template.h" +#include "executor_pool.h" +namespace OHOS::DataShare { +struct Key { + Key(const std::string &uri, int64_t subscriberId, const std::string &bundleName); + bool operator==(const Key &rhs) const; + bool operator!=(const Key &rhs) const; + bool operator<(const Key &rhs) const; + bool operator>(const Key &rhs) const; + bool operator<=(const Key &rhs) const; + bool operator>=(const Key &rhs) const; + const std::string uri; + const int64_t subscriberId; + const std::string bundleName; +}; +class TemplateManager { +public: + static TemplateManager &GetInstance(); + int32_t Add(const Key &key, int32_t userId, const Template &tpl); + int32_t Delete(const Key &key, int32_t userId); + bool Get(const Key &key, int32_t userId, Template &tpl); + +private: + TemplateManager(); + friend class RdbSubscriberManager; +}; + +class RdbSubscriberManager { +public: + static RdbSubscriberManager &GetInstance(); + int Add(const Key &key, const sptr observer, std::shared_ptr context, + std::shared_ptr executorPool); + int Delete(const Key &key, uint32_t callerTokenId); + void Delete(uint32_t callerTokenId); + int Disable(const Key &key, uint32_t callerTokenId); + int Enable(const Key &key, std::shared_ptr context); + void Emit(const std::string &uri, std::shared_ptr context); + void EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version); + std::vector GetKeysByUri(const std::string &uri); + void Clear(); + +private: + struct ObserverNode { + ObserverNode(const sptr &observer, uint32_t callerTokenId); + sptr observer; + uint32_t callerTokenId; + bool enabled = true; + bool isNotifyOnEnabled = false; + }; + + RdbSubscriberManager() = default; + ConcurrentMap> rdbCache_; + int Notify(const Key &key, int32_t userId, const std::vector &val, const std::string &rdbDir, + int rdbVersion); + int GetEnableObserverCount(const Key &key); + void SetObserverNotifyOnEnabled(std::vector &nodes); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/kvdb/auth_delegate.cpp b/services/distributeddataservice/service/kvdb/auth_delegate.cpp index b768416e16a387805d62fd4d2760353b6fcd4545..c50f1236e7fcc67a7406fdc3a0c26aef0efe1e67 100644 --- a/services/distributeddataservice/service/kvdb/auth_delegate.cpp +++ b/services/distributeddataservice/service/kvdb/auth_delegate.cpp @@ -32,7 +32,7 @@ public: int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) override; private: - bool IsUserActive(const std::vector &userStatus, int32_t userId); + bool IsUserActive(const std::vector &users, int32_t userId); static constexpr pid_t UID_CAPACITY = 10000; static constexpr int SYSTEM_USER = 0; }; diff --git a/services/distributeddataservice/service/kvdb/kvdb_exporter.cpp b/services/distributeddataservice/service/kvdb/kvdb_exporter.cpp index 4b0c2e7f5c4824e26b34402bf3c9572e5941675d..22532d531bef560b3dfcfefd1a3a1b811595b40c 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_exporter.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_exporter.cpp @@ -16,7 +16,7 @@ #include "kvdb_exporter.h" #include "backup_manager.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "log_print.h" #include "reporter.h" #include "store_cache.h" diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 8428cb58d63598b95eb56cdf3913afef3ee6dd46..40a4709ab77e4bc00ee0ea14f8ed5adf098b1515 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -26,15 +26,15 @@ #include "communication_strategy.h" #include "crypto_manager.h" #include "device_manager_adapter.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "eventcenter/event_center.h" #include "ipc_skeleton.h" #include "log_print.h" #include "matrix_event.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" -#include "query_helper.h" #include "permit_delegate.h" +#include "query_helper.h" #include "upgrade.h" #include "utils/anonymous.h" #include "utils/constant.h" @@ -70,7 +70,7 @@ KVDBServiceImpl::KVDBServiceImpl() EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_META_FINISHED, [this](const Event &event) { auto &matrixEvent = static_cast(event); auto deviceId = matrixEvent.GetDeviceId(); - RefCount refCount([deviceId] { DMAdapter::GetInstance().NotifyReadyEvent(deviceId); }); + auto refCount = matrixEvent.StealRefCount(); std::vector metaData; auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid }); if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { @@ -99,7 +99,8 @@ KVDBServiceImpl::KVDBServiceImpl() if (policy.IsValueEffect()) { syncInfo.delay = policy.valueUint; } - ZLOGI("[online] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), data.storeId.c_str()); + ZLOGI("[online] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), + Anonymous::Change(data.storeId).c_str()); auto delay = GetSyncDelayTime(syncInfo.delay, { data.storeId }); KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(data.tokenId), delay, std::bind(&KVDBServiceImpl::DoSync, this, data, syncInfo, std::placeholders::_1, ACTION_SYNC), @@ -154,8 +155,8 @@ Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId) MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true); PermitDelegate::GetInstance().DelCache(metaData.GetKey()); storeCache_.CloseStore(tokenId, storeId); - ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), storeId.storeId.c_str(), - metaData.instanceId); + ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId); return SUCCESS; } @@ -170,7 +171,7 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const S MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyLocal(), localMeta, true); if (!localMeta.HasPolicy(IMMEDIATE_SYNC_ON_CHANGE)) { ZLOGW("appId:%{public}s storeId:%{public}s no IMMEDIATE_SYNC_ON_CHANGE ", appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return Status::SUCCESS; } } @@ -306,8 +307,8 @@ Status KVDBServiceImpl::RmvSubscribeInfo(const AppId &appId, const StoreId &stor Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) { auto tokenId = IPCSkeleton::GetCallingTokenID(); - ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(), storeId.storeId.c_str(), - tokenId); + ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str(), tokenId); syncAgents_.Compute(tokenId, [&appId, &storeId, &observer](auto &key, SyncAgent &value) { if (value.pid_ != IPCSkeleton::GetCallingPid()) { value.ReInit(IPCSkeleton::GetCallingPid(), appId); @@ -327,8 +328,8 @@ Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sp Status KVDBServiceImpl::Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) { auto tokenId = IPCSkeleton::GetCallingTokenID(); - ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(), storeId.storeId.c_str(), - tokenId); + ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str(), tokenId); syncAgents_.ComputeIfPresent(tokenId, [&appId, &storeId, &observer](auto &key, SyncAgent &value) { if (value.pid_ != IPCSkeleton::GetCallingPid()) { ZLOGW("agent already changed! old pid:%{public}d new pid:%{public}d appId:%{public}s", @@ -352,7 +353,8 @@ Status KVDBServiceImpl::GetBackupPassword(const AppId &appId, const StoreId &sto Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) { - ZLOGD("appId:%{public}s storeId:%{public}s to export data", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGD("appId:%{public}s storeId:%{public}s to export data", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); StoreMetaData meta = GetStoreMetaData(appId, storeId); AddOptions(options, meta); @@ -365,8 +367,8 @@ Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, old.area != meta.area || !options.persistent) { ZLOGE("meta appId:%{public}s storeId:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " "area:%{public}d->%{public}d persistent:%{public}d", - appId.appId.c_str(), storeId.storeId.c_str(), old.storeType, meta.storeType, old.isEncrypt, meta.isEncrypt, - old.area, meta.area, options.persistent); + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.storeType, meta.storeType, + old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent); return Status::STORE_META_CHANGED; } @@ -382,7 +384,7 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, { if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType()) { ZLOGE("failed please check type:%{public}d appId:%{public}s storeId:%{public}s", options.kvStoreType, - appId.appId.c_str(), storeId.storeId.c_str()); + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); return INVALID_ARGUMENT; } @@ -396,8 +398,8 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, auto dbStatus = Upgrade::GetInstance().UpdateStore(oldMeta, metaData, password); ZLOGI("update status:%{public}d appId:%{public}s storeId:%{public}s inst:%{public}d " "type:%{public}d->%{public}d dir:%{public}s", - dbStatus, appId.appId.c_str(), storeId.storeId.c_str(), metaData.instanceId, oldMeta.storeType, - metaData.storeType, metaData.dataDir.c_str()); + dbStatus, appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId, + oldMeta.storeType, metaData.storeType, metaData.dataDir.c_str()); if (dbStatus != DBStatus::OK) { status = STORE_UPGRADE_FAILED; } @@ -413,7 +415,7 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, SaveLocalMetaData(options, metaData); Upgrade::GetInstance().UpdatePassword(metaData, password); ZLOGI("appId:%{public}s storeId:%{public}s instanceId:%{public}d type:%{public}d dir:%{public}s", - appId.appId.c_str(), storeId.storeId.c_str(), metaData.instanceId, metaData.storeType, + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId, metaData.storeType, metaData.dataDir.c_str()); return status; } @@ -442,7 +444,7 @@ int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) { ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), - param.appId.c_str(), param.storeId.c_str(), Anonymous::Change(identifier).c_str()); + param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(identifier).c_str()); std::vector metaData; auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid, param.userId }); if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { @@ -462,7 +464,8 @@ int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaun auto observers = GetObservers(storeMeta.tokenId, storeMeta.storeId); ZLOGD("user:%{public}s appId:%{public}s storeId:%{public}s observers:%{public}zu", storeMeta.user.c_str(), - storeMeta.bundleName.c_str(), storeMeta.storeId.c_str(), (observers) ? observers->size() : size_t(0)); + storeMeta.bundleName.c_str(), Anonymous::Change(storeMeta.storeId).c_str(), + (observers) ? observers->size() : size_t(0)); DBStatus status; storeCache_.GetStore(storeMeta, observers, status); } @@ -593,11 +596,11 @@ int32_t KVDBServiceImpl::GetInstIndex(uint32_t tokenId, const AppId &appId) Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type) { ZLOGD("seqId:0x%{public}" PRIx64 " type:%{public}d remote:%{public}zu appId:%{public}s storeId:%{public}s", - info.seqId, type, info.devices.size(), meta.bundleName.c_str(), meta.storeId.c_str()); + info.seqId, type, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); auto uuids = ConvertDevices(info.devices); if (uuids.empty()) { ZLOGW("no device online seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", - info.seqId, info.devices.size(), meta.bundleName.c_str(), meta.storeId.c_str()); + info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); return Status::ERROR; } @@ -606,7 +609,7 @@ Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, auto store = storeCache_.GetStore(meta, observers, status); if (store == nullptr) { ZLOGE("failed! status:%{public}d appId:%{public}s storeId:%{public}s dir:%{public}s", status, - meta.bundleName.c_str(), meta.storeId.c_str(), meta.dataDir.c_str()); + meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), meta.dataDir.c_str()); return ConvertDbStatus(status); } bool isSuccess = false; @@ -782,7 +785,7 @@ size_t KVDBServiceImpl::GetSyncDataSize(const std::string &deviceId) auto store = storeCache_.GetStore(data, observers, status); if (store == nullptr) { ZLOGE("failed! status:%{public}d appId:%{public}s storeId:%{public}s dir:%{public}s", status, - data.bundleName.c_str(), data.storeId.c_str(), data.dataDir.c_str()); + data.bundleName.c_str(), Anonymous::Change(data.storeId).c_str(), data.dataDir.c_str()); continue; } totalSize += store->GetSyncDataSize(deviceId); @@ -790,12 +793,11 @@ size_t KVDBServiceImpl::GetSyncDataSize(const std::string &deviceId) return totalSize; } -int32_t KVDBServiceImpl::OnExecutor(std::shared_ptr executors) +int32_t KVDBServiceImpl::OnBind(const BindInfo &bindInfo) { - executors_ = executors; - storeCache_.SetThreadPool(executors); - KvStoreSyncManager::GetInstance()->SetThreadPool(executors); - ZLOGE("onexecutor:%{public}p", executors.get()); + executors_ = bindInfo.executors; + storeCache_.SetThreadPool(bindInfo.executors); + KvStoreSyncManager::GetInstance()->SetThreadPool(bindInfo.executors); return 0; } } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index b1c3e5fd07d5bc8a27e90b74533842cd1d0a64b6..d41b5aade11d249c6e90bbbc88def7aeed87b515 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -26,12 +26,13 @@ #include "metadata/store_meta_data.h" #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" -#include "ref_count.h" +#include "utils/ref_count.h" #include "store_cache.h" namespace OHOS::DistributedKv { class API_EXPORT KVDBServiceImpl final : public KVDBServiceStub { public: using DBLaunchParam = DistributedDB::AutoLaunchParam; + using RefCount = DistributedData::RefCount; API_EXPORT KVDBServiceImpl(); virtual ~KVDBServiceImpl(); Status GetStoreIds(const AppId &appId, std::vector &storeIds) override; @@ -53,7 +54,7 @@ public: Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; - int32_t OnExecutor(std::shared_ptr executors) override; + int32_t OnBind(const BindInfo &bindInfo) override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 61fdde59d2b3d0c3df0b738173138307d6a6a7ec..1da51ce462fb7232c9cd535dba3ad376547de188 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -20,9 +20,11 @@ #include "itypes_util.h" #include "log_print.h" #include "utils/constant.h" +#include "utils/anonymous.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; -const KVDBServiceStub::Handler KVDBServiceStub::HANDLERS[TRANS_BUTT] = { +const KVDBServiceStub::Handler + KVDBServiceStub::HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)] = { &KVDBServiceStub::OnGetStoreIds, &KVDBServiceStub::OnBeforeCreate, &KVDBServiceStub::OnAfterCreate, @@ -52,15 +54,18 @@ int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return -1; } - if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] == nullptr) { - ZLOGE("not support code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT); + if (static_cast(KVDBServiceInterfaceCode::TRANS_HEAD) > code || + code >= static_cast(KVDBServiceInterfaceCode::TRANS_BUTT) || HANDLERS[code] == nullptr) { + ZLOGE("not support code:%{public}u, BUTT:%{public}d", code, + static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)); return -1; } AppId appId; StoreId storeId; if (!ITypesUtil::Unmarshal(data, appId, storeId)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } appId.appId = Constant::TrimCopy(appId.appId); @@ -75,11 +80,11 @@ int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return (this->*HANDLERS[code])(appId, storeId, data, reply); } ZLOGE("PERMISSION_DENIED uid:%{public}d appId:%{public}s storeId:%{public}s", info.uid, info.bundleName.c_str(), - info.storeId.c_str()); + Anonymous::Change(info.storeId).c_str()); if (!ITypesUtil::Marshal(reply, static_cast(PERMISSION_DENIED))) { ZLOGE("Marshal PERMISSION_DENIED code:%{public}u appId:%{public}s storeId:%{public}s", code, - appId.appId.c_str(), storeId.storeId.c_str()); + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -102,13 +107,14 @@ int32_t KVDBServiceStub::OnBeforeCreate( { Options options; if (!ITypesUtil::Unmarshal(data, options)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = BeforeCreate(appId, storeId, options); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -120,14 +126,15 @@ int32_t KVDBServiceStub::OnAfterCreate( Options options; std::vector password; if (!ITypesUtil::Unmarshal(data, options, password)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = AfterCreate(appId, storeId, options, password); password.assign(password.size(), 0); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -138,7 +145,7 @@ int32_t KVDBServiceStub::OnDelete(const AppId &appId, const StoreId &storeId, Me int32_t status = Delete(appId, storeId); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -148,13 +155,14 @@ int32_t KVDBServiceStub::OnSync(const AppId &appId, const StoreId &storeId, Mess { SyncInfo syncInfo; if (!ITypesUtil::Unmarshal(data, syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = Sync(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -165,14 +173,15 @@ int32_t KVDBServiceStub::OnRegisterCallback( { sptr remoteObj; if (!ITypesUtil::Unmarshal(data, remoteObj)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } auto syncCallback = (remoteObj == nullptr) ? nullptr : iface_cast(remoteObj); int32_t status = RegisterSyncCallback(appId, syncCallback); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -184,7 +193,7 @@ int32_t KVDBServiceStub::OnUnregisterCallback( int32_t status = UnregisterSyncCallback(appId); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -195,13 +204,14 @@ int32_t KVDBServiceStub::OnSetSyncParam( { KvSyncParam syncParam; if (!ITypesUtil::Unmarshal(data, syncParam.allowedDelayMs)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = SetSyncParam(appId, storeId, syncParam); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -214,7 +224,7 @@ int32_t KVDBServiceStub::OnGetSyncParam( int32_t status = GetSyncParam(appId, storeId, syncParam); if (!ITypesUtil::Marshal(reply, status, syncParam.allowedDelayMs)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -226,7 +236,7 @@ int32_t KVDBServiceStub::OnEnableCap( int32_t status = EnableCapability(appId, storeId); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -238,7 +248,7 @@ int32_t KVDBServiceStub::OnDisableCap( int32_t status = DisableCapability(appId, storeId); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -250,13 +260,14 @@ int32_t KVDBServiceStub::OnSetCapability( std::vector local; std::vector remote; if (!ITypesUtil::Unmarshal(data, local, remote)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = SetCapability(appId, storeId, local, remote); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -267,13 +278,14 @@ int32_t KVDBServiceStub::OnAddSubInfo(const AppId &appId, const StoreId &storeId { SyncInfo syncInfo; if (!ITypesUtil::Unmarshal(data, syncInfo.seqId, syncInfo.devices, syncInfo.query)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = AddSubscribeInfo(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -284,13 +296,14 @@ int32_t KVDBServiceStub::OnRmvSubInfo(const AppId &appId, const StoreId &storeId { SyncInfo syncInfo; if (!ITypesUtil::Unmarshal(data, syncInfo.seqId, syncInfo.devices, syncInfo.query)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } int32_t status = RmvSubscribeInfo(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -301,14 +314,15 @@ int32_t KVDBServiceStub::OnSubscribe( { sptr remoteObj; if (!ITypesUtil::Unmarshal(data, remoteObj)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } auto observer = (remoteObj == nullptr) ? nullptr : iface_cast(remoteObj); int32_t status = Subscribe(appId, storeId, observer); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -319,14 +333,15 @@ int32_t KVDBServiceStub::OnUnsubscribe( { sptr remoteObj; if (!ITypesUtil::Unmarshal(data, remoteObj)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } auto observer = (remoteObj == nullptr) ? nullptr : iface_cast(remoteObj); int32_t status = Unsubscribe(appId, storeId, observer); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -339,7 +354,7 @@ int32_t KVDBServiceStub::OnGetBackupPassword( int32_t status = GetBackupPassword(appId, storeId, password); if (!ITypesUtil::Marshal(reply, status, password)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), - storeId.storeId.c_str()); + Anonymous::Change(storeId.storeId).c_str()); password.assign(password.size(), 0); return IPC_STUB_WRITE_PARCEL_ERR; } diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index ab0bacc494d2e6df8019b6a077d2e563102f7c99..00b1763def44b6c8f646ad4139525b3046e34129 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_STUB_H #define OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_STUB_H +#include "distributeddata_kvdb_ipc_interface_code.h" #include "iremote_stub.h" #include "kvdb_service.h" #include "feature/feature_system.h" @@ -43,7 +44,7 @@ private: int32_t OnSubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnUnsubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetBackupPassword(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - static const Handler HANDLERS[TRANS_BUTT]; + static const Handler HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)]; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_STUB_H diff --git a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h index bad171c5225e9d53b30e808a38fa3afd9e4a3ee9..4f4fc19d2d83237e6cc5d208515a631ed9b8eed3 100644 --- a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h +++ b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h @@ -62,9 +62,9 @@ private: uint32_t DoRemoveSyncingOp(OpPred pred, std::list &syncingOps); Status RemoveSyncingOp(uint32_t opSeq, std::list &syncingOps); void AddTimer(const TimePoint &expireTime); - bool GetTimeoutSyncOps(const TimePoint &time, std::list &syncOps); + bool GetTimeoutSyncOps(const TimePoint ¤tTime, std::list &syncOps); void DoCheckSyncingTimeout(std::list &syncingOps); - void Schedule(const TimePoint &expireTime); + void Schedule(const TimePoint &time); static constexpr uint32_t SYNCING_TIMEOUT_MS = 5000; static constexpr uint32_t REALTIME_PRIOR_SYNCING_MS = 300; diff --git a/services/distributeddataservice/service/kvdb/store_cache.cpp b/services/distributeddataservice/service/kvdb/store_cache.cpp index 093e8e5a9fc95f3868e8045149114ef34123ae01..3f9059e8a73a4af629f9096d75af88e72b2192d6 100644 --- a/services/distributeddataservice/service/kvdb/store_cache.cpp +++ b/services/distributeddataservice/service/kvdb/store_cache.cpp @@ -14,14 +14,16 @@ */ #define LOG_TAG "StoreCache" #include "store_cache.h" + #include "account/account_delegate.h" #include "crypto_manager.h" #include "device_matrix.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" #include "types.h" +#include "utils/anonymous.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; constexpr int64_t StoreCache::INTERVAL; @@ -104,7 +106,7 @@ void StoreCache::CloseExcept(const std::set &users) void StoreCache::SetObserver(uint32_t tokenId, const std::string &storeId, std::shared_ptr observers) { stores_.ComputeIfPresent(tokenId, [&storeId, &observers](auto &key, auto &stores) { - ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, storeId.c_str(), + ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, Anonymous::Change(storeId).c_str(), observers ? observers->size() : size_t(0)); auto it = stores.find(storeId); if (it != stores.end()) { @@ -197,9 +199,8 @@ void StoreCache::SetThreadPool(std::shared_ptr executors) } StoreCache::DBStoreDelegate::DBStoreDelegate(DBStore *delegate, std::shared_ptr observers) - : delegate_(delegate) + : time_(std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL)), delegate_(delegate) { - time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); SetObservers(std::move(observers)); } @@ -234,13 +235,12 @@ bool StoreCache::DBStoreDelegate::Close(DBManager &manager) std::unique_lock lock(mutex_); if (delegate_ != nullptr) { delegate_->UnRegisterObserver(this); + auto status = manager.CloseKvStore(delegate_); + if (status == DBStatus::BUSY) { + return false; + } + delegate_ = nullptr; } - - auto status = manager.CloseKvStore(delegate_); - if (status == DBStatus::BUSY) { - return false; - } - delegate_ = nullptr; return true; } diff --git a/services/distributeddataservice/service/kvdb/store_cache.h b/services/distributeddataservice/service/kvdb/store_cache.h index 2e4d726c32ef6bfeec899e8192ccf5e1573a8674..37e5133df94fb707a77a3556d45201224feac7a2 100644 --- a/services/distributeddataservice/service/kvdb/store_cache.h +++ b/services/distributeddataservice/service/kvdb/store_cache.h @@ -33,9 +33,9 @@ public: template struct Less { public: - bool operator()(const sptr &__x, const sptr &__y) const + bool operator()(const sptr &x, const sptr &y) const { - return __x.GetRefPtr() < __y.GetRefPtr(); + return x.GetRefPtr() < y.GetRefPtr(); } }; using DBStatus = DistributedDB::DBStatus; diff --git a/services/distributeddataservice/service/kvdb/upgrade.cpp b/services/distributeddataservice/service/kvdb/upgrade.cpp index ea40a6bd1de21eb555e09ba4afd6e0cc2c881c91..38a370e880cf26addc7d16d8ba3011fc5aae2721 100644 --- a/services/distributeddataservice/service/kvdb/upgrade.cpp +++ b/services/distributeddataservice/service/kvdb/upgrade.cpp @@ -18,14 +18,14 @@ #include #include +#include "accesstoken_kit.h" #include "crypto_manager.h" -#include "metadata/secret_key_meta_data.h" #include "device_manager_adapter.h" +#include "directory/directory_manager.h" #include "log_print.h" #include "metadata/meta_data_manager.h" +#include "metadata/secret_key_meta_data.h" #include "store_cache.h" -#include "accesstoken_kit.h" -#include "directory_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; using system_clock = std::chrono::system_clock; diff --git a/services/distributeddataservice/service/kvdb/upgrade.h b/services/distributeddataservice/service/kvdb/upgrade.h index b6d83b02d7fcc8b1b20e66c31d15f559f8cd24c0..5e98238026688e45db76f2bbcda2dd5d4b8fca7f 100644 --- a/services/distributeddataservice/service/kvdb/upgrade.h +++ b/services/distributeddataservice/service/kvdb/upgrade.h @@ -39,7 +39,7 @@ public: API_EXPORT bool RegisterExporter(uint32_t version, Exporter exporter); API_EXPORT bool RegisterCleaner(uint32_t version, Cleaner cleaner); - DBStatus UpdateStore(const StoreMeta &old, const StoreMeta &metaData, const std::vector &pwd); + DBStatus UpdateStore(const StoreMeta &old, const StoreMeta &meta, const std::vector &pwd); DBStatus ExportStore(const StoreMeta &old, const StoreMeta &meta); void UpdatePassword(const StoreMeta &meta, const std::vector &password); DBStatus UpdateUuid(const StoreMeta &old, const StoreMeta &meta, const std::vector &pwd); diff --git a/services/distributeddataservice/service/kvdb/user_delegate.cpp b/services/distributeddataservice/service/kvdb/user_delegate.cpp index 2cd03d0fdfccc7d58c1ceb176695b4d2b7bd6b19..1d245bf96de5112df8ee5f4515f4cc04b4fdfa0b 100644 --- a/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -26,12 +26,7 @@ namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; std::string GetLocalDeviceId() { - static std::string deviceId; - if (deviceId.empty()) { - deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; - } - - return deviceId; + return DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; } std::vector UserDelegate::GetLocalUserStatus() diff --git a/services/distributeddataservice/service/matrix/include/device_matrix.h b/services/distributeddataservice/service/matrix/include/device_matrix.h index c04223aa48429ebb33f23d63c88b4be049c671b3..4298f3b6301a90cf989dccb4c1ed0394f267c600 100644 --- a/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -20,6 +20,7 @@ #include "lru_bucket.h" #include "metadata/matrix_meta_data.h" #include "metadata/store_meta_data.h" +#include "utils/ref_count.h" #include "visibility.h" namespace OHOS::DistributedData { class API_EXPORT DeviceMatrix { @@ -34,7 +35,7 @@ public: }; static DeviceMatrix &GetInstance(); bool Initialize(uint32_t token, std::string storeId); - void Online(const std::string &device); + void Online(const std::string &device, RefCount refCount = {}); void Offline(const std::string &device); uint16_t OnBroadcast(const std::string &device, uint16_t code); void OnChanged(uint16_t code); diff --git a/services/distributeddataservice/service/matrix/include/matrix_event.h b/services/distributeddataservice/service/matrix/include/matrix_event.h index e6e9b471368303ee33bf59eedfbdf3169f5a1cc1..e44f82058c300ed1627c095632d937abb0933c94 100644 --- a/services/distributeddataservice/service/matrix/include/matrix_event.h +++ b/services/distributeddataservice/service/matrix/include/matrix_event.h @@ -18,6 +18,7 @@ #include #include "eventcenter/event.h" +#include "utils/ref_count.h" #include "visibility.h" namespace OHOS::DistributedData { class API_EXPORT MatrixEvent : public Event { @@ -26,11 +27,14 @@ public: ~MatrixEvent() = default; uint16_t GetMask() const; std::string GetDeviceId() const; + void SetRefCount(RefCount refCount); + RefCount StealRefCount() const; bool Equals(const Event &event) const override; private: uint16_t mask_; std::string deviceId_; + mutable RefCount refCount_; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_MATRIX_EVENT_H diff --git a/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/services/distributeddataservice/service/matrix/src/device_matrix.cpp index 2217be08db9564cf094f1f2a0997a6ce0b009401..d4db69a1e2460bbdd2944ca399a1f8b92cb2e727 100644 --- a/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -72,7 +72,7 @@ bool DeviceMatrix::Initialize(uint32_t token, std::string storeId) return MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta); } -void DeviceMatrix::Online(const std::string &device) +void DeviceMatrix::Online(const std::string &device, RefCount refCount) { Mask mask; EventCenter::Defer defer; @@ -84,7 +84,9 @@ void DeviceMatrix::Online(const std::string &device) } onLines_.insert_or_assign(device, mask); if (mask.bitset != 0) { - EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_ONLINE, device, mask.bitset)); + auto evt = std::make_unique(MATRIX_ONLINE, device, mask.bitset); + evt->SetRefCount(std::move(refCount)); + EventCenter::GetInstance().PostEvent(std::move(evt)); } } @@ -217,7 +219,7 @@ uint16_t DeviceMatrix::ConvertMask(const std::string &device, uint16_t code) if (index >= meta.maskInfo.size()) { return result; } - auto &app = meta.maskInfo[index]; + const auto &app = meta.maskInfo[index]; for (size_t i = 0; i < maskApps_.size(); i++) { if (maskApps_[i] == app) { result |= SetMask(i); diff --git a/services/distributeddataservice/service/matrix/src/matrix_event.cpp b/services/distributeddataservice/service/matrix/src/matrix_event.cpp index b61a0caf17624b4eb4cb47147d2c64ed78d049b1..d7ce1c13b2532eb1443b847dd7f009c6ccfd9b92 100644 --- a/services/distributeddataservice/service/matrix/src/matrix_event.cpp +++ b/services/distributeddataservice/service/matrix/src/matrix_event.cpp @@ -34,4 +34,14 @@ bool MatrixEvent::Equals(const Event &event) const auto &evt = static_cast(event); return (deviceId_ == evt.deviceId_) && (mask_ == evt.mask_); } + +void MatrixEvent::SetRefCount(RefCount refCount) +{ + refCount_ = std::move(refCount); +} + +RefCount MatrixEvent::StealRefCount() const +{ + return std::move(refCount_); +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/service/object/object_callback_proxy.cpp b/services/distributeddataservice/service/object/object_callback_proxy.cpp index 4e88e7dce83684e049018e69dbdc6538cf874ac2..0eb7942b539dbb8a7adea41a04a586daa1443a4f 100644 --- a/services/distributeddataservice/service/object/object_callback_proxy.cpp +++ b/services/distributeddataservice/service/object/object_callback_proxy.cpp @@ -15,8 +15,8 @@ #define LOG_TAG "IObjectCallbackProxy" #include "object_callback_proxy.h" -#include -#include + +#include "ipc_skeleton.h" #include "itypes_util.h" #include "log_print.h" diff --git a/services/distributeddataservice/service/object/object_service_impl.cpp b/services/distributeddataservice/service/object/object_service_impl.cpp index 7ae417c363f1e5259c4a22870fec4317cb12e00c..55464231a35590e9640db201f01097f2ffe1a7f8 100644 --- a/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/services/distributeddataservice/service/object/object_service_impl.cpp @@ -23,7 +23,7 @@ #include "bootstrap.h" #include "checker/checker_manager.h" #include "device_manager_adapter.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" @@ -112,7 +112,8 @@ int32_t ObjectServiceImpl::OnInitialize() if (!saved) { ZLOGE("Save appIdMeta failed"); } - ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", saveMeta.appId.c_str(), saveMeta.storeId.c_str()); + ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", + saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str()); return OBJECT_SUCCESS; } @@ -235,7 +236,8 @@ int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, Dist { ZLOGI("ObjectServiceImpl::ResolveAutoLaunch start"); ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), - param.appId.c_str(), param.storeId.c_str(), DistributedData::Anonymous::Change(identifier).c_str()); + param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(), + DistributedData::Anonymous::Change(identifier).c_str()); std::vector metaData; auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid, param.userId }); if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { @@ -277,9 +279,11 @@ int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, con ObjectServiceImpl::ObjectServiceImpl() { } -int32_t ObjectServiceImpl::OnExecutor(std::shared_ptr executors) + +int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo) { - executors_ = executors; + executors_ = bindInfo.executors; + ObjectStoreManager::GetInstance()->SetThreadPool(executors_); return 0; } } // namespace OHOS::DistributedObject diff --git a/services/distributeddataservice/service/object/object_service_impl.h b/services/distributeddataservice/service/object/object_service_impl.h index 932ea29afd3d15abfd8ca6e4cbb55789858c9589..5206481e6bc074b5c99349ec20cccc2ad2b5e1fd 100644 --- a/services/distributeddataservice/service/object/object_service_impl.h +++ b/services/distributeddataservice/service/object/object_service_impl.h @@ -42,9 +42,9 @@ public: int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; int32_t OnInitialize() override; - int32_t OnExecutor(std::shared_ptr executors) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; + int32_t OnBind(const BindInfo &bindInfo) override; private: class Factory { diff --git a/services/distributeddataservice/service/object/object_service_stub.cpp b/services/distributeddataservice/service/object/object_service_stub.cpp index 9a5281bfed6fb4a1598df12a124a81cf61514e7c..a97dd72dcb1c1b940a9fb8b3a202b545fe9821d6 100644 --- a/services/distributeddataservice/service/object/object_service_stub.cpp +++ b/services/distributeddataservice/service/object/object_service_stub.cpp @@ -150,7 +150,7 @@ int ObjectServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Messa if (!CheckInterfaceToken(data)) { return -1; } - if (code >= 0 && code < OBJECTSTORE_SERVICE_CMD_MAX) { + if (code >= 0 && code < static_cast(ObjectCode::OBJECTSTORE_SERVICE_CMD_MAX)) { return (this->*HANDLERS[code])(data, reply); } return -1; diff --git a/services/distributeddataservice/service/object/object_service_stub.h b/services/distributeddataservice/service/object/object_service_stub.h index c3e319fa5f0912b1a277bf61209985e471fb6bdf..6acd6c758867dddc9057be907bfa8a049fc15d76 100644 --- a/services/distributeddataservice/service/object/object_service_stub.h +++ b/services/distributeddataservice/service/object/object_service_stub.h @@ -20,6 +20,8 @@ #include "iobject_service.h" #include "feature/feature_system.h" namespace OHOS::DistributedObject { +using ObjectCode = ObjectStoreService::ObjectServiceInterfaceCode; + class ObjectServiceStub : public ObjectService, public DistributedData::FeatureSystem::Feature { public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; @@ -33,7 +35,7 @@ private: int32_t OnUnsubscribeRequest(MessageParcel &data, MessageParcel &reply); using RequestHandle = int (ObjectServiceStub::*)(MessageParcel &, MessageParcel &); - static constexpr RequestHandle HANDLERS[OBJECTSTORE_SERVICE_CMD_MAX] = { + static constexpr RequestHandle HANDLERS[static_cast(ObjectCode::OBJECTSTORE_SERVICE_CMD_MAX)] = { &ObjectServiceStub::ObjectStoreSaveOnRemote, &ObjectServiceStub::ObjectStoreRevokeSaveOnRemote, &ObjectServiceStub::ObjectStoreRetrieveOnRemote, diff --git a/services/distributeddataservice/service/permission/src/permit_delegate.cpp b/services/distributeddataservice/service/permission/src/permit_delegate.cpp index 7a4bd29e6d157103362ab5adc9d3c80deb3e8a14..52b9af7c4e4c59c0c06f9c8d3c555f601a40d843 100644 --- a/services/distributeddataservice/service/permission/src/permit_delegate.cpp +++ b/services/distributeddataservice/service/permission/src/permit_delegate.cpp @@ -79,7 +79,7 @@ bool PermitDelegate::SyncActivate(const ActiveParam ¶m) bool PermitDelegate::VerifyPermission(const CheckParam ¶m, uint8_t flag) { ZLOGI("user:%{public}s, appId:%{public}s, storeId:%{public}s, remote devId:%{public}s, instanceId:%{public}d," - "flag:%{public}u", param.userId.c_str(), param.appId.c_str(), param.storeId.c_str(), + "flag:%{public}u", param.userId.c_str(), param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(param.deviceId).c_str(), param.instanceId, flag); auto devId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; diff --git a/services/distributeddataservice/service/kvdb/executor_factory.cpp b/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp similarity index 35% rename from services/distributeddataservice/service/kvdb/executor_factory.cpp rename to services/distributeddataservice/service/rdb/rdb_asset_loader.cpp index 4d4385625599c2efc7d444a1f8c7027ce209f60d..5612e8a9bafcf02a07d8329588185cd9960ad1b5 100644 --- a/services/distributeddataservice/service/kvdb/executor_factory.cpp +++ b/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022 Huawei Device Co., Ltd. +* Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,35 +12,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "executor_factory.h" -namespace OHOS::DistributedData { -using namespace OHOS::DistributedKv; -ExecutorFactory &ExecutorFactory::GetInstance() -{ - static ExecutorFactory instance; - return instance; -} +#define LOG_TAG "RdbAssetLoader" +#include "rdb_asset_loader.h" -bool ExecutorFactory::Execute(KvStoreTask &&task) -{ - if (threadPool_ == nullptr) { - return false; - } - threadPool_->AddTask(std::move(task)); - return true; -} +#include "error/general_error.h" +#include "log_print.h" +#include "rdb_cloud.h" +#include "value_proxy.h" -ExecutorFactory::ExecutorFactory() +using namespace DistributedDB; +namespace OHOS::DistributedRdb { +RdbAssetLoader::RdbAssetLoader(std::shared_ptr cloudAssetLoader) + : assetLoader_(std::move(cloudAssetLoader)) { - threadPool_ = KvStoreThreadPool::GetPool(POOL_SIZE, "Executor", true); } -ExecutorFactory::~ExecutorFactory() +DBStatus RdbAssetLoader::Download(const std::string &tableName, const std::string &gid, const Type &prefix, + std::map &assets) { - if (threadPool_ != nullptr) { - threadPool_->Stop(); - threadPool_ = nullptr; + DistributedData::VBucket downLoadAssets = ValueProxy::Convert(assets); + DistributedDB::Type prefixTemp = prefix; + auto error = assetLoader_->Download(tableName, gid, ValueProxy::Convert(std::move(prefixTemp)), downLoadAssets); + if (error == DistributedData::GeneralError::E_OK) { + assets = ValueProxy::Convert(std::move(downLoadAssets)); } + return RdbCloud::ConvertStatus(static_cast(error)); } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_asset_loader.h b/services/distributeddataservice/service/rdb/rdb_asset_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..0197afbf918a03959532e35e23a0aec3de34fe18 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_asset_loader.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H + +#include "cloud/asset_loader.h" +#include "cloud/cloud_store_types.h" +#include "cloud/iAssetLoader.h" +#include "error/general_error.h" + +namespace OHOS::DistributedRdb { +class RdbAssetLoader : public DistributedDB::IAssetLoader { +public: + using Type = DistributedDB::Type; + using Asset = DistributedDB::Asset; + using DBStatus = DistributedDB::DBStatus; + explicit RdbAssetLoader(std::shared_ptr cloudAssetLoader); + + ~RdbAssetLoader() = default; + + DBStatus Download(const std::string &tableName, const std::string &gid, const Type &prefix, + std::map> &assets) override; + +private: + DBStatus ConvertStatus(DistributedData::GeneralError error); + + std::shared_ptr assetLoader_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/services/distributeddataservice/service/rdb/rdb_cloud.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e41b7664a3a4e6fec985eef11b3dab0c81c5d730 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -0,0 +1,135 @@ +/* + * 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. + */ + +#define LOG_TAG "RdbCloud" +#include "rdb_cloud.h" + +#include "cloud/schema_meta.h" +#include "log_print.h" +#include "value_proxy.h" +#include "utils/anonymous.h" + +namespace OHOS::DistributedRdb { +using namespace DistributedDB; +using namespace DistributedData; +RdbCloud::RdbCloud(std::shared_ptr cloudDB) + : cloudDB_(std::move(cloudDB)) +{ +} + +DBStatus RdbCloud::BatchInsert( + const std::string &tableName, std::vector &&record, std::vector &extend) +{ + DistributedData::VBuckets extends; + auto error = cloudDB_->BatchInsert(tableName, ValueProxy::Convert(std::move(record)), extends); + if (error == GeneralError::E_OK) { + extend = ValueProxy::Convert(std::move(extends)); + } + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::BatchUpdate( + const std::string &tableName, std::vector &&record, std::vector &extend) +{ + DistributedData::VBuckets extends = ValueProxy::Convert(std::move(extend)); + auto error = cloudDB_->BatchUpdate(tableName, ValueProxy::Convert(std::move(record)), extends); + if (error == GeneralError::E_OK) { + extend = ValueProxy::Convert(std::move(extends)); + } + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::BatchDelete(const std::string &tableName, std::vector &extend) +{ + auto error = cloudDB_->BatchDelete(tableName, ValueProxy::Convert(std::move(extend))); + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::Query(const std::string &tableName, DBVBucket &extend, std::vector &data) +{ + auto cursor = cloudDB_->Query(tableName, ValueProxy::Convert(std::move(extend))); + if (cursor == nullptr) { + ZLOGE("cursor is null, table:%{public}s, extend:%{public}zu", + Anonymous::Change(tableName).c_str(), extend.size()); + return ConvertStatus(static_cast(E_ERROR)); + } + int32_t count = cursor->GetCount(); + data.reserve(count); + auto err = cursor->MoveToFirst(); + while (err == E_OK && count > 0) { + DistributedData::VBucket entry; + err = cursor->GetEntry(entry); + if (err != E_OK) { + break; + } + data.emplace_back(ValueProxy::Convert(std::move(entry))); + err = cursor->MoveToNext(); + count--; + } + DistributedData::Value cursorFlag; + cursor->Get(SchemaMeta::CURSOR_FIELD, cursorFlag); + extend[SchemaMeta::CURSOR_FIELD] = ValueProxy::Convert(std::move(cursorFlag)); + if (cursor->IsEnd()) { + ZLOGD("query end, table:%{public}s", Anonymous::Change(tableName).c_str()); + return DBStatus::QUERY_END; + } + return ConvertStatus(static_cast(err)); +} + +std::pair RdbCloud::Lock() +{ + auto error = cloudDB_->Lock(); + return std::make_pair( // int64_t <-> uint32_t, s <-> ms + ConvertStatus(static_cast(error)), cloudDB_->AliveTime() * TO_MS); +} + +DBStatus RdbCloud::UnLock() +{ + auto error = cloudDB_->Unlock(); + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::HeartBeat() +{ + auto error = cloudDB_->Heartbeat(); + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::Close() +{ + auto error = cloudDB_->Close(); + return ConvertStatus(static_cast(error)); +} + +DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) +{ + switch (error) { + case GeneralError::E_OK: + return DBStatus::OK; + case GeneralError::E_NETWORK_ERROR: + return DBStatus::CLOUD_NETWORK_ERROR; + case GeneralError::E_LOCKED_BY_OTHERS: + return DBStatus::CLOUD_LOCK_ERROR; + case GeneralError::E_RECODE_LIMIT_EXCEEDED: + return DBStatus::CLOUD_FULL_RECORDS; + case GeneralError::E_NO_SPACE_FOR_ASSET: + return DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT; + default: + ZLOGI("error:0x%{public}x", error); + break; + } + return DBStatus::CLOUD_ERROR; +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_cloud.h b/services/distributeddataservice/service/rdb/rdb_cloud.h new file mode 100644 index 0000000000000000000000000000000000000000..161286ea5293657ad1cea77fad1dd9283f63dca6 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H +#include "cloud/cloud_db.h" +#include "cloud/cloud_store_types.h" +#include "cloud/icloud_db.h" +#include "error/general_error.h" + +namespace OHOS::DistributedRdb { +class RdbCloud : public DistributedDB::ICloudDb { +public: + using DBStatus = DistributedDB::DBStatus; + using DBVBucket = DistributedDB::VBucket; + + explicit RdbCloud(std::shared_ptr cloudDB); + virtual ~RdbCloud() = default; + DBStatus BatchInsert(const std::string &tableName, std::vector &&record, + std::vector &extend) override; + DBStatus BatchUpdate(const std::string &tableName, std::vector &&record, + std::vector &extend) override; + DBStatus BatchDelete(const std::string &tableName, std::vector &extend) override; + DBStatus Query(const std::string &tableName, DBVBucket &extend, std::vector &data) override; + std::pair Lock() override; + DBStatus UnLock() override; + DBStatus HeartBeat() override; + DBStatus Close() override; + static DBStatus ConvertStatus(DistributedData::GeneralError error); + +private: + static constexpr int32_t TO_MS = 1000; // s > ms + std::shared_ptr cloudDB_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H diff --git a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f7981f0db5a6f584803042d8efcd29bcfbdd9ac --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp @@ -0,0 +1,177 @@ +/* +* 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 "rdb_cloud_data_translate.h" + +#include "utils/endian_converter.h" +#include "value_proxy.h" + +namespace OHOS::DistributedRdb { +using Asset = DistributedDB::Asset; +using Assets = DistributedDB::Assets; +using DataAsset = NativeRdb::ValueObject::Asset; +using DataAssets = NativeRdb::ValueObject::Assets; +std::vector RdbCloudDataTranslate::AssetToBlob(const Asset &asset) +{ + std::vector rawData; + DataAsset dataAsset = ValueProxy::Asset(asset); + InnerAsset innerAsset(dataAsset); + auto data = Serializable::Marshall(innerAsset); + auto size = DistributedData::HostToNet((uint16_t)data.length()); + auto leMagic = DistributedData::HostToNet(ASSET_MAGIC); + auto magicU8 = reinterpret_cast(const_cast(&leMagic)); + rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSET_MAGIC)); + rawData.insert(rawData.end(), reinterpret_cast(&size), + reinterpret_cast(&size) + sizeof(size)); + rawData.insert(rawData.end(), data.begin(), data.end()); + return rawData; +} + +std::vector RdbCloudDataTranslate::AssetsToBlob(const Assets &assets) +{ + std::vector rawData; + auto num = DistributedData::HostToNet((uint16_t)assets.size()); + auto leMagic = DistributedData::HostToNet(ASSETS_MAGIC); + auto magicU8 = reinterpret_cast(const_cast(&leMagic)); + rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSETS_MAGIC)); + rawData.insert(rawData.end(), reinterpret_cast(&num), reinterpret_cast(&num) + sizeof(num)); + for (auto &asset : assets) { + auto data = AssetToBlob(asset); + rawData.insert(rawData.end(), data.begin(), data.end()); + } + return rawData; +} + +Asset RdbCloudDataTranslate::BlobToAsset(const std::vector &blob) +{ + DataAsset asset; + if (ParserRawData(blob.data(), blob.size(), asset) == 0) { + return {}; + } + return ValueProxy::Convert(asset); +} + +Assets RdbCloudDataTranslate::BlobToAssets(std::vector &blob) +{ + DataAssets assets; + if (ParserRawData(blob.data(), blob.size(), assets) == 0) { + return {}; + } + return ValueProxy::Convert(assets); +} + +size_t RdbCloudDataTranslate::ParserRawData(const uint8_t *data, size_t length, DataAsset &asset) +{ + size_t used = 0; + uint16_t size = 0; + + if (sizeof(ASSET_MAGIC) > length - used) { + return 0; + } + std::vector alignData; + alignData.assign(data, data + sizeof(ASSET_MAGIC)); + used += sizeof(ASSET_MAGIC); + auto hostMagicWord = DistributedData::NetToHost(*(reinterpret_cast(alignData.data()))); + if (hostMagicWord != ASSET_MAGIC) { + return 0; + } + if (sizeof(size) > length - used) { + return 0; + } + alignData.assign(data + used, data + used + sizeof(size)); + used += sizeof(size); + size = DistributedData::NetToHost(*(reinterpret_cast(alignData.data()))); + if (size > length - used) { + return 0; + } + auto rawData = std::string(reinterpret_cast(&data[used]), size); + InnerAsset innerAsset(asset); + if (!innerAsset.Unmarshall(rawData)) { + return 0; + } + used += size; + return used; +} + +size_t RdbCloudDataTranslate::ParserRawData(const uint8_t *data, size_t length, DataAssets &assets) +{ + size_t used = 0; + uint16_t num = 0; + + if (sizeof(ASSETS_MAGIC) > length - used) { + return 0; + } + std::vector alignData; + alignData.assign(data, data + sizeof(ASSETS_MAGIC)); + used += sizeof(ASSETS_MAGIC); + auto hostMagicWord = DistributedData::NetToHost(*(reinterpret_cast(alignData.data()))); + if (hostMagicWord != ASSETS_MAGIC) { + return 0; + } + + if (sizeof(num) > length - used) { + return 0; + } + alignData.assign(data, data + sizeof(num)); + num = DistributedData::NetToHost(*(reinterpret_cast(alignData.data()))); + used += sizeof(num); + uint16_t count = 0; + while (used < length && count < num) { + DataAsset asset; + auto dataLen = ParserRawData(&data[used], length - used, asset); + if (dataLen == 0) { + break; + } + used += dataLen; + assets.push_back(ValueProxy::Convert(asset)); + count++; + } + return used; +} + +bool RdbCloudDataTranslate::InnerAsset::Marshal(OHOS::DistributedData::Serializable::json &node) const +{ + bool ret = true; + ret = SetValue(node[GET_NAME(version)], asset_.version) && ret; + ret = SetValue(node[GET_NAME(status)], asset_.status) && ret; + ret = SetValue(node[GET_NAME(expiresTime)], asset_.expiresTime) && ret; + ret = SetValue(node[GET_NAME(id)], asset_.id) && ret; + ret = SetValue(node[GET_NAME(name)], asset_.name) && ret; + ret = SetValue(node[GET_NAME(uri)], asset_.uri) && ret; + ret = SetValue(node[GET_NAME(path)], asset_.path) && ret; + ret = SetValue(node[GET_NAME(createTime)], asset_.createTime) && ret; + ret = SetValue(node[GET_NAME(modifyTime)], asset_.modifyTime) && ret; + ret = SetValue(node[GET_NAME(size)], asset_.size) && ret; + ret = SetValue(node[GET_NAME(hash)], asset_.hash) && ret; + return ret; +} + +bool RdbCloudDataTranslate::InnerAsset::Unmarshal(const OHOS::DistributedData::Serializable::json &node) +{ + bool ret = true; + ret = GetValue(node, GET_NAME(version), asset_.version) && ret; + ret = GetValue(node, GET_NAME(status), asset_.status) && ret; + ret = GetValue(node, GET_NAME(expiresTime), asset_.expiresTime) && ret; + ret = GetValue(node, GET_NAME(id), asset_.id) && ret; + ret = GetValue(node, GET_NAME(name), asset_.name) && ret; + ret = GetValue(node, GET_NAME(uri), asset_.uri) && ret; + ret = GetValue(node, GET_NAME(path), asset_.path) && ret; + ret = GetValue(node, GET_NAME(createTime), asset_.createTime) && ret; + ret = GetValue(node, GET_NAME(modifyTime), asset_.modifyTime) && ret; + ret = GetValue(node, GET_NAME(size), asset_.size) && ret; + ret = GetValue(node, GET_NAME(hash), asset_.hash) && ret; + return ret; +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h new file mode 100644 index 0000000000000000000000000000000000000000..f4d350432d7e350963794bbc3b2bd584fa4bbc58 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_DATA_TRASLATE_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_DATA_TRASLATE_H + +#include "cloud/icloud_data_translate.h" +#include "serializable/serializable.h" +#include "value_object.h" +namespace OHOS::DistributedRdb { +class RdbCloudDataTranslate : public DistributedDB::ICloudDataTranslate { +public: + using Asset = DistributedDB::Asset; + using Assets = DistributedDB::Assets; + using DataAsset = NativeRdb::ValueObject::Asset; + using DataAssets = NativeRdb::ValueObject::Assets; + RdbCloudDataTranslate() = default; + ~RdbCloudDataTranslate() = default; + std::vector AssetToBlob(const Asset &asset) override; + std::vector AssetsToBlob(const Assets &assets) override; + Asset BlobToAsset(const std::vector &blob) override; + Assets BlobToAssets(std::vector &blob) override; + +private: + using Serializable = DistributedData::Serializable; + + static constexpr const uint32_t ASSET_MAGIC = 0x41534554; + static constexpr const uint32_t ASSETS_MAGIC = 0x41534553; + struct InnerAsset : public Serializable { + DataAsset &asset_; + explicit InnerAsset(DataAsset &asset) : asset_(asset) {} + + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + size_t ParserRawData(const uint8_t *data, size_t length, DataAsset &asset); + size_t ParserRawData(const uint8_t *data, size_t length, DataAssets &assets); +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_DATA_TRASLATE_H diff --git a/services/distributeddataservice/service/rdb/rdb_cursor.cpp b/services/distributeddataservice/service/rdb/rdb_cursor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..619e7d3a7baba2a767f9c41490822216cf0f40b8 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cursor.cpp @@ -0,0 +1,110 @@ +/* + * 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 "rdb_cursor.h" + +#include "rdb_general_store.h" +#include "result_set.h" +#include "value_proxy.h" +namespace OHOS::DistributedRdb { +using namespace OHOS::DistributedData; +RdbCursor::RdbCursor(std::shared_ptr resultSet) + : resultSet_(std::move(resultSet)) +{ +} + +RdbCursor::~RdbCursor() +{ + if (resultSet_) { + resultSet_->Close(); + } + resultSet_ = nullptr; +} + +int32_t RdbCursor::GetColumnNames(std::vector &names) const +{ + return resultSet_->GetAllColumnNames(names); +} + +int32_t RdbCursor::GetColumnName(int32_t col, std::string &name) const +{ + return resultSet_->GetColumnName(col, name); +} + +int32_t RdbCursor::GetColumnType(int32_t col) const +{ + NativeRdb::ColumnType columnType; + resultSet_->GetColumnType(col, columnType); + return int32_t(columnType); +} + +int32_t RdbCursor::GetCount() const +{ + int32_t count = -1; + resultSet_->GetRowCount(count); + return count; +} + +int32_t RdbCursor::MoveToFirst() +{ + return resultSet_->GoToFirstRow(); +} + +int32_t RdbCursor::MoveToNext() +{ + return resultSet_->GoToNextRow(); +} + +int32_t RdbCursor::GetEntry(VBucket &entry) +{ + return GetRow(entry); +} + +int32_t RdbCursor::GetRow(VBucket &data) +{ + NativeRdb::RowEntity bucket; + auto ret = resultSet_->GetRow(bucket); + data = ValueProxy::Convert(NativeRdb::ValuesBucket(bucket.Steal())); + return ret; +} + +int32_t RdbCursor::Get(int32_t col, Value &value) +{ + NativeRdb::ValueObject object; + auto ret = resultSet_->Get(col, object); + value = ValueProxy::Convert(std::move(object)); + return ret; +} + +int32_t RdbCursor::Get(const std::string &col, Value &value) +{ + int32_t index = -1; + auto ret = resultSet_->GetColumnIndex(col, index); + if (ret != NativeRdb::E_OK) { + return ret; + } + return Get(index, value); +} + +int32_t RdbCursor::Close() +{ + return resultSet_->Close(); +} + +bool RdbCursor::IsEnd() +{ + return false; +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_cursor.h b/services/distributeddataservice/service/rdb/rdb_cursor.h new file mode 100644 index 0000000000000000000000000000000000000000..dd184d49edcab33eec31ae8e798db18e77d94c83 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_cursor.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H +#include "store/cursor.h" +#include "result_set.h" +namespace OHOS::DistributedRdb { +class RdbCursor : public DistributedData::Cursor { +public: + explicit RdbCursor(std::shared_ptr resultSet); + ~RdbCursor(); + int32_t GetColumnNames(std::vector &names) const override; + int32_t GetColumnName(int32_t col, std::string &name) const override; + int32_t GetColumnType(int32_t col) const override; + int32_t GetCount() const override; + int32_t MoveToFirst() override; + int32_t MoveToNext() override; + int32_t GetEntry(DistributedData::VBucket &entry) override; + int32_t GetRow(DistributedData::VBucket &data) override; + int32_t Get(int32_t col, DistributedData::Value &value) override; + int32_t Get(const std::string &col, DistributedData::Value &value) override; + int32_t Close() override; + bool IsEnd() override; + +private: + std::shared_ptr resultSet_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H diff --git a/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/services/distributeddataservice/service/rdb/rdb_general_store.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31944ad99a471a1076a18f8d88003b41dfcf4581 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -0,0 +1,397 @@ +/* + * 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. + */ +#define LOG_TAG "RdbGeneralStore" +#include "rdb_general_store.h" +#include "cloud_service.h" +#include "cloud/asset_loader.h" +#include "cloud/cloud_db.h" +#include "cloud/schema_meta.h" +#include "crypto_manager.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "metadata/secret_key_meta_data.h" +#include "rdb_cursor.h" +#include "rdb_helper.h" +#include "rdb_query.h" +#include "rdb_syncer.h" +#include "relational_store_manager.h" +#include "utils/anonymous.h" +#include "value_proxy.h" +namespace OHOS::DistributedRdb { +using namespace DistributedData; +using namespace DistributedDB; +using namespace NativeRdb; +using namespace CloudData; +using DBField = DistributedDB::Field; +using DBTable = DistributedDB::TableSchema; +using DBSchema = DistributedDB::DataBaseSchema; +using ClearMode = DistributedDB::ClearMode; +using DBStatus = DistributedDB::DBStatus; +class RdbOpenCallbackImpl : public RdbOpenCallback { +public: + int OnCreate(RdbStore &rdbStore) override + { + return NativeRdb::E_OK; + } + int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override + { + return NativeRdb::E_OK; + } +}; + +RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) +{ + observer_.storeId_ = meta.storeId; + RelationalStoreDelegate::Option option; + if (meta.isEncrypt) { + std::string key = meta.GetSecretKey(); + SecretKeyMetaData secretKeyMeta; + MetaDataManager::GetInstance().LoadMeta(key, secretKeyMeta, true); + std::vector decryptKey; + CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); + if (option.passwd.SetValue(decryptKey.data(), decryptKey.size()) != CipherPassword::OK) { + std::fill(decryptKey.begin(), decryptKey.end(), 0); + } + std::fill(decryptKey.begin(), decryptKey.end(), 0); + option.isEncryptedDb = meta.isEncrypt; + option.iterateTimes = ITERATE_TIMES; + option.cipher = CipherType::AES_256_GCM; + } + option.observer = &observer_; + manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); +} + +RdbGeneralStore::~RdbGeneralStore() +{ + manager_.CloseStore(delegate_); + delegate_ = nullptr; + store_ = nullptr; + bindInfo_.loader_ = nullptr; + bindInfo_.db_->Close(); + bindInfo_.db_ = nullptr; + rdbCloud_ = nullptr; + rdbLoader_ = nullptr; +} + +int32_t RdbGeneralStore::Bind(const Database &database, BindInfo bindInfo) +{ + if (bindInfo.db_ == nullptr || bindInfo.loader_ == nullptr) { + return GeneralError::E_INVALID_ARGS; + } + + if (isBound_.exchange(true)) { + return GeneralError::E_OK; + } + + bindInfo_ = std::move(bindInfo); + rdbCloud_ = std::make_shared(bindInfo_.db_); + rdbLoader_ = std::make_shared(bindInfo_.loader_); + DBSchema schema; + schema.tables.resize(database.tables.size()); + for (size_t i = 0; i < database.tables.size(); i++) { + const Table &table = database.tables[i]; + DBTable &dbTable = schema.tables[i]; + dbTable.name = table.name; + for (auto &field : table.fields) { + DBField dbField; + dbField.colName = field.colName; + dbField.type = field.type; + dbField.primary = field.primary; + dbField.nullable = field.nullable; + dbTable.fields.push_back(std::move(dbField)); + } + } + std::unique_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database:%{public}s already closed!", Anonymous::Change(database.name).c_str()); + return GeneralError::E_ALREADY_CLOSED; + } + delegate_->SetCloudDB(rdbCloud_); + delegate_->SetIAssetLoader(rdbLoader_); + delegate_->SetCloudDbSchema(std::move(schema)); + return GeneralError::E_OK; +} + +bool RdbGeneralStore::IsBound() +{ + return isBound_; +} + +int32_t RdbGeneralStore::Close() +{ + std::unique_lock lock(rwMutex_); + if (delegate_ == nullptr) { + return 0; + } + auto status = manager_.CloseStore(delegate_); + if (status != DBStatus::OK) { + return status; + } + delegate_ = nullptr; + store_ = nullptr; + bindInfo_.loader_ = nullptr; + bindInfo_.db_->Close(); + bindInfo_.db_ = nullptr; + rdbCloud_ = nullptr; + rdbLoader_ = nullptr; + return 0; +} + +int32_t RdbGeneralStore::Execute(const std::string &table, const std::string &sql) +{ + return GeneralError::E_OK; +} + +int32_t RdbGeneralStore::BatchInsert(const std::string &table, VBuckets &&values) +{ + return 0; +} + +int32_t RdbGeneralStore::BatchUpdate(const std::string &table, const std::string &sql, VBuckets &&values) +{ + return 0; +} + +int32_t RdbGeneralStore::Delete(const std::string &table, const std::string &sql, Values &&args) +{ + return 0; +} + +std::shared_ptr RdbGeneralStore::Query(const std::string &table, const std::string &sql, Values &&args) +{ + return std::shared_ptr(); +} + +std::shared_ptr RdbGeneralStore::Query(const std::string &table, GenQuery &query) +{ + return std::shared_ptr(); +} + +int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &query, DetailAsync async, int32_t wait) +{ + DistributedDB::Query dbQuery; + RdbQuery *rdbQuery = nullptr; + auto ret = query.QueryInterface(rdbQuery); + if (ret != GeneralError::E_OK || rdbQuery == nullptr) { + dbQuery.FromTable(query.GetTables()); + } else { + dbQuery = rdbQuery->query_; + } + auto dbMode = DistributedDB::SyncMode(mode); + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " + "wait:%{public}d", + devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), mode, wait); + return GeneralError::E_ALREADY_CLOSED; + } + auto status = (mode < NEARBY_END) + ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), wait) + : (mode > NEARBY_END && mode < CLOUD_END) + ? delegate_->Sync(devices, dbMode, dbQuery, GetDBProcessCB(std::move(async)), wait) + : DistributedDB::INVALID_ARGS; + return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; +} + +int32_t RdbGeneralStore::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) +{ + if (mode < 0 || mode > CloudService::CLEAR_CLOUD_BUTT) { + return GeneralError::E_INVALID_ARGS; + } + int32_t dbMode; + DBStatus status; + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " + "tableName:%{public}s", + devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), mode, + Anonymous::Change(tableName).c_str()); + return GeneralError::E_ALREADY_CLOSED; + } + switch (mode) { + case CloudService::CLEAR_CLOUD_INFO: + dbMode = CleanMode::CLOUD_INFO; + status = delegate_->RemoveDeviceData("", static_cast(dbMode)); + break; + case CloudService::CLEAR_CLOUD_DATA_AND_INFO: + dbMode = CleanMode::CLOUD_DATA; + status = delegate_->RemoveDeviceData("", static_cast(dbMode)); + break; + default: + if (devices.empty()) { + status = delegate_->RemoveDeviceData(); + break; + } + + for (auto device : devices) { + status = delegate_->RemoveDeviceData(device, tableName); + } + break; + } + return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; +} + +int32_t RdbGeneralStore::Watch(int32_t origin, Watcher &watcher) +{ + if (origin != Watcher::Origin::ORIGIN_ALL || observer_.watcher_ != nullptr) { + return GeneralError::E_INVALID_ARGS; + } + + observer_.watcher_ = &watcher; + return GeneralError::E_OK; +} + +int32_t RdbGeneralStore::Unwatch(int32_t origin, Watcher &watcher) +{ + if (origin != Watcher::Origin::ORIGIN_ALL || observer_.watcher_ != &watcher) { + return GeneralError::E_INVALID_ARGS; + } + + observer_.watcher_ = nullptr; + return GeneralError::E_OK; +} + +RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) +{ + if (!async) { + return [](auto &) {}; + } + return [async = std::move(async)](const std::map> &result) { + DistributedData::GenDetails details; + for (auto &[key, tables] : result) { + auto &value = details[key]; + value.progress = FINISHED; + value.code = GeneralError::E_OK; + for (auto &table : tables) { + if (table.status != DBStatus::OK) { + value.code = GeneralError::E_ERROR; + } + } + } + async(details); + }; +} + +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async) +{ + if (!async) { + return [](auto &) {}; + } + + return [async = std::move(async)](const std::map &processes) { + DistributedData::GenDetails details; + for (auto &[id, process] : processes) { + auto &detail = details[id]; + detail.progress = process.process; + detail.code = ConvertStatus(process.errCode); + for (auto [key, value] : process.tableProcess) { + auto &table = detail.details[key]; + table.upload.total = value.upLoadInfo.total; + table.upload.success = value.upLoadInfo.successCount; + table.upload.failed = value.upLoadInfo.failCount; + table.upload.untreated = table.upload.total - table.upload.success - table.upload.failed; + table.download.total = value.downLoadInfo.total; + table.download.success = value.downLoadInfo.successCount; + table.download.failed = value.downLoadInfo.failCount; + table.download.untreated = table.download.total - table.download.success - table.download.failed; + } + } + async(details); + }; +} + +int32_t RdbGeneralStore::Release() +{ + auto ref = 1; + { + std::lock_guard lock(mutex_); + if (ref_ == 0) { + return 0; + } + ref = --ref_; + } + ZLOGD("ref:%{public}d", ref); + if (ref == 0) { + delete this; + } + return ref; +} + +int32_t RdbGeneralStore::AddRef() +{ + std::lock_guard lock(mutex_); + if (ref_ == 0) { + return 0; + } + return ++ref_; +} + +RdbGeneralStore::GenErr RdbGeneralStore::ConvertStatus(DistributedDB::DBStatus status) +{ + switch (status) { + case DBStatus::OK: + return GenErr::E_OK; + case DBStatus::CLOUD_NETWORK_ERROR: + return GenErr::E_NETWORK_ERROR; + case DBStatus::CLOUD_LOCK_ERROR: + return GenErr::E_LOCKED_BY_OTHERS; + case DBStatus::CLOUD_FULL_RECORDS: + return GenErr::E_RECODE_LIMIT_EXCEEDED; + case DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT: + return GenErr::E_NO_SPACE_FOR_ASSET; + default: + ZLOGI("status:0x%{public}x", status); + break; + } + return GenErr::E_ERROR; +} + +void RdbGeneralStore::ObserverProxy::OnChange(const DBChangedIF &data) +{ + if (!HasWatcher()) { + return; + } + return; +} + +void RdbGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string &originalId, DBChangedData &&data) +{ + using GenOrigin = Watcher::Origin; + if (!HasWatcher()) { + return; + } + GenOrigin genOrigin; + genOrigin.origin = (origin == DBOrigin::ORIGIN_LOCAL) ? GenOrigin::ORIGIN_LOCAL + : (origin == DBOrigin::ORIGIN_CLOUD) ? GenOrigin::ORIGIN_CLOUD + : GenOrigin::ORIGIN_NEARBY; + genOrigin.dataType = data.type == DistributedDB::ASSET ? GenOrigin::ASSET_DATA : GenOrigin::BASIC_DATA; + genOrigin.id.push_back(originalId); + genOrigin.store = storeId_; + Watcher::PRIFields fields; + Watcher::ChangeInfo changeInfo; + for (uint32_t i = 0; i < DistributedDB::OP_BUTT; ++i) { + auto &info = changeInfo[data.tableName][i]; + for (auto &priData : data.primaryData[i]) { + Watcher::PRIValue value; + Convert(std::move(*(priData.begin())), value); + info.push_back(std::move(value)); + } + } + if (!data.field.empty()) { + fields[std::move(data.tableName)] = std::move(*(data.field.begin())); + } + watcher_->OnChange(genOrigin, fields, std::move(changeInfo)); +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_general_store.h b/services/distributeddataservice/service/rdb/rdb_general_store.h new file mode 100644 index 0000000000000000000000000000000000000000..128198f299246f26e61b0c58cf111665f5c7a871 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H +#include +#include +#include "metadata/store_meta_data.h" +#include "rdb_asset_loader.h" +#include "rdb_cloud.h" +#include "rdb_store.h" +#include "relational_store_delegate.h" +#include "relational_store_manager.h" +#include "store/general_store.h" +#include "store/general_value.h" +namespace OHOS::DistributedRdb { +class RdbGeneralStore : public DistributedData::GeneralStore { +public: + using Cursor = DistributedData::Cursor; + using GenQuery = DistributedData::GenQuery; + using VBucket = DistributedData::VBucket; + using VBuckets = DistributedData::VBuckets; + using Value = DistributedData::Value; + using Values = DistributedData::Values; + using StoreMetaData = DistributedData::StoreMetaData; + using Database = DistributedData::Database; + using GenErr = DistributedData::GeneralError; + using RdbStore = OHOS::NativeRdb::RdbStore; + + explicit RdbGeneralStore(const StoreMetaData &meta); + ~RdbGeneralStore(); + int32_t Bind(const Database &database, BindInfo bindInfo) override; + bool IsBound() override; + int32_t Execute(const std::string &table, const std::string &sql) override; + int32_t BatchInsert(const std::string &table, VBuckets &&values) override; + int32_t BatchUpdate(const std::string &table, const std::string &sql, VBuckets &&values) override; + int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; + std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; + std::shared_ptr Query(const std::string &table, GenQuery &query) override; + int32_t Sync(const Devices &devices, int32_t mode, GenQuery &query, DetailAsync async, int32_t wait) override; + int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; + int32_t Watch(int32_t origin, Watcher &watcher) override; + int32_t Unwatch(int32_t origin, Watcher &watcher) override; + int32_t Close() override; + int32_t AddRef() override; + int32_t Release() override; + static GenErr ConvertStatus(DistributedDB::DBStatus status); + +private: + using RdbDelegate = DistributedDB::RelationalStoreDelegate; + using RdbManager = DistributedDB::RelationalStoreManager; + using SyncProcess = DistributedDB::SyncProcess; + using DBBriefCB = DistributedDB::SyncStatusCallback; + using DBProcessCB = std::function &processes)>; + static constexpr uint32_t ITERATE_TIMES = 10000; + class ObserverProxy : public DistributedDB::StoreObserver { + public: + using DBChangedIF = DistributedDB::StoreChangedData; + using DBChangedData = DistributedDB::ChangedData; + using DBOrigin = DistributedDB::Origin; + void OnChange(const DistributedDB::StoreChangedData &data) override; + void OnChange(DBOrigin origin, const std::string &originalId, DBChangedData &&data) override; + bool HasWatcher() const + { + return watcher_ != nullptr; + } + private: + friend RdbGeneralStore; + Watcher *watcher_ = nullptr; + std::string storeId_; + }; + DBBriefCB GetDBBriefCB(DetailAsync async); + DBProcessCB GetDBProcessCB(DetailAsync async); + + ObserverProxy observer_; + RdbManager manager_; + RdbDelegate *delegate_ = nullptr; + std::shared_ptr store_; + std::shared_ptr rdbCloud_ {}; + std::shared_ptr rdbLoader_ {}; + BindInfo bindInfo_; + std::atomic isBound_ = false; + std::mutex mutex_; + int32_t ref_ = 1; + mutable std::shared_mutex rwMutex_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H diff --git a/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp b/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp index 8818a092735ba52ac5ea79e6e64341ea21bdcaf9..1d9d74015d16237f7c5896830d665ba17fbd8b44 100644 --- a/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp +++ b/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp @@ -17,6 +17,8 @@ #include "itypes_util.h" #include "log_print.h" namespace OHOS::DistributedRdb { +using NotifierIFCode = RelationalStore::IRdbNotifierInterfaceCode; + RdbNotifierProxy::RdbNotifierProxy(const sptr &object) : IRemoteProxy(object) { ZLOGI("construct"); @@ -27,7 +29,7 @@ RdbNotifierProxy::~RdbNotifierProxy() noexcept ZLOGI("destroy"); } -int32_t RdbNotifierProxy::OnComplete(uint32_t seqNum, const SyncResult &result) +int32_t RdbNotifierProxy::OnComplete(uint32_t seqNum, Details &&result) { MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { @@ -40,28 +42,30 @@ int32_t RdbNotifierProxy::OnComplete(uint32_t seqNum, const SyncResult &result) MessageParcel reply; MessageOption option(MessageOption::TF_ASYNC); - if (Remote()->SendRequest(RDB_NOTIFIER_CMD_SYNC_COMPLETE, data, reply, option) != 0) { + if (Remote()->SendRequest( + static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_SYNC_COMPLETE), data, reply, option) != 0) { ZLOGE("send request failed"); return RDB_ERROR; } return RDB_OK; } -int RdbNotifierProxy::OnChange(const std::string &storeName, const std::vector &devices) +int32_t RdbNotifierProxy::OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) { MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { ZLOGE("write descriptor failed"); return RDB_ERROR; } - if (!ITypesUtil::Marshal(data, storeName, devices)) { + if (!ITypesUtil::Marshal(data, origin, primaries, changeInfo)) { ZLOGE("write store name or devices failed"); return RDB_ERROR; } MessageParcel reply; - MessageOption option(MessageOption::TF_ASYNC); - if (Remote()->SendRequest(RDB_NOTIFIER_CMD_DATA_CHANGE, data, reply, option) != 0) { + MessageOption option; + if (Remote()->SendRequest( + static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_DATA_CHANGE), data, reply, option) != 0) { ZLOGE("send request failed"); return RDB_ERROR; } diff --git a/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h b/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h index 375cc7456196f5a7de64011aa1961fa9436f873e..991fcae4f7e6106589828e1b00f12149b0f17d2b 100644 --- a/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h +++ b/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h @@ -29,9 +29,9 @@ public: explicit RdbNotifierProxy(const sptr& object); virtual ~RdbNotifierProxy() noexcept; - int32_t OnComplete(uint32_t seqNum, const SyncResult& result) override; + int32_t OnComplete(uint32_t seqNum, Details &&result) override; - int32_t OnChange(const std::string& storeName, const std::vector& devices) override; + int32_t OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) override; private: static inline BrokerDelegator delegator_; diff --git a/services/distributeddataservice/service/rdb/rdb_query.cpp b/services/distributeddataservice/service/rdb/rdb_query.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4830c1fb085be561828ece3feabcc6f045a52870 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_query.cpp @@ -0,0 +1,28 @@ +/* + * 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 "rdb_query.h" +namespace OHOS::DistributedRdb { +using namespace DistributedData; +bool RdbQuery::IsEqual(uint64_t tid) +{ + return tid == TYPE_ID; +} + +std::vector RdbQuery::GetTables() +{ + return {}; +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_query.h b/services/distributeddataservice/service/rdb/rdb_query.h new file mode 100644 index 0000000000000000000000000000000000000000..aea76acf5778fe76bb16677189e9a0704a2dea42 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_query.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H +#include "rdb_predicates.h" +#include "store/general_value.h" +#include "query.h" +namespace OHOS::DistributedRdb { +class RdbQuery : public DistributedData::GenQuery { +public: + using Predicates = NativeRdb::RdbPredicates; + static constexpr uint64_t TYPE_ID = 0x20000001; + RdbQuery() = default; + + ~RdbQuery() override = default; + + bool IsEqual(uint64_t tid) override; + std::vector GetTables() override; + + DistributedDB::Query query_; + std::string sql_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index ef578fd707027f0edbcc2e52e0bd134b9e29ee0e..491d38e3c6f6538686657f97e2e6bf1e0964d11a 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -17,57 +17,56 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "checker/checker_manager.h" +#include "cloud/cloud_event.h" #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" +#include "directory/directory_manager.h" +#include "eventcenter/event_center.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" -#include "permission/permission_validator.h" +#include "rdb_watcher.h" #include "rdb_notifier_proxy.h" +#include "rdb_query.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" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; using OHOS::DistributedData::StoreMetaData; using OHOS::DistributedData::Anonymous; using namespace OHOS::DistributedData; +using namespace OHOS::Security::AccessToken; using DistributedDB::RelationalStoreManager; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using system_clock = std::chrono::system_clock; constexpr uint32_t ITERATE_TIMES = 10000; namespace OHOS::DistributedRdb { __attribute__((used)) RdbServiceImpl::Factory RdbServiceImpl::factory_; RdbServiceImpl::Factory::Factory() { - FeatureSystem::GetInstance().RegisterCreator("relational_store", - []() { return std::make_shared(); }); + FeatureSystem::GetInstance().RegisterCreator(RdbServiceImpl::SERVICE_NAME, [this]() { + if (product_ == nullptr) { + product_ = std::make_shared(); + } + return product_; + }); + AutoCache::GetInstance().RegCreator(RDB_DEVICE_COLLABORATION, [](const StoreMetaData &metaData) -> GeneralStore* { + return new (std::nothrow) RdbGeneralStore(metaData); + }); } RdbServiceImpl::Factory::~Factory() { } -RdbServiceImpl::DeathRecipientImpl::DeathRecipientImpl(const DeathCallback& callback) - : callback_(callback) -{ - ZLOGI("construct"); -} - -RdbServiceImpl::DeathRecipientImpl::~DeathRecipientImpl() -{ - ZLOGI("destroy"); -} - -void RdbServiceImpl::DeathRecipientImpl::OnRemoteDied(const wptr &object) -{ - ZLOGI("enter"); - if (callback_) { - callback_(); - } -} - RdbServiceImpl::RdbServiceImpl() : autoLaunchObserver_(this) { ZLOGI("construct"); @@ -75,6 +74,28 @@ RdbServiceImpl::RdbServiceImpl() : autoLaunchObserver_(this) [this](const std::string& identifier, DistributedDB::AutoLaunchParam ¶m) { return ResolveAutoLaunch(identifier, param); }); + auto process = [this](const Event &event) { + auto &evt = static_cast(event); + auto storeInfo = evt.GetStoreInfo(); + StoreMetaData meta; + meta.storeId = storeInfo.storeName; + meta.bundleName = storeInfo.bundleName; + meta.user = std::to_string(storeInfo.user); + meta.instanceId = storeInfo.instanceId; + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + return; + } + auto watchers = GetWatchers(meta.tokenId, meta.storeId); + auto store = AutoCache::GetInstance().GetStore(meta, watchers); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + return; + } + }; + EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); } int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) @@ -95,11 +116,12 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier( entry.user, entry.appId, entry.storeId); - ZLOGI("%{public}s %{public}s %{public}s", entry.user.c_str(), entry.appId.c_str(), entry.storeId.c_str()); + ZLOGI("%{public}s %{public}s %{public}s", + entry.user.c_str(), entry.appId.c_str(), Anonymous::Change(entry.storeId).c_str()); if (aIdentifier != identifier) { continue; } - ZLOGI("find identifier %{public}s", entry.storeId.c_str()); + ZLOGI("find identifier %{public}s", Anonymous::Change(entry.storeId).c_str()); param.userId = entry.user; param.appId = entry.appId; param.storeId = entry.storeId; @@ -118,6 +140,13 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib return false; } +int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) +{ + OnClientDied(pid); + AutoCache::GetInstance().CloseStore(tokenId); + return E_OK; +} + void RdbServiceImpl::OnClientDied(pid_t pid) { ZLOGI("client dead pid=%{public}d", pid); @@ -128,20 +157,20 @@ void RdbServiceImpl::OnClientDied(pid_t pid) } return false; }); - notifiers_.Erase(pid); - identifiers_.EraseIf([pid](const auto& key, pid_t& value) { - return pid == value; + identifiers_.EraseIf([pid](const auto &key, std::pair &value) { + return value.first == pid; }); + syncAgents_.EraseIf([pid](auto &key, SyncAgent &agent) { return agent.pid_ == pid; }); } -bool RdbServiceImpl::CheckAccess(const RdbSyncerParam ¶m) +bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::string& storeName) { CheckerManager::StoreInfo storeInfo; storeInfo.uid = IPCSkeleton::GetCallingUid(); storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); - storeInfo.bundleName = param.bundleName_; - storeInfo.storeId = RdbSyncer::RemoveSuffix(param.storeName_); - auto instanceId = RdbSyncer::GetInstIndex(storeInfo.tokenId, storeInfo.bundleName); + storeInfo.bundleName = bundleName; + storeInfo.storeId = RdbSyncer::RemoveSuffix(storeName); + auto [instanceId, user] = RdbSyncer::GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName); if (instanceId != 0) { return false; } @@ -159,54 +188,59 @@ std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device return DistributedDB::RelationalStoreManager::GetDistributedTableName(uuid, table); } -int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam& param, const sptr notifier) +int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptr notifier) { - if (!CheckAccess(param)) { + if (!CheckAccess(param.bundleName_, "")) { ZLOGE("permission error"); return RDB_ERROR; } - - pid_t pid = IPCSkeleton::GetCallingPid(); - auto recipient = new(std::nothrow) DeathRecipientImpl([this, pid] { - OnClientDied(pid); - }); - if (recipient == nullptr) { - ZLOGE("malloc recipient failed"); + if (notifier == nullptr) { + ZLOGE("notifier is null"); return RDB_ERROR; } - if (!notifier->AddDeathRecipient(recipient)) { - ZLOGE("link to death failed"); - return RDB_ERROR; - } - notifiers_.Insert(pid, iface_cast(notifier)); - ZLOGI("success pid=%{public}d", pid); + auto notifierProxy = iface_cast(notifier); + pid_t pid = IPCSkeleton::GetCallingPid(); + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + syncAgents_.Compute(tokenId, [¶m, notifierProxy, pid](auto, SyncAgent &agent) { + if (pid != agent.pid_) { + agent.ReInit(pid, param.bundleName_); + } + agent.SetNotifier(notifierProxy); + return true; + }); + ZLOGI("success tokenId:%{public}x, pid=%{public}d", tokenId, pid); return RDB_OK; } -void RdbServiceImpl::OnDataChange(pid_t pid, const DistributedDB::StoreChangedData &data) +void RdbServiceImpl::OnDataChange(pid_t pid, uint32_t tokenId, const DistributedDB::StoreChangedData &data) { DistributedDB::StoreProperty property; data.GetStoreProperty(property); - ZLOGI("%{public}d %{public}s", pid, property.storeId.c_str()); + ZLOGI("%{public}d %{public}s", pid, Anonymous::Change(property.storeId).c_str()); if (pid == 0) { auto identifier = RelationalStoreManager::GetRelationalStoreIdentifier(property.userId, property.appId, property.storeId); - auto pair = identifiers_.Find(TransferStringToHex(identifier)); - if (!pair.first) { + auto [success, info] = identifiers_.Find(TransferStringToHex(identifier)); + if (!success) { ZLOGI("client doesn't subscribe"); return; } - pid = pair.second; - ZLOGI("fixed pid=%{public}d", pid); + pid = info.first; + tokenId = info.second; + ZLOGI("fixed pid=%{public}d and tokenId=0x%{public}d", pid, tokenId); } - notifiers_.ComputeIfPresent(pid, [&data, &property] (const auto& key, const sptr& value) { + auto [success, agent] = syncAgents_.Find(tokenId); + if (success && agent.notifier_ != nullptr && pid == agent.pid_) { std::string device = data.GetDataChangeDevice(); auto networkId = DmAdapter::GetInstance().ToNetworkID(device); - value->OnChange(property.storeId, { networkId }); - return true; - }); + Origin origin; + origin.origin = Origin::ORIGIN_NEARBY; + origin.store = property.storeId; + origin.id.push_back(networkId); + agent.notifier_->OnChange(origin, {}, {}); + } } void RdbServiceImpl::SyncerTimeout(std::shared_ptr syncer) @@ -214,9 +248,10 @@ void RdbServiceImpl::SyncerTimeout(std::shared_ptr syncer) if (syncer == nullptr) { return; } - ZLOGI("%{public}s", syncer->GetStoreId().c_str()); - syncers_.ComputeIfPresent(syncer->GetPid(), [this, &syncer](const auto& key, StoreSyncersType& syncers) { - syncers.erase(syncer->GetStoreId()); + auto storeId = syncer->GetStoreId(); + ZLOGI("%{public}s", Anonymous::Change(storeId).c_str()); + syncers_.ComputeIfPresent(syncer->GetPid(), [this, storeId](const auto& key, StoreSyncersType& syncers) { + syncers.erase(storeId); syncerNum_--; return true; }); @@ -243,20 +278,18 @@ std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam &pa } syncers.erase(storeId); } - if (syncers.size() >= MAX_SYNCER_PER_PROCESS) { - ZLOGE("%{public}d exceed MAX_PROCESS_SYNCER_NUM", pid); + if (syncers.size() >= MAX_SYNCER_PER_PROCESS || syncerNum_ >= MAX_SYNCER_NUM) { + ZLOGE("pid: %{public}d, syncers size: %{public}zu. syncerNum: %{public}d", pid, syncers.size(), syncerNum_); return !syncers.empty(); } - if (syncerNum_ >= MAX_SYNCER_NUM) { - ZLOGE("no available syncer"); - return !syncers.empty(); - } - auto rdbObserver = new (std::nothrow) RdbStoreObserverImpl(this, pid); + auto rdbObserver = new (std::nothrow) RdbStoreObserverImpl(this, pid, tokenId); if (rdbObserver == nullptr) { return !syncers.empty(); } auto syncer_ = std::make_shared(param, rdbObserver); - if (syncer_->Init(pid, uid, tokenId) != 0) { + StoreMetaData storeMetaData = GetStoreMetaData(param); + MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData); + if (syncer_->Init(pid, uid, tokenId, storeMetaData) != RDB_OK) { return !syncers.empty(); } syncers[storeId] = syncer_; @@ -270,17 +303,18 @@ std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam &pa }); if (syncer != nullptr) { - identifiers_.Insert(syncer->GetIdentifier(), pid); + identifiers_.Insert(syncer->GetIdentifier(), { pid, tokenId }); } else { ZLOGE("syncer is nullptr"); } return syncer; } -int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables) +int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, + int32_t type) { ZLOGI("enter"); - if (!CheckAccess(param)) { + if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); return RDB_ERROR; } @@ -288,49 +322,53 @@ int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const if (syncer == nullptr) { return RDB_ERROR; } - return syncer->SetDistributedTables(tables); + return syncer->SetDistributedTables(tables, type); } -int32_t RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const SyncOption &option, - const RdbPredicates &predicates, SyncResult &result) +std::pair RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const Option &option, + const PredicatesMemo &pred) { - if (!CheckAccess(param)) { + if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); - return RDB_ERROR; + return {RDB_ERROR, {}}; } auto syncer = GetRdbSyncer(param); if (syncer == nullptr) { - return RDB_ERROR; + return {RDB_ERROR, {}}; } - return syncer->DoSync(option, predicates, result); + Details details = {}; + auto status = syncer->DoSync(option, pred, [&details, ¶m](auto &&result) mutable { + ZLOGD("Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + details = std::move(result); + }); + return { status, std::move(details) }; } -void RdbServiceImpl::OnAsyncComplete(pid_t pid, uint32_t seqNum, const SyncResult &result) +void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result) { - ZLOGI("pid=%{public}d seqnum=%{public}u", pid, seqNum); - notifiers_.ComputeIfPresent(pid, [seqNum, &result] (const auto& key, const sptr& value) { - value->OnComplete(seqNum, result); - return true; - }); + ZLOGI("pid=%{public}x seqnum=%{public}u", tokenId, seqNum); + auto [success, agent] = syncAgents_.Find(tokenId); + if (success && agent.notifier_ != nullptr) { + agent.notifier_->OnComplete(seqNum, std::move(result)); + } } -int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, uint32_t seqNum, const SyncOption &option, - const RdbPredicates &predicates) +int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred) { - if (!CheckAccess(param)) { + if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); return RDB_ERROR; } - pid_t pid = IPCSkeleton::GetCallingPid(); - ZLOGI("seq num=%{public}u", seqNum); + auto tokenId = IPCSkeleton::GetCallingTokenID(); + ZLOGI("seq num=%{public}u", option.seqNum); auto syncer = GetRdbSyncer(param); if (syncer == nullptr) { return RDB_ERROR; } - return syncer->DoAsync(option, predicates, - [this, pid, seqNum] (const SyncResult& result) { - OnAsyncComplete(pid, seqNum, result); - }); + return syncer->DoSync(option, pred, [this, tokenId, seqNum = option.seqNum](Details &&result) { + OnAsyncComplete(tokenId, seqNum, std::move(result)); + }); } std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr) @@ -353,7 +391,7 @@ std::string RdbServiceImpl::GenIdentifier(const RdbSyncerParam ¶m) pid_t uid = IPCSkeleton::GetCallingUid(); uint32_t token = IPCSkeleton::GetCallingTokenID(); auto storeId = RdbSyncer::RemoveSuffix(param.storeName_); - CheckerManager::StoreInfo storeInfo{ uid, token, param.bundleName_, storeId }; + CheckerManager::StoreInfo storeInfo { uid, token, param.bundleName_, storeId }; auto userId = AccountDelegate::GetInstance()->GetUserByToken(token); std::string appId = CheckerManager::GetInstance().GetAppId(storeInfo); std::string identifier = RelationalStoreManager::GetRelationalStoreIdentifier( @@ -361,27 +399,48 @@ std::string RdbServiceImpl::GenIdentifier(const RdbSyncerParam ¶m) return TransferStringToHex(identifier); } -int32_t RdbServiceImpl::DoSubscribe(const RdbSyncerParam& param) +AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName) { - pid_t pid = IPCSkeleton::GetCallingPid(); - auto identifier = GenIdentifier(param); - ZLOGI("%{public}s %{public}.6s %{public}d", param.storeName_.c_str(), identifier.c_str(), pid); - identifiers_.Insert(identifier, pid); - return RDB_OK; + auto [success, agent] = syncAgents_.Find(tokenId); + if (agent.watcher_ == nullptr) { + return {}; + } + return { agent.watcher_ }; } -int32_t RdbServiceImpl::DoUnSubscribe(const RdbSyncerParam& param) +void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName) { - auto identifier = GenIdentifier(param); - ZLOGI("%{public}s %{public}.6s", param.storeName_.c_str(), identifier.c_str()); - identifiers_.Erase(identifier); - return RDB_OK; + pid_ = pid; + count_ = 0; + bundleName_ = bundleName; + notifier_ = nullptr; + if (watcher_ != nullptr) { + watcher_->SetNotifier(nullptr); + } +} + +void RdbServiceImpl::SyncAgent::SetNotifier(sptr notifier) +{ + notifier_ = notifier; + if (watcher_ != nullptr) { + watcher_->SetNotifier(notifier); + } +} + +void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr watcher) +{ + if (watcher_ != watcher) { + watcher_ = watcher; + if (watcher_ != nullptr) { + watcher_->SetNotifier(notifier_); + } + } } int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet) { - if (!CheckAccess(param)) { + if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); return RDB_ERROR; } @@ -393,64 +452,205 @@ int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::stri return syncer->RemoteQuery(device, sql, selectionArgs, resultSet); } -int32_t RdbServiceImpl::CreateRDBTable( - const RdbSyncerParam ¶m, const std::string &writePermission, const std::string &readPermission) +int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, + const AsyncDetail &async) { - if (!CheckAccess(param)) { - ZLOGE("permission error"); - return RDB_ERROR; + if (!option.isAsync) { + auto [status, details] = DoSync(param, option, predicates); + if (async != nullptr) { + async(std::move(details)); + } + return status; } + return DoAsync(param, option, predicates); +} +int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, + RdbStoreObserver *observer) +{ pid_t pid = IPCSkeleton::GetCallingPid(); - auto rdbObserver = new (std::nothrow) RdbStoreObserverImpl(this, pid); - if (rdbObserver == nullptr) { - return RDB_ERROR; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + switch (option.mode) { + case SubscribeMode::REMOTE: { + auto identifier = GenIdentifier(param); + identifiers_.Insert(identifier, std::pair { pid, tokenId }); + ZLOGI("%{public}s %{public}.6s %{public}d", Anonymous::Change(param.storeName_).c_str(), + identifier.c_str(), pid); + break; + } + case SubscribeMode::CLOUD: // fallthrough + case SubscribeMode::CLOUD_DETAIL: { + syncAgents_.Compute(tokenId, [pid, ¶m](auto &key, SyncAgent &agent) { + if (pid != agent.pid_) { + agent.ReInit(pid, param.bundleName_); + } + if (agent.watcher_ == nullptr) { + agent.SetWatcher(std::make_shared()); + } + agent.count_++; + return true; + }); + break; + } + default: + return RDB_ERROR; } - auto syncer = new (std::nothrow) RdbSyncer(param, rdbObserver); - if (syncer == nullptr) { - ZLOGE("new syncer error"); + return RDB_OK; +} + +int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, + RdbStoreObserver *observer) +{ + switch (option.mode) { + case SubscribeMode::REMOTE: { + auto identifier = GenIdentifier(param); + ZLOGI("%{public}s %{public}.6s", param.storeName_.c_str(), identifier.c_str()); + identifiers_.Erase(identifier); + break; + } + case SubscribeMode::CLOUD: // fallthrough + case SubscribeMode::CLOUD_DETAIL: { + syncAgents_.ComputeIfPresent(IPCSkeleton::GetCallingTokenID(), [](auto &key, SyncAgent &agent) { + if (agent.count_ > 0) { + agent.count_--; + } + if (agent.count_ == 0) { + agent.SetWatcher(nullptr); + } + return true; + }); + break; + } + default: + ZLOGI("mode:%{public}d", option.mode); + return RDB_ERROR; + } + return RDB_OK; +} + +int32_t RdbServiceImpl::OnInitialize() +{ + return RDB_OK; +} + +int32_t RdbServiceImpl::GetSchema(const RdbSyncerParam ¶m) +{ + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("permission error"); return RDB_ERROR; } - auto uid = IPCSkeleton::GetCallingUid(); - auto tokenId = IPCSkeleton::GetCallingTokenID(); - if (syncer->Init(pid, uid, tokenId, writePermission, readPermission) != RDB_OK) { - ZLOGE("Init error"); - delete syncer; + StoreMetaData storeMeta; + if (CreateMetaData(param, storeMeta) != RDB_OK) { return RDB_ERROR; } - delete syncer; + + if (executors_ != nullptr) { + CloudEvent::StoreInfo storeInfo; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.bundleName = param.bundleName_; + storeInfo.storeName = RdbSyncer::RemoveSuffix(param.storeName_); + auto [instanceId, user]= RdbSyncer::GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_); + storeInfo.instanceId = instanceId; + storeInfo.user = user; + executors_->Execute([storeInfo]() { + auto event = std::make_unique(CloudEvent::GET_SCHEMA, std::move(storeInfo)); + EventCenter::GetInstance().PostEvent(move(event)); + return; + }); + } return RDB_OK; } -int32_t RdbServiceImpl::DestroyRDBTable(const RdbSyncerParam ¶m) +StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m) { - if (!CheckAccess(param)) { - ZLOGE("permission error"); + StoreMetaData metaData; + metaData.uid = IPCSkeleton::GetCallingUid(); + metaData.tokenId = IPCSkeleton::GetCallingTokenID(); + auto [instanceId, user] = RdbSyncer::GetInstIndexAndUser(metaData.tokenId, param.bundleName_); + metaData.instanceId = instanceId; + metaData.bundleName = param.bundleName_; + metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + metaData.storeId = RdbSyncer::RemoveSuffix(param.storeName_); + metaData.user = std::to_string(user); + metaData.storeType = param.type_; + metaData.securityLevel = param.level_; + metaData.area = param.area_; + metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData)); + metaData.appType = "harmony"; + metaData.hapName = param.hapName_; + metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_; + metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); + metaData.isEncrypt = param.isEncrypt_; + return metaData; +} + +int32_t RdbServiceImpl::CreateMetaData(const RdbSyncerParam ¶m, StoreMetaData &old) +{ + auto meta = GetStoreMetaData(param); + bool isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old); + if (isCreated && (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || + old.area != meta.area)) { + ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " + "area:%{public}d->%{public}d", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType, + old.isEncrypt, meta.isEncrypt, old.area, meta.area); return RDB_ERROR; } - pid_t pid = IPCSkeleton::GetCallingPid(); - auto rdbObserver = new (std::nothrow) RdbStoreObserverImpl(this, pid); - if (rdbObserver == nullptr) { - return RDB_ERROR; + if (!isCreated || meta != old) { + Upgrade(param, old); + ZLOGD("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " + "area:%{public}d->%{public}d", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType, + old.isEncrypt, meta.isEncrypt, old.area, meta.area); + MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta); } - auto syncer = new (std::nothrow) RdbSyncer(param, rdbObserver); - if (syncer == nullptr) { - ZLOGE("new syncer error"); + AppIDMetaData appIdMeta; + appIdMeta.bundleName = meta.bundleName; + appIdMeta.appId = meta.appId; + if (!MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true)) { + ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " + "area:%{public}d->%{public}d", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType, + old.isEncrypt, meta.isEncrypt, old.area, meta.area); return RDB_ERROR; } + if (!param.isEncrypt_ || param.password_.empty()) { + return RDB_OK; + } + return SetSecretKey(param, meta); +} - StoreMetaData meta; - if (syncer->DestroyMetaData(meta) != RDB_OK) { - ZLOGE("destroy meta data error"); - delete syncer; +int32_t RdbServiceImpl::SetSecretKey(const RdbSyncerParam ¶m, const StoreMetaData &meta) +{ + SecretKeyMetaData newSecretKey; + newSecretKey.storeType = meta.storeType; + newSecretKey.sKey = CryptoManager::GetInstance().Encrypt(param.password_); + if (newSecretKey.sKey.empty()) { + ZLOGE("encrypt work key error."); return RDB_ERROR; } - delete syncer; + auto time = system_clock::to_time_t(system_clock::now()); + newSecretKey.time = { reinterpret_cast(&time), reinterpret_cast(&time) + sizeof(time) }; + return MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), newSecretKey, true) ? RDB_OK : RDB_ERROR; +} + +int32_t RdbServiceImpl::Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old) +{ + if (old.storeType == RDB_DEVICE_COLLABORATION && old.version < StoreMetaData::UUID_CHANGED_TAG) { + auto syncer = GetRdbSyncer(param); + if (syncer == nullptr) { + ZLOGE("syncer is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str()); + return RDB_ERROR; + } + return syncer->RemoveDeviceData(); + } return RDB_OK; } -int32_t RdbServiceImpl::OnExecutor(std::shared_ptr executors) + +int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo) { - executors_ = executors; + executors_ = bindInfo.executors; return 0; } } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.h b/services/distributeddataservice/service/rdb/rdb_service_impl.h index 4a32c7128032c901259dd5a9e4b0dbf9b078c1b9..061e5489d43ac4a34289c83274054446384cb3b8 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -26,6 +26,8 @@ #include "metadata/store_meta_data.h" #include "rdb_notifier_proxy.h" #include "rdb_syncer.h" +#include "rdb_watcher.h" +#include "store/auto_cache.h" #include "store_observer.h" #include "visibility.h" namespace OHOS::DistributedRdb { @@ -40,74 +42,92 @@ public: /* IPC interface */ std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; - int32_t InitNotifier(const RdbSyncerParam& param, const sptr notifier) override; + int32_t InitNotifier(const RdbSyncerParam ¶m, sptr notifier) override; - int32_t SetDistributedTables(const RdbSyncerParam& param, const std::vector& tables) override; + int32_t SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, + int32_t type = DISTRIBUTED_DEVICE) override; int32_t RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet) override; - void OnDataChange(pid_t pid, const DistributedDB::StoreChangedData& data); + int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, + const AsyncDetail &async) override; - int32_t CreateRDBTable( - const RdbSyncerParam ¶m, const std::string &writePermission, const std::string &readPermission) override; - int32_t DestroyRDBTable(const RdbSyncerParam ¶m) override; + int32_t Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) override; - int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; + int32_t UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, + RdbStoreObserver *observer) override; + + void OnDataChange(pid_t pid, uint32_t tokenId, const DistributedDB::StoreChangedData& data); - int32_t OnExecutor(std::shared_ptr executors) override; + int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; -protected: - int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, - const RdbPredicates& predicates, SyncResult& result) override; + int32_t OnInitialize() override; - int32_t DoAsync(const RdbSyncerParam& param, uint32_t seqNum, const SyncOption& option, - const RdbPredicates& predicates) override; + int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) override; - int32_t DoSubscribe(const RdbSyncerParam& param) override; + int32_t GetSchema(const RdbSyncerParam ¶m) override; - int32_t DoUnSubscribe(const RdbSyncerParam& param) override; + int32_t OnBind(const BindInfo &bindInfo) override; private: + using Watchers = DistributedData::AutoCache::Watchers; + struct SyncAgent { + pid_t pid_ = 0; + int32_t count_ = 0; + std::string bundleName_; + sptr notifier_ = nullptr; + std::shared_ptr watcher_ = nullptr; + void ReInit(pid_t pid, const std::string &bundleName); + void SetNotifier(sptr notifier); + void SetWatcher(std::shared_ptr watcher); + }; + + class Factory { + public: + Factory(); + ~Factory(); + private: + std::shared_ptr product_; + }; + using StoreSyncersType = std::map>; + + static constexpr int32_t MAX_SYNCER_NUM = 50; + static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; + static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms + + std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); + + int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); + + Watchers GetWatchers(uint32_t tokenId, const std::string &storeName); + std::string GenIdentifier(const RdbSyncerParam& param); - bool CheckAccess(const RdbSyncerParam& param); + bool CheckAccess(const std::string& bundleName, const std::string& storeName); void SyncerTimeout(std::shared_ptr syncer); std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param); - void OnAsyncComplete(pid_t pid, uint32_t seqNum, const SyncResult& result); + void OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details&& result); - class DeathRecipientImpl : public IRemoteObject::DeathRecipient { - public: - using DeathCallback = std::function; - explicit DeathRecipientImpl(const DeathCallback& callback); - ~DeathRecipientImpl() override; - void OnRemoteDied(const wptr &object) override; - private: - const DeathCallback callback_; - }; - class Factory { - public: - Factory(); - ~Factory(); - }; + int32_t CreateMetaData(const RdbSyncerParam ¶m, StoreMetaData &old); - using StoreSyncersType = std::map>; - int32_t syncerNum_ {}; - ConcurrentMap syncers_; - ConcurrentMap> notifiers_; - ConcurrentMap identifiers_; - RdbStoreObserverImpl autoLaunchObserver_; + StoreMetaData GetStoreMetaData(const RdbSyncerParam ¶m); - static Factory factory_; + int32_t SetSecretKey(const RdbSyncerParam ¶m, const StoreMetaData &meta); + + int32_t Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old); static std::string TransferStringToHex(const std::string& origStr); - static constexpr int32_t MAX_SYNCER_NUM = 50; - static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; - static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms + static Factory factory_; + int32_t syncerNum_ {}; + ConcurrentMap syncers_; + ConcurrentMap> identifiers_; + ConcurrentMap syncAgents_; + RdbStoreObserverImpl autoLaunchObserver_; std::shared_ptr executors_; }; } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 931792acf9baa426ff5499f90ed61809abf13919..8e602e5cda5dc604daf024be61889ab602ae39f3 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -22,13 +22,13 @@ #include "utils/anonymous.h" namespace OHOS::DistributedRdb { +using Anonymous = DistributedData::Anonymous; int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, MessageParcel &reply) { std::string device; std::string table; if (!ITypesUtil::Unmarshal(data, device, table)) { - ZLOGE("Unmarshal device:%{public}s table:%{public}s", DistributedData::Anonymous::Change(device).c_str(), - table.c_str()); + ZLOGE("Unmarshal device:%{public}s table:%{public}s", Anonymous::Change(device).c_str(), table.c_str()); return IPC_STUB_INVALID_DATA_ERR; } @@ -40,13 +40,29 @@ int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, return RDB_OK; } +int32_t RdbServiceStub::OnGetSchema(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto status = GetSchema(param); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} + int32_t RdbServiceStub::OnRemoteInitNotifier(MessageParcel &data, MessageParcel &reply) { RdbSyncerParam param; sptr notifier; if (!ITypesUtil::Unmarshal(data, param, notifier) || notifier == nullptr) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + ZLOGE("Unmarshal bundleName:%{public}s storeName_:%{public}s notifier is nullptr:%{public}d", + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), notifier == nullptr); return IPC_STUB_INVALID_DATA_ERR; } auto status = InitNotifier(param, notifier); @@ -61,13 +77,14 @@ int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, Messag { RdbSyncerParam param; std::vector tables; - if (!ITypesUtil::Unmarshal(data, param, tables)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables size:%{public}zu", - param.bundleName_.c_str(), param.storeName_.c_str(), tables.size()); + int32_t type; + if (!ITypesUtil::Unmarshal(data, param, tables, type)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables size:%{public}zu type:%{public}d", + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), tables.size(), type); return IPC_STUB_INVALID_DATA_ERR; } - auto status = SetDistributedTables(param, tables); + auto status = SetDistributedTables(param, tables, type); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -78,16 +95,16 @@ int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, Messag int32_t RdbServiceStub::OnRemoteDoSync(MessageParcel &data, MessageParcel &reply) { RdbSyncerParam param; - SyncOption option {}; - RdbPredicates predicates; + Option option {}; + PredicatesMemo predicates; if (!ITypesUtil::Unmarshal(data, param, option, predicates)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str(), predicates.table_.c_str()); + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables:%{public}zu", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str(), predicates.tables_.size()); return IPC_STUB_INVALID_DATA_ERR; } - SyncResult result; - auto status = DoSync(param, option, predicates, result); + Details result = {}; + auto status = Sync(param, option, predicates, [&result](Details &&details) { result = std::move(details); }); if (!ITypesUtil::Marshal(reply, status, result)) { ZLOGE("Marshal status:0x%{public}x result size:%{public}zu", status, result.size()); return IPC_STUB_WRITE_PARCEL_ERR; @@ -98,16 +115,15 @@ int32_t RdbServiceStub::OnRemoteDoSync(MessageParcel &data, MessageParcel &reply int32_t RdbServiceStub::OnRemoteDoAsync(MessageParcel &data, MessageParcel &reply) { RdbSyncerParam param; - uint32_t seqNum; - SyncOption option {}; - RdbPredicates predicates; - if (!ITypesUtil::Unmarshal(data, param, seqNum, option, predicates)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s seqNum:%{public}u tables:%{public}s", - param.bundleName_.c_str(), param.storeName_.c_str(), seqNum, predicates.table_.c_str()); + Option option {}; + PredicatesMemo predicates; + if (!ITypesUtil::Unmarshal(data, param, option, predicates)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s seqNum:%{public}u table:%{public}s", + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), option.seqNum, + predicates.tables_.empty() ? "null" : predicates.tables_.begin()->c_str()); return IPC_STUB_INVALID_DATA_ERR; } - - auto status = DoAsync(param, seqNum, option, predicates); + auto status = Sync(param, option, predicates, nullptr); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -118,13 +134,14 @@ int32_t RdbServiceStub::OnRemoteDoAsync(MessageParcel &data, MessageParcel &repl int32_t RdbServiceStub::OnRemoteDoSubscribe(MessageParcel &data, MessageParcel &reply) { RdbSyncerParam param; - if (!ITypesUtil::Unmarshal(data, param)) { + SubscribeOption option; + if (!ITypesUtil::Unmarshal(data, param, option)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - auto status = DoSubscribe(param); + auto status = Subscribe(param, option, nullptr); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -135,13 +152,14 @@ int32_t RdbServiceStub::OnRemoteDoSubscribe(MessageParcel &data, MessageParcel & int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel &reply) { RdbSyncerParam param; + SubscribeOption option; if (!ITypesUtil::Unmarshal(data, param)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - auto status = DoUnSubscribe(param); + auto status = UnSubscribe(param, option, nullptr); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -157,9 +175,9 @@ int32_t RdbServiceStub::OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel std::vector selectionArgs; if (!ITypesUtil::Unmarshal(data, param, device, sql, selectionArgs)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s device:%{public}s sql:%{public}s " - "selectionArgs size:%{public}zu", param.bundleName_.c_str(), param.storeName_.c_str(), - DistributedData::Anonymous::Change(device).c_str(), - DistributedData::Anonymous::Change(sql).c_str(), selectionArgs.size()); + "selectionArgs size:%{public}zu", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str(), Anonymous::Change(device).c_str(), + Anonymous::Change(sql).c_str(), selectionArgs.size()); return IPC_STUB_INVALID_DATA_ERR; } @@ -189,47 +207,9 @@ int RdbServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageP if (!CheckInterfaceToken(data)) { return RDB_ERROR; } - if (code >= 0 && code < RDB_SERVICE_CMD_MAX) { + if (code >= 0 && code < static_cast(RdbServiceCode::RDB_SERVICE_CMD_MAX)) { return (this->*HANDLERS[code])(data, reply); } return RDB_ERROR; } - -int32_t RdbServiceStub::OnRemoteDoCreateTable(MessageParcel &data, MessageParcel &reply) -{ - RdbSyncerParam param; - std::string writePermission; - std::string readPermission; - if (!ITypesUtil::Unmarshal(data, param, writePermission, readPermission)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s writePermission:%{public}s " - "readPermission:%{public}s", param.bundleName_.c_str(), param.storeName_.c_str(), - DistributedData::Anonymous::Change(writePermission).c_str(), - DistributedData::Anonymous::Change(readPermission).c_str()); - return IPC_STUB_INVALID_DATA_ERR; - } - - int32_t status = CreateRDBTable(param, writePermission, readPermission); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return RDB_OK; -} - -int32_t RdbServiceStub::OnRemoteDoDestroyTable(MessageParcel &data, MessageParcel &reply) -{ - RdbSyncerParam param; - if (!ITypesUtil::Unmarshal(data, param)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); - return IPC_STUB_INVALID_DATA_ERR; - } - - int32_t status = DestroyRDBTable(param); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return RDB_OK; -} } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.h b/services/distributeddataservice/service/rdb/rdb_service_stub.h index 901a7d6e779d013968eb098a7bba2ddc7b2b5eaf..fbd2173a40ffc8a64c0ccce8ce216273371c86a6 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_stub.h +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -22,37 +22,23 @@ #include "feature/feature_system.h" namespace OHOS::DistributedRdb { +using RdbServiceCode = OHOS::DistributedRdb::RelationalStore::RdbServiceInterfaceCode; + class RdbServiceStub : public RdbService, public DistributedData::FeatureSystem::Feature { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.IRdbService"); int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; - int32_t Sync(const RdbSyncerParam& param, const SyncOption& option, - const RdbPredicates& predicates, const SyncCallback& callback) override - { - return 0; - } - - int32_t Subscribe(const RdbSyncerParam& param, const SubscribeOption& option, - RdbStoreObserver *observer) override - { - return 0; - } - - int32_t UnSubscribe(const RdbSyncerParam& param, const SubscribeOption& option, - RdbStoreObserver *observer) override - { - return 0; - } - private: static bool CheckInterfaceToken(MessageParcel& data); int32_t OnRemoteObtainDistributedTableName(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteInitNotifier(MessageParcel&data, MessageParcel& reply); + int32_t OnGetSchema(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteSetDistributedTables(MessageParcel &data, MessageParcel &reply); + int32_t OnRemoteInitNotifier(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteSetDistributedTables(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteDoSync(MessageParcel& data, MessageParcel& reply); @@ -64,22 +50,19 @@ private: int32_t OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteDoCreateTable(MessageParcel& data, MessageParcel& reply); - - int32_t OnRemoteDoDestroyTable(MessageParcel& data, MessageParcel& reply); - using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); - static constexpr RequestHandle HANDLERS[RDB_SERVICE_CMD_MAX] = { - [RDB_SERVICE_CMD_OBTAIN_TABLE] = &RdbServiceStub::OnRemoteObtainDistributedTableName, - [RDB_SERVICE_CMD_INIT_NOTIFIER] = &RdbServiceStub::OnRemoteInitNotifier, - [RDB_SERVICE_CMD_SET_DIST_TABLE] = &RdbServiceStub::OnRemoteSetDistributedTables, - [RDB_SERVICE_CMD_SYNC] = &RdbServiceStub::OnRemoteDoSync, - [RDB_SERVICE_CMD_ASYNC] = &RdbServiceStub::OnRemoteDoAsync, - [RDB_SERVICE_CMD_SUBSCRIBE] = &RdbServiceStub::OnRemoteDoSubscribe, - [RDB_SERVICE_CMD_UNSUBSCRIBE] = &RdbServiceStub::OnRemoteDoUnSubscribe, - [RDB_SERVICE_CMD_REMOTE_QUERY] = &RdbServiceStub::OnRemoteDoRemoteQuery, - [RDB_SERVICE_CREATE_RDB_TABLE] = &RdbServiceStub::OnRemoteDoCreateTable, - [RDB_SERVICE_DESTROY_RDB_TABLE] = &RdbServiceStub::OnRemoteDoDestroyTable + static constexpr RequestHandle HANDLERS[static_cast(RdbServiceCode::RDB_SERVICE_CMD_MAX)] = { + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_OBTAIN_TABLE)] = + &RdbServiceStub::OnRemoteObtainDistributedTableName, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_INIT_NOTIFIER)] = &RdbServiceStub::OnRemoteInitNotifier, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_DIST_TABLE)] = + &RdbServiceStub::OnRemoteSetDistributedTables, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_SYNC)] = &RdbServiceStub::OnRemoteDoSync, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_ASYNC)] = &RdbServiceStub::OnRemoteDoAsync, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_SUBSCRIBE)] = &RdbServiceStub::OnRemoteDoSubscribe, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNSUBSCRIBE)] = &RdbServiceStub::OnRemoteDoUnSubscribe, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_REMOTE_QUERY)] = &RdbServiceStub::OnRemoteDoRemoteQuery, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_SCHEMA)] = &RdbServiceStub::OnGetSchema }; }; } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp index 036eedb8d13c7bbed472b17b79cf4f3b14641233..e9e7ec53a4ae7f472a4b23c43a21b6eb53ac833f 100644 --- a/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp @@ -20,8 +20,8 @@ #include "log_print.h" namespace OHOS::DistributedRdb { -RdbStoreObserverImpl::RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid) - : pid_(pid), owner_(owner) +RdbStoreObserverImpl::RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid, uint32_t tokenId) + : pid_(pid), tokenId_(tokenId), owner_(owner) { ZLOGI("construct"); } @@ -35,7 +35,7 @@ void RdbStoreObserverImpl::OnChange(const DistributedDB::StoreChangedData &data) { ZLOGI("enter"); if (owner_ != nullptr) { - owner_->OnDataChange(pid_, data); + owner_->OnDataChange(pid_, tokenId_, data); } } } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h index e0043f5f96264cb5eddaf9519b7bb8340fa60719..0c7af901556e0eed9615a7b1e54a3d1902915959 100644 --- a/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h @@ -23,15 +23,16 @@ namespace OHOS::DistributedRdb { class RdbServiceImpl; class RdbStoreObserverImpl : public DistributedDB::StoreObserver { public: - explicit RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid = 0); + explicit RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid = 0, uint32_t tokenId = 0); ~RdbStoreObserverImpl() override; void OnChange(const DistributedDB::StoreChangedData &data) override; private: - pid_t pid_ {}; - RdbServiceImpl* owner_ {}; + pid_t pid_ = 0; + uint32_t tokenId_ = 0; + RdbServiceImpl* owner_ = nullptr; }; } // namespace OHOS::DistributedRdb #endif diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/services/distributeddataservice/service/rdb/rdb_syncer.cpp index f8f6192a1b6c967ef960d8d5aedfad5d92775000..9fbd7642d852d3158dbb2b92561e6fdbbd76da7e 100644 --- a/services/distributeddataservice/service/rdb/rdb_syncer.cpp +++ b/services/distributeddataservice/service/rdb/rdb_syncer.cpp @@ -20,21 +20,19 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "checker/checker_manager.h" +#include "cloud/change_event.h" #include "crypto_manager.h" #include "device_manager_adapter.h" -#include "directory_manager.h" -#include "kvstore_utils.h" +#include "eventcenter/event_center.h" #include "log_print.h" -#include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" -#include "metadata/store_meta_data.h" +#include "rdb_query.h" #include "rdb_result_set_impl.h" -#include "types.h" +#include "store/general_store.h" +#include "types_export.h" +#include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" -#include "types_export.h" - -using OHOS::DistributedKv::KvStoreUtils; using OHOS::DistributedKv::AccountDelegate; using namespace OHOS::Security::AccessToken; using namespace OHOS::DistributedData; @@ -46,13 +44,13 @@ namespace OHOS::DistributedRdb { RdbSyncer::RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer) : param_(param), observer_(observer) { - ZLOGI("construct %{public}s", param_.storeName_.c_str()); + ZLOGI("construct %{public}s", Anonymous::Change(param_.storeName_).c_str()); } RdbSyncer::~RdbSyncer() noexcept { param_.password_.assign(param_.password_.size(), 0); - ZLOGI("destroy %{public}s", param_.storeName_.c_str()); + ZLOGI("destroy %{public}s", Anonymous::Change(param_.storeName_).c_str()); if ((manager_ != nullptr) && (delegate_ != nullptr)) { manager_->CloseStore(delegate_); } @@ -102,105 +100,22 @@ std::string RdbSyncer::GetStoreId() const return RemoveSuffix(param_.storeName_); } -int32_t RdbSyncer::Init( - pid_t pid, pid_t uid, uint32_t token, const std::string &writePermission, const std::string &readPermission) +int32_t RdbSyncer::Init(pid_t pid, pid_t uid, uint32_t token, const StoreMetaData &meta) { ZLOGI("enter"); pid_ = pid; uid_ = uid; token_ = token; - StoreMetaData oldMeta; - StoreMetaData meta; - if (CreateMetaData(meta, oldMeta) != RDB_OK) { - ZLOGE("create meta data failed"); - return RDB_ERROR; - } if (InitDBDelegate(meta) != RDB_OK) { ZLOGE("delegate is nullptr"); return RDB_ERROR; } - if (oldMeta.storeType == RDB_DEVICE_COLLABORATION && oldMeta.version < StoreMetaData::UUID_CHANGED_TAG) { - delegate_->RemoveDeviceData(); - } - ZLOGI("success"); return RDB_OK; } -int32_t RdbSyncer::DestroyMetaData(StoreMetaData &meta) -{ - FillMetaData(meta); - auto deleted = MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true); - return deleted ? RDB_OK : RDB_ERROR; -} - -void RdbSyncer::FillMetaData(StoreMetaData &meta) -{ - meta.uid = uid_; - meta.tokenId = token_; - meta.instanceId = GetInstIndex(token_, param_.bundleName_); - meta.bundleName = param_.bundleName_; - meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - meta.storeId = RemoveSuffix(param_.storeName_); - meta.user = std::to_string(AccountDelegate::GetInstance()->GetUserByToken(token_)); - meta.storeType = param_.type_; - meta.securityLevel = param_.level_; - meta.area = param_.area_; - meta.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(meta)); - meta.appType = "harmony"; - meta.hapName = param_.hapName_; - meta.dataDir = DirectoryManager::GetInstance().GetStorePath(meta) + "/" + param_.storeName_; - meta.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); - meta.isEncrypt = param_.isEncrypt_; -} - -int32_t RdbSyncer::CreateMetaData(StoreMetaData &meta, StoreMetaData &old) -{ - FillMetaData(meta); - bool isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old); - if (isCreated && (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || - old.area != meta.area)) { - ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " - "area:%{public}d->%{public}d", - meta.bundleName.c_str(), meta.storeId.c_str(), old.storeType, meta.storeType, old.isEncrypt, - meta.isEncrypt, old.area, meta.area); - return RDB_ERROR; - } - - auto saved = MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta); - if (!saved) { - return RDB_ERROR; - } - AppIDMetaData appIdMeta; - appIdMeta.bundleName = meta.bundleName; - appIdMeta.appId = meta.appId; - saved = MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true); - if (!saved) { - return RDB_ERROR; - } - if (!param_.isEncrypt_ || param_.password_.empty()) { - return RDB_OK; - } - return SetSecretKey(meta); -} - -bool RdbSyncer::SetSecretKey(const StoreMetaData &meta) -{ - SecretKeyMetaData newSecretKey; - newSecretKey.storeType = meta.storeType; - newSecretKey.sKey = CryptoManager::GetInstance().Encrypt(param_.password_); - if (newSecretKey.sKey.empty()) { - ZLOGE("encrypt work key error."); - return RDB_ERROR; - } - param_.password_.assign(param_.password_.size(), 0); - auto time = system_clock::to_time_t(system_clock::now()); - newSecretKey.time = { reinterpret_cast(&time), reinterpret_cast(&time) + sizeof(time) }; - return MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), newSecretKey, true) ? RDB_OK : RDB_ERROR; -} - bool RdbSyncer::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) { if (!metaData.isEncrypt) { @@ -252,11 +167,11 @@ int32_t RdbSyncer::InitDBDelegate(const StoreMetaData &meta) } option.observer = observer_; std::string fileName = meta.dataDir; - ZLOGI("path=%{public}s storeId=%{public}s", fileName.c_str(), meta.storeId.c_str()); + ZLOGI("path=%{public}s storeId=%{public}s", Anonymous::Change(fileName).c_str(), meta.GetStoreAlias().c_str()); auto status = manager_->OpenStore(fileName, meta.storeId, option, delegate_); if (status != DistributedDB::DBStatus::OK) { ZLOGE("open store failed, path=%{public}s storeId=%{public}s status=%{public}d", - fileName.c_str(), meta.storeId.c_str(), status); + Anonymous::Change(fileName).c_str(), meta.GetStoreAlias().c_str(), status); return RDB_ERROR; } ZLOGI("open store success"); @@ -265,10 +180,10 @@ int32_t RdbSyncer::InitDBDelegate(const StoreMetaData &meta) return RDB_OK; } -int32_t RdbSyncer::GetInstIndex(uint32_t tokenId, const std::string &bundleName) +std::pair RdbSyncer::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName) { if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { - return 0; + return { 0, 0 }; } HapTokenInfo tokenInfo; @@ -277,9 +192,9 @@ int32_t RdbSyncer::GetInstIndex(uint32_t tokenId, const std::string &bundleName) if (errCode != RET_SUCCESS) { ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId, bundleName.c_str()); - return -1; + return { -1, -1 }; } - return tokenInfo.instIndex; + return { tokenInfo.instIndex, tokenInfo.userID }; } DistributedDB::RelationalStoreDelegate* RdbSyncer::GetDelegate() @@ -288,7 +203,7 @@ DistributedDB::RelationalStoreDelegate* RdbSyncer::GetDelegate() return delegate_; } -int32_t RdbSyncer::SetDistributedTables(const std::vector &tables) +int32_t RdbSyncer::SetDistributedTables(const std::vector &tables, int32_t type) { auto* delegate = GetDelegate(); if (delegate == nullptr) { @@ -298,7 +213,7 @@ int32_t RdbSyncer::SetDistributedTables(const std::vector &tables) for (const auto& table : tables) { ZLOGI("%{public}s", table.c_str()); - auto dBStatus = delegate->CreateDistributedTable(table); + auto dBStatus = delegate->CreateDistributedTable(table, static_cast(type)); if (dBStatus != DistributedDB::DBStatus::OK) { ZLOGE("create distributed table failed, table:%{public}s, err:%{public}d", table.c_str(), dBStatus); return RDB_ERROR; @@ -317,7 +232,7 @@ std::vector RdbSyncer::GetConnectDevices() } ZLOGI("size=%{public}u", static_cast(devices.size())); for (const auto& device: devices) { - ZLOGI("%{public}s", KvStoreUtils::ToBeAnonymous(device).c_str()); + ZLOGI("%{public}s", Anonymous::Change(device).c_str()); } return devices; } @@ -328,19 +243,18 @@ std::vector RdbSyncer::NetworkIdToUUID(const std::vector %{public}s", KvStoreUtils::ToBeAnonymous(networkId).c_str(), - KvStoreUtils::ToBeAnonymous(uuid).c_str()); + ZLOGI("%{public}s <--> %{public}s", Anonymous::Change(networkId).c_str(), Anonymous::Change(uuid).c_str()); } return uuids; } -void RdbSyncer::HandleSyncStatus(const std::map> &syncStatus, - SyncResult &result) +Details RdbSyncer::HandleSyncStatus(const std::map> &syncStatus) { + Details details; for (const auto& status : syncStatus) { auto res = DistributedDB::DBStatus::OK; for (const auto& tableStatus : status.second) { @@ -355,9 +269,27 @@ void RdbSyncer::HandleSyncStatus(const std::map 1) { + query.FromTable(predicates.tables_); + } for (const auto& operation : predicates.operations_) { if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) { HANDLES[operation.operator_](operation, query); @@ -416,7 +352,7 @@ DistributedDB::Query RdbSyncer::MakeQuery(const RdbPredicates &predicates) return query; } -int32_t RdbSyncer::DoSync(const SyncOption &option, const RdbPredicates &predicates, SyncResult &result) +int32_t RdbSyncer::DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { ZLOGI("enter"); auto* delegate = GetDelegate(); @@ -425,42 +361,39 @@ int32_t RdbSyncer::DoSync(const SyncOption &option, const RdbPredicates &predica return RDB_ERROR; } - std::vector devices; - if (predicates.devices_.empty()) { - devices = NetworkIdToUUID(GetConnectDevices()); - } else { - devices = NetworkIdToUUID(predicates.devices_); - } - - ZLOGI("delegate sync"); - return delegate->Sync(devices, static_cast(option.mode), - MakeQuery(predicates), [&result] (const auto& syncStatus) { - HandleSyncStatus(syncStatus, result); - }, true); -} - -int32_t RdbSyncer::DoAsync(const SyncOption &option, const RdbPredicates &predicates, const SyncCallback& callback) -{ - auto* delegate = GetDelegate(); - if (delegate == nullptr) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } + if (option.mode < DistributedData::GeneralStore::NEARBY_END) { + auto &networkIds = predicates.devices_; + auto devices = networkIds.empty() ? NetworkIdToUUID(GetConnectDevices()) : NetworkIdToUUID(networkIds); + return delegate->Sync( + devices, static_cast(option.mode), MakeQuery(predicates), + [async](const std::map> &syncStatus) { + if (async != nullptr) { + async(HandleSyncStatus(syncStatus)); + } + }, + !option.isAsync); + } else if (option.mode < DistributedData::GeneralStore::CLOUD_END && + option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) { + CloudEvent::StoreInfo storeInfo; + storeInfo.bundleName = GetBundleName(); + storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(token_); + storeInfo.storeName = GetStoreId(); + storeInfo.tokenId = token_; + std::shared_ptr query = nullptr; + if (!predicates.tables_.empty()) { + query = std::make_shared(); + query->query_.FromTable(predicates.tables_); + } - std::vector devices; - if (predicates.devices_.empty()) { - devices = NetworkIdToUUID(GetConnectDevices()); - } else { - devices = NetworkIdToUUID(predicates.devices_); + auto info = ChangeEvent::EventInfo(option.mode, (option.isAsync ? 0 : WAIT_TIME), + (option.isAsync && option.seqNum == 0), query, [async](const GenDetails &details) { + async(HandleGenDetails(details)); + }); + auto evt = std::make_unique(std::move(storeInfo), std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); } - ZLOGI("delegate sync"); - return delegate->Sync(devices, static_cast(option.mode), - MakeQuery(predicates), [callback] (const auto& syncStatus) { - SyncResult result; - HandleSyncStatus(syncStatus, result); - callback(result); - }, false); + return RDB_OK; } int32_t RdbSyncer::RemoteQuery(const std::string& device, const std::string& sql, @@ -488,4 +421,19 @@ int32_t RdbSyncer::RemoteQuery(const std::string& device, const std::string& sql } return RDB_OK; } + +int32_t RdbSyncer::RemoveDeviceData() +{ + auto* delegate = GetDelegate(); + if (delegate == nullptr) { + ZLOGE("delegate is nullptr"); + return RDB_ERROR; + } + DistributedDB::DBStatus status = delegate->RemoveDeviceData(); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("DistributedDB RemoveDeviceData failed, status is %{public}d.", status); + return RDB_ERROR; + } + return RDB_OK; +} } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.h b/services/distributeddataservice/service/rdb/rdb_syncer.h index 42602bdbb83f3547ac249b955e11a853310866e0..11983e8df95341daa6380967692f3f2a0ff2c2de 100644 --- a/services/distributeddataservice/service/rdb/rdb_syncer.h +++ b/services/distributeddataservice/service/rdb/rdb_syncer.h @@ -18,24 +18,28 @@ #include #include +#include +#include "iremote_object.h" +#include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data.h" +#include "rdb_service.h" #include "rdb_store_observer_impl.h" #include "rdb_types.h" #include "relational_store_delegate.h" #include "relational_store_manager.h" -#include "metadata/secret_key_meta_data.h" -#include "iremote_object.h" +#include "store/general_value.h" namespace OHOS::DistributedRdb { class RdbSyncer { public: using StoreMetaData = OHOS::DistributedData::StoreMetaData; + using GenDetails = OHOS::DistributedData::GenDetails; using SecretKeyMetaData = DistributedData::SecretKeyMetaData; + using Option = DistributedRdb::RdbService::Option; RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer); ~RdbSyncer() noexcept; - int32_t Init(pid_t pid, pid_t uid, uint32_t token, const std::string &writePermission = "", - const std::string &readPermission = ""); + int32_t Init(pid_t pid, pid_t uid, uint32_t token, const StoreMetaData &meta); pid_t GetPid() const; @@ -47,22 +51,23 @@ public: std::string GetIdentifier() const; - int32_t SetDistributedTables(const std::vector& tables); + int32_t SetDistributedTables(const std::vector &tables, int32_t type); - int32_t DoSync(const SyncOption& option, const RdbPredicates& predicates, SyncResult& result); - - int32_t DoAsync(const SyncOption& option, const RdbPredicates& predicates, const SyncCallback& callback); + int32_t DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); int32_t RemoteQuery(const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet); - int32_t DestroyMetaData(StoreMetaData &meta); + int32_t RemoveDeviceData(); + static std::string RemoveSuffix(const std::string& name); - static int32_t GetInstIndex(uint32_t tokenId, const std::string &bundleName); + static std::pair GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName); static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); + static DistributedDB::Query MakeQuery(const PredicatesMemo &predicates); + private: std::string GetUserId() const; @@ -70,10 +75,7 @@ private: std::string GetAppId() const; - int32_t CreateMetaData(StoreMetaData &meta, StoreMetaData &old); - void FillMetaData(StoreMetaData &meta); int32_t InitDBDelegate(const StoreMetaData &meta); - bool SetSecretKey(const StoreMetaData &meta); DistributedDB::RelationalStoreDelegate* GetDelegate(); @@ -90,9 +92,8 @@ private: static std::vector GetConnectDevices(); static std::vector NetworkIdToUUID(const std::vector& networkIds); - static void HandleSyncStatus(const std::map>& SyncStatus, - SyncResult& result); - static DistributedDB::Query MakeQuery(const RdbPredicates& predicates); + static Details HandleSyncStatus(const std::map> &syncStatus); + static Details HandleGenDetails(const GenDetails &details); static void EqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); static void NotEqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); static void And(const RdbPredicateOperation& operation, DistributedDB::Query& query); @@ -112,6 +113,7 @@ private: static constexpr int DECIMAL_BASE = 10; static constexpr uint64_t REMOTE_QUERY_TIME_OUT = 30 * 1000; + static constexpr int32_t WAIT_TIME = 30 * 1000; }; } // namespace OHOS::DistributedRdb #endif diff --git a/services/distributeddataservice/service/rdb/rdb_watcher.cpp b/services/distributeddataservice/service/rdb/rdb_watcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0d4d0ed9ab07b23d9583bc01495a89cc609f64a --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_watcher.cpp @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#define LOG_TAG "RdbWatcher" + +#include "rdb_watcher.h" + +#include "error/general_error.h" +#include "log_print.h" + +namespace OHOS::DistributedRdb { +using namespace DistributedData; +using Error = DistributedData::GeneralError; +RdbWatcher::RdbWatcher() +{ +} + +int32_t RdbWatcher::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) +{ + auto notifier = GetNotifier(); + if (notifier == nullptr) { + return E_NOT_INIT; + } + DistributedRdb::Origin rdbOrigin; + rdbOrigin.origin = origin.origin; + rdbOrigin.dataType = origin.dataType; + rdbOrigin.id = origin.id; + rdbOrigin.store = origin.store; + notifier->OnChange(rdbOrigin, primaryFields, std::move(values)); + return E_OK; +} + +sptr RdbWatcher::GetNotifier() const +{ + std::shared_lock lock(mutex_); + return notifier_; +} + +void RdbWatcher::SetNotifier(sptr notifier) +{ + std::unique_lock lock(mutex_); + if (notifier_ == notifier) { + return; + } + notifier_ = notifier; +} +} // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_watcher.h b/services/distributeddataservice/service/rdb/rdb_watcher.h new file mode 100644 index 0000000000000000000000000000000000000000..ac898854cc78388438aed56e8718f74ee0053ae6 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_watcher.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_WATCHER_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_WATCHER_H +#include +#include +#include "rdb_notifier_proxy.h" +#include "store/general_value.h" +#include "store/general_watcher.h" + +namespace OHOS::DistributedRdb { +class RdbWatcher : public DistributedData::GeneralWatcher { +public: + RdbWatcher(); + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; + sptr GetNotifier() const; + void SetNotifier(sptr notifier); + +private: + mutable std::shared_mutex mutex_; + sptr notifier_; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_WATCHER_H diff --git a/services/distributeddataservice/service/rdb/value_proxy.cpp b/services/distributeddataservice/service/rdb/value_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f87ef75bb10bb27b0dcc9813afac667ffd4fdb1f --- /dev/null +++ b/services/distributeddataservice/service/rdb/value_proxy.cpp @@ -0,0 +1,390 @@ +/* + * 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. + */ + +#define LOG_TAG "ValueProxy" +#include "value_proxy.h" +namespace OHOS::DistributedRdb { +using namespace OHOS::DistributedData; +ValueProxy::Value ValueProxy::Convert(DistributedData::Value &&value) +{ + Value proxy; + DistributedData::Convert(std::move(value), proxy.value_); + return proxy; +} + +ValueProxy::Value ValueProxy::Convert(NativeRdb::ValueObject &&value) +{ + Value proxy; + DistributedData::Convert(std::move(value.value), proxy.value_); + return proxy; +} + +ValueProxy::Value ValueProxy::Convert(DistributedDB::Type &&value) +{ + Value proxy; + DistributedData::Convert(std::move(value), proxy.value_); + return proxy; +} + +ValueProxy::Values ValueProxy::Convert(DistributedData::Values &&values) +{ + Values proxy; + proxy.value_.reserve(values.size()); + for (auto &value : values) { + proxy.value_.emplace_back(Convert(std::move(value))); + } + return proxy; +} + +ValueProxy::Values ValueProxy::Convert(std::vector &&values) +{ + Values proxy; + proxy.value_.reserve(values.size()); + for (auto &value : values) { + proxy.value_.emplace_back(Convert(std::move(value))); + } + return proxy; +} + +ValueProxy::Bucket ValueProxy::Convert(DistributedData::VBucket &&bucket) +{ + ValueProxy::Bucket proxy; + for (auto &[key, value] : bucket) { + proxy.value_.insert_or_assign(key, Convert(std::move(value))); + } + return proxy; +} + +ValueProxy::Bucket ValueProxy::Convert(NativeRdb::ValuesBucket &&bucket) +{ + ValueProxy::Bucket proxy; + for (auto &[key, value] : bucket.values_) { + proxy.value_.insert_or_assign(key, Convert(std::move(value))); + } + return proxy; +} + +ValueProxy::Bucket ValueProxy::Convert(DistributedDB::VBucket &&bucket) +{ + ValueProxy::Bucket proxy; + for (auto &[key, value] : bucket) { + proxy.value_.insert_or_assign(key, Convert(std::move(value))); + } + return proxy; +} + +ValueProxy::Buckets ValueProxy::Convert(std::vector &&buckets) +{ + ValueProxy::Buckets proxy; + proxy.value_.reserve(buckets.size()); + for (auto &bucket : buckets) { + proxy.value_.emplace_back(Convert(std::move(bucket))); + } + return proxy; +} + +ValueProxy::Buckets ValueProxy::Convert(std::vector &&buckets) +{ + ValueProxy::Buckets proxy; + proxy.value_.reserve(buckets.size()); + for (auto &bucket : buckets) { + proxy.value_.emplace_back(Convert(std::move(bucket))); + } + return proxy; +} + +ValueProxy::Buckets ValueProxy::Convert(DistributedData::VBuckets &&buckets) +{ + ValueProxy::Buckets proxy; + proxy.value_.reserve(buckets.size()); + for (auto &bucket : buckets) { + proxy.value_.emplace_back(Convert(std::move(bucket))); + } + return proxy; +} + +ValueProxy::Asset::Asset(DistributedData::Asset asset) +{ + asset_ = std::move(asset); +} + +ValueProxy::Asset::Asset(NativeRdb::AssetValue asset) +{ + asset_ = DistributedData::Asset { .version = asset.version, + .status = asset.status, + .expiresTime = asset.expiresTime, + .id = std::move(asset.id), + .name = std::move(asset.name), + .uri = std::move(asset.uri), + .createTime = std::move(asset.createTime), + .modifyTime = std::move(asset.modifyTime), + .size = std::move(asset.size), + .hash = std::move(asset.hash), + .path = std::move(asset.path) }; +} + +ValueProxy::Asset::Asset(DistributedDB::Asset asset) +{ + asset_ = DistributedData::Asset { .version = asset.version, + .status = ConvertToDataStatus(asset), + .expiresTime = DistributedData::Asset::NO_EXPIRES_TIME, + .id = std::move(asset.assetId), + .name = std::move(asset.name), + .uri = std::move(asset.uri), + .createTime = std::move(asset.createTime), + .modifyTime = std::move(asset.modifyTime), + .size = std::move(asset.size), + .hash = std::move(asset.hash), + .path = std::move(asset.subpath) }; +} + +ValueProxy::Asset &ValueProxy::Asset::operator=(const Asset &proxy) +{ + if (this == &proxy) { + return *this; + } + asset_ = proxy.asset_; + return *this; +} + +ValueProxy::Asset &ValueProxy::Asset::operator=(Asset &&proxy) noexcept +{ + if (this == &proxy) { + return *this; + } + asset_ = std::move(proxy); + return *this; +} + +ValueProxy::Asset::operator NativeRdb::AssetValue() +{ + return NativeRdb::AssetValue { .version = asset_.version, + .status = asset_.status, + .expiresTime = asset_.expiresTime, + .id = std::move(asset_.id), + .name = std::move(asset_.name), + .uri = std::move(asset_.uri), + .createTime = std::move(asset_.createTime), + .modifyTime = std::move(asset_.modifyTime), + .size = std::move(asset_.size), + .hash = std::move(asset_.hash), + .path = std::move(asset_.path) }; +} + +ValueProxy::Asset::operator DistributedData::Asset() +{ + return std::move(asset_); +} + +ValueProxy::Asset::operator DistributedDB::Asset() +{ + return DistributedDB::Asset { .version = asset_.version, + .name = std::move(asset_.name), + .assetId = std::move(asset_.id), + .subpath = std::move(asset_.path), + .uri = std::move(asset_.uri), + .modifyTime = std::move(asset_.modifyTime), + .createTime = std::move(asset_.createTime), + .size = std::move(asset_.size), + .hash = std::move(asset_.hash), + .status = ConvertToDBStatus(asset_) }; +} + +uint32_t ValueProxy::Asset::ConvertToDataStatus(const DistributedDB::Asset &asset) +{ + if (asset.status == DistributedDB::AssetStatus::DOWNLOADING) { + if (asset.flag == static_cast(DistributedDB::AssetOpType::DELETE)) { + return DistributedData::Asset::STATUS_DELETE; + } + return DistributedData::Asset::STATUS_DOWNLOADING; + } else if (asset.status == DistributedDB::AssetStatus::ABNORMAL) { + return DistributedData::Asset::STATUS_ABNORMAL; + } else { + switch (asset.flag) { + case static_cast(DistributedDB::AssetOpType::INSERT): + return DistributedData::Asset::STATUS_INSERT; + case static_cast(DistributedDB::AssetOpType::UPDATE): + return DistributedData::Asset::STATUS_UPDATE; + case static_cast(DistributedDB::AssetOpType::DELETE): + return DistributedData::Asset::STATUS_DELETE; + default: + return DistributedData::Asset::STATUS_NORMAL; + } + } + return DistributedData::Asset::STATUS_UNKNOWN; +} + +uint32_t ValueProxy::Asset::ConvertToDBStatus(const DistributedData::Asset &asset) +{ + switch (asset.status) { + case DistributedData::Asset::STATUS_NORMAL: + return static_cast(DistributedDB::AssetStatus::NORMAL); + case DistributedData::Asset::STATUS_ABNORMAL: + return static_cast(DistributedDB::AssetStatus::ABNORMAL); + case DistributedData::Asset::STATUS_INSERT: + return static_cast(DistributedDB::AssetStatus::INSERT); + case DistributedData::Asset::STATUS_UPDATE: + return static_cast(DistributedDB::AssetStatus::UPDATE); + case DistributedData::Asset::STATUS_DELETE: + return static_cast(DistributedDB::AssetStatus::DELETE); + case DistributedData::Asset::STATUS_DOWNLOADING: + return static_cast(DistributedDB::AssetStatus::DOWNLOADING); + default: + return static_cast(DistributedDB::AssetStatus::NORMAL); + } +} + +ValueProxy::Assets::Assets(DistributedData::Assets assets) +{ + assets_.clear(); + assets_.reserve(assets.size()); + for (auto &asset : assets) { + assets_.emplace_back(std::move(asset)); + } +} + +ValueProxy::Assets::Assets(NativeRdb::ValueObject::Assets assets) +{ + assets_.clear(); + assets_.reserve(assets.size()); + for (auto &asset : assets) { + assets_.emplace_back(std::move(asset)); + } +} + +ValueProxy::Assets::Assets(DistributedDB::Assets assets) +{ + assets_.clear(); + assets_.reserve(assets.size()); + for (auto &asset : assets) { + assets_.emplace_back(std::move(asset)); + } +} + +ValueProxy::Assets &ValueProxy::Assets::operator=(const Assets &proxy) +{ + if (this == &proxy) { + return *this; + } + assets_ = proxy.assets_; + return *this; +} + +ValueProxy::Assets &ValueProxy::Assets::operator=(Assets &&proxy) noexcept +{ + if (this == &proxy) { + return *this; + } + assets_ = std::move(proxy.assets_); + return *this; +} + +ValueProxy::Assets::operator NativeRdb::ValueObject::Assets() +{ + NativeRdb::ValueObject::Assets assets; + assets.reserve(assets_.size()); + for (auto &asset : assets_) { + assets.push_back(std::move(asset)); + } + return assets; +} + +ValueProxy::Assets::operator DistributedData::Assets() +{ + DistributedData::Assets assets; + assets.reserve(assets_.size()); + for (auto &asset : assets_) { + assets.push_back(std::move(asset)); + } + return assets; +} + +ValueProxy::Assets::operator DistributedDB::Assets() +{ + DistributedDB::Assets assets; + assets.reserve(assets_.size()); + for (auto &asset : assets_) { + assets.push_back(std::move(asset)); + } + return assets; +} + +ValueProxy::Value &ValueProxy::Value::operator=(ValueProxy::Value &&value) noexcept +{ + if (this == &value) { + return *this; + } + value_ = std::move(value.value_); + return *this; +} + +ValueProxy::Value::operator NativeRdb::ValueObject() +{ + NativeRdb::ValueObject object; + DistributedData::Convert(std::move(value_), object.value); + return object; +} + +ValueProxy::Value::operator DistributedData::Value() +{ + DistributedData::Value value; + DistributedData::Convert(std::move(value_), value); + return value; +} + +ValueProxy::Value::operator DistributedDB::Type() +{ + DistributedDB::Type value; + DistributedData::Convert(std::move(value_), value); + return value; +} + +ValueProxy::Values &ValueProxy::Values::operator=(ValueProxy::Values &&values) noexcept +{ + if (this == &values) { + return *this; + } + value_ = std::move(values.value_); + return *this; +} + +ValueProxy::Bucket &ValueProxy::Bucket::operator=(Bucket &&bucket) noexcept +{ + if (this == &bucket) { + return *this; + } + value_ = std::move(bucket.value_); + return *this; +} + +ValueProxy::Bucket::operator NativeRdb::ValuesBucket() +{ + NativeRdb::ValuesBucket bucket; + for (auto &[key, value] : value_) { + bucket.values_.insert_or_assign(key, std::move(value)); + } + value_.clear(); + return bucket; +} + +ValueProxy::Buckets &ValueProxy::Buckets::operator=(Buckets &&buckets) noexcept +{ + if (this == &buckets) { + return *this; + } + value_ = std::move(buckets.value_); + return *this; +} +} // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/value_proxy.h b/services/distributeddataservice/service/rdb/value_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..3c351ee58ad9f30fa04b27b7f12143e5a19bb56c --- /dev/null +++ b/services/distributeddataservice/service/rdb/value_proxy.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H +#include "asset_value.h" +#include "cloud/cloud_store_types.h" +#include "store/general_value.h" +#include "value_object.h" +#include "values_bucket.h" +namespace OHOS::DistributedRdb { +class ValueProxy final { +public: + template + static inline constexpr uint32_t INDEX = DistributedData::TYPE_INDEX; + static inline constexpr uint32_t MAX = DistributedData::TYPE_MAX; + + template + struct variant_cvt_of { + static constexpr size_t value = std::is_class_v ? Traits::convertible_index_of_v + : Traits::same_index_of_v; + }; + + template + static variant_cvt_of variant_cvt_test(const T &, const std::variant &); + + template + static inline constexpr uint32_t CVT_INDEX = + decltype(variant_cvt_test(std::declval(), std::declval()))::value; + + using Bytes = DistributedData::Bytes; + class Asset { + public: + Asset() = default; + Asset(Asset &&proxy) noexcept + { + *this = std::move(proxy); + }; + Asset(const Asset &proxy) + { + *this = proxy; + }; + Asset(DistributedData::Asset asset); + Asset(NativeRdb::AssetValue asset); + Asset(DistributedDB::Asset asset); + Asset &operator=(const Asset &proxy); + Asset &operator=(Asset &&proxy) noexcept; + operator NativeRdb::AssetValue(); + operator DistributedData::Asset(); + operator DistributedDB::Asset(); + static uint32_t ConvertToDataStatus(const DistributedDB::Asset &asset); + static uint32_t ConvertToDBStatus(const DistributedData::Asset &asset); + + private: + DistributedData::Asset asset_; + }; + + class Assets { + public: + Assets() = default; + Assets(Assets &&proxy) noexcept + { + *this = std::move(proxy); + }; + Assets(const Assets &proxy) + { + *this = proxy; + }; + Assets(DistributedData::Assets assets); + Assets(NativeRdb::ValueObject::Assets assets); + Assets(DistributedDB::Assets assets); + Assets &operator=(const Assets &proxy); + Assets &operator=(Assets &&proxy) noexcept; + operator NativeRdb::ValueObject::Assets(); + operator DistributedData::Assets(); + operator DistributedDB::Assets(); + + private: + std::vector assets_; + }; + using Proxy = std::variant; + + class Value { + public: + Value() = default; + Value(Value &&value) noexcept + { + *this = std::move(value); + }; + Value &operator=(Value &&value) noexcept; + operator NativeRdb::ValueObject(); + operator DistributedData::Value(); + operator DistributedDB::Type(); + + template + operator T() noexcept + { + auto val = Traits::get_if(&value_); + if (val != nullptr) { + return T(std::move(*val)); + } + return T(); + }; + + private: + friend ValueProxy; + Proxy value_; + }; + class Values { + public: + Values() = default; + Values(Values &&values) noexcept + { + *this = std::move(values); + }; + Values &operator=(Values &&values) noexcept; + template + operator std::vector() + { + std::vector objects; + objects.reserve(value_.size()); + for (auto &proxy : value_) { + objects.emplace_back(std::move(proxy)); + } + value_.clear(); + return objects; + } + + private: + friend ValueProxy; + std::vector value_; + }; + class Bucket { + public: + Bucket() = default; + Bucket(Bucket &&bucket) noexcept + { + *this = std::move(bucket); + }; + Bucket &operator=(Bucket &&bucket) noexcept; + template + operator std::map() + { + std::map bucket; + for (auto &[key, value] : value_) { + bucket.insert_or_assign(key, std::move(static_cast(value))); + } + value_.clear(); + return bucket; + } + operator NativeRdb::ValuesBucket(); + + private: + friend ValueProxy; + std::map value_; + }; + class Buckets { + public: + Buckets() = default; + Buckets(Buckets &&buckets) noexcept + { + *this = std::move(buckets); + }; + Buckets &operator=(Buckets &&buckets) noexcept; + template + operator std::vector() + { + std::vector buckets; + buckets.reserve(value_.size()); + for (auto &bucket : value_) { + buckets.emplace_back(std::move(bucket)); + } + value_.clear(); + return buckets; + } + + private: + friend ValueProxy; + std::vector value_; + }; + static Value Convert(DistributedData::Value &&value); + static Value Convert(NativeRdb::ValueObject &&value); + static Value Convert(DistributedDB::Type &&value); + static Values Convert(DistributedData::Values &&values); + static Values Convert(std::vector &&values); + static Bucket Convert(DistributedData::VBucket &&bucket); + static Bucket Convert(NativeRdb::ValuesBucket &&bucket); + static Bucket Convert(DistributedDB::VBucket &&bucket); + static Buckets Convert(DistributedData::VBuckets &&buckets); + static Buckets Convert(std::vector &&buckets); + static Buckets Convert(std::vector &&buckets); + + template + static std::enable_if_t < CVT_INDEX + Convert(const std::map &values) + { + Bucket bucket; + for (auto &[key, value] : values) { + bucket.value_[key].value_ = static_cast, Proxy>>(value); + } + return bucket; + } + +private: + ValueProxy() = delete; + ~ValueProxy() = delete; +}; +} // namespace OHOS::DistributedRdb +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 70ad6fddbf99bd05d4b6dbd047e361a6af889c04..a951e0527c4b498c927e5e078046c1fc75bfdbd4 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos_var.gni") import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") module_output_path = "datamgr_service/distributeddatafwk" @@ -26,6 +27,7 @@ config("module_private_config") { "../crypto/include/", "../directory/include/", "../matrix/include/", + "../rdb/", "../../framework/include/", ] @@ -35,6 +37,68 @@ config("module_private_config") { ] } +ohos_unittest("CloudDataTest") { + module_out_path = module_output_path + sources = [ + "cloud_data_test.cpp", + "mock/db_change_data_mock.cpp", + "mock/db_store_mock.cpp", + ] + + include_dirs = + [ "../../../../../relational_store/interfaces/inner_api/rdb/include" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${kv_store_distributeddb_path}:distributeddb", + "../../adapter:distributeddata_adapter", + "../../framework:distributeddatasvcfwk", + "../../service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + +ohos_unittest("ValueProxyTest") { + module_out_path = module_output_path + sources = [ + "../rdb/value_proxy.cpp", + "value_proxy_test.cpp", + ] + + include_dirs = + [ "../../../../../relational_store/interfaces/inner_api/rdb/include" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${kv_store_distributeddb_path}:distributeddb", + "${relational_store_inner_api_path}:native_rdb_static", + "../../adapter:distributeddata_adapter", + "../../framework:distributeddatasvcfwk", + "../../service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ohos_unittest("ConfigFactoryTest") { module_out_path = module_output_path sources = [ "config_factory_test.cpp" ] @@ -45,7 +109,7 @@ ohos_unittest("ConfigFactoryTest") { "ability_base:base", "ability_base:want", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -71,7 +135,7 @@ ohos_unittest("DirectoryManagerTest") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -96,7 +160,7 @@ ohos_unittest("CryptoManagerTest") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -125,7 +189,7 @@ ohos_unittest("DeviceMatrixTest") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -146,10 +210,12 @@ group("unittest") { deps = [] deps += [ + ":CloudDataTest", ":ConfigFactoryTest", ":CryptoManagerTest", ":DeviceMatrixTest", ":DirectoryManagerTest", + ":ValueProxyTest", ] } ############################################################################### diff --git a/services/distributeddataservice/service/test/cloud_data_test.cpp b/services/distributeddataservice/service/test/cloud_data_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8500014ed5f2fee7e61bd3d9005e0d6f29481e6 --- /dev/null +++ b/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -0,0 +1,198 @@ +/* +* 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. +*/ +#define LOG_TAG "CloudDataTest" +#include +#include "log_print.h" +#include "ipc_skeleton.h" +#include "account/account_delegate.h" +#include "cloud/cloud_event.h" +#include "cloud/cloud_server.h" +#include "cloud/schema_meta.h" +#include "communicator/device_manager_adapter.h" +#include "device_matrix.h" +#include "eventcenter/event_center.h" +#include "feature/feature_system.h" +#include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "mock/db_store_mock.h" +#include "rdb_types.h" +using namespace testing::ext; +using namespace OHOS::DistributedData; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; + +namespace OHOS::Test { +namespace DistributedDataTest { +static constexpr const char *TEST_CLOUD_BUNDLE = "test_cloud_bundleName"; +static constexpr const char *TEST_CLOUD_APPID = "test_cloud_appid"; +static constexpr const char *TEST_CLOUD_STORE = "test_cloud_database_name"; +class CloudDataTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static SchemaMeta schemaMeta_; +protected: + static constexpr const char *TEST_DISTRIBUTEDDATA_BUNDLE = "test_distributeddata"; + static constexpr const char *TEST_DISTRIBUTEDDATA_STORE = "test_service_meta"; + + void InitMetaData(); + void InitSchemaMeta(); + static std::shared_ptr dbStoreMock_; + StoreMetaData metaData_; +}; + +class CloudServerMock : public CloudServer { +public: + CloudInfo GetServerInfo(int32_t userId) override; + SchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName) override; + virtual ~CloudServerMock() = default; + static constexpr uint64_t REMAINSPACE = 1000; + static constexpr uint64_t TATALSPACE = 2000; +}; + +CloudInfo CloudServerMock::GetServerInfo(int32_t userId) +{ + CloudInfo cloudInfo; + cloudInfo.user = userId; + cloudInfo.id = "test_cloud_id"; + cloudInfo.remainSpace = REMAINSPACE; + cloudInfo.totalSpace = TATALSPACE; + cloudInfo.enableCloud = true; + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + appInfo.appId = TEST_CLOUD_APPID; + appInfo.version = 1; + appInfo.cloudSwitch = true; + + cloudInfo.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo); + return cloudInfo; +} + +SchemaMeta CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) +{ + return CloudDataTest::schemaMeta_; +} + +std::shared_ptr CloudDataTest::dbStoreMock_ = std::make_shared(); +SchemaMeta CloudDataTest::schemaMeta_; + +void CloudDataTest::InitMetaData() +{ + metaData_.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + metaData_.appId = TEST_DISTRIBUTEDDATA_BUNDLE; + metaData_.bundleName = TEST_DISTRIBUTEDDATA_BUNDLE; + metaData_.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + metaData_.user = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId)); + metaData_.area = OHOS::DistributedKv::EL1; + metaData_.instanceId = 0; + metaData_.isAutoSync = true; + metaData_.storeType = 1; + metaData_.storeId = TEST_DISTRIBUTEDDATA_STORE; + PolicyValue value; + value.type = OHOS::DistributedKv::PolicyType::IMMEDIATE_SYNC_ON_ONLINE; +} + +void CloudDataTest::InitSchemaMeta() +{ + SchemaMeta::Field field1; + field1.colName = "test_cloud_field_name1"; + field1.alias = "test_cloud_field_alias1"; + SchemaMeta::Field field2; + field2.colName = "test_cloud_field_name2"; + field2.alias = "test_cloud_field_alias2"; + + SchemaMeta::Table table; + table.name = "test_cloud_table_name"; + table.alias = "test_cloud_table_alias"; + table.fields.emplace_back(field1); + table.fields.emplace_back(field2); + + SchemaMeta::Database database; + database.name = TEST_CLOUD_STORE; + database.alias = "test_cloud_database_alias"; + database.tables.emplace_back(table); + + schemaMeta_.version = 1; + schemaMeta_.bundleName = TEST_DISTRIBUTEDDATA_BUNDLE; + schemaMeta_.databases.emplace_back(database); +} + +void CloudDataTest::SetUpTestCase(void) +{ + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, [](const auto &, auto) { + DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); + }); + + auto cloudServerMock = new CloudServerMock(); + CloudServer::RegisterCloudInstance(cloudServerMock); + FeatureSystem::GetInstance().GetCreator("cloud")(); + FeatureSystem::GetInstance().GetCreator("relational_store")(); +} + +void CloudDataTest::TearDownTestCase() {} + +void CloudDataTest::SetUp() +{ + InitMetaData(); + InitSchemaMeta(); + + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_); + + StoreMetaData storeMetaData; + storeMetaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + storeMetaData.bundleName = TEST_CLOUD_BUNDLE; + storeMetaData.storeId = TEST_CLOUD_STORE; + storeMetaData.instanceId = 0; + storeMetaData.isAutoSync = true; + storeMetaData.storeType = DistributedRdb::RDB_DEVICE_COLLABORATION; + storeMetaData.area = OHOS::DistributedKv::EL1; + storeMetaData.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + storeMetaData.user = + std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(storeMetaData.tokenId)); + MetaDataManager::GetInstance().SaveMeta(storeMetaData.GetKey(), storeMetaData); +} + +void CloudDataTest::TearDown() {} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(CloudDataTest, GetSchema, TestSize.Level0) +{ + ZLOGI("CloudDataTest start"); + auto cloudServerMock = std::make_shared(); + auto cloudInfo = cloudServerMock->GetServerInfo( + DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID())); + ASSERT_TRUE(MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), true)); + SchemaMeta schemaMeta; + ASSERT_FALSE( + MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + CloudEvent::StoreInfo storeInfo { OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; + auto event = std::make_unique(CloudEvent::GET_SCHEMA, std::move(storeInfo)); + EventCenter::GetInstance().PostEvent(move(event)); + ASSERT_TRUE( + MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + ASSERT_EQ(to_string(schemaMeta.Marshall()), to_string(schemaMeta_.Marshall())); +} +} // namespace DistributedDataTest +} // namespace OHOS::Test diff --git a/services/distributeddataservice/service/test/config_factory_test.cpp b/services/distributeddataservice/service/test/config_factory_test.cpp index 70a6a5ad833c9303b948e0b4c40ae979dd2ec8da..0210610981332ce8a419440097b0adbb46801ff5 100644 --- a/services/distributeddataservice/service/test/config_factory_test.cpp +++ b/services/distributeddataservice/service/test/config_factory_test.cpp @@ -61,7 +61,7 @@ HWTEST_F(ConfigFactoryTest, ComponentConfig, TestSize.Level0) { auto *components = ConfigFactory::GetInstance().GetComponentConfig(); ASSERT_NE(components, nullptr); - ASSERT_EQ(components->size(), 3); + ASSERT_EQ(components->size(), 4); const ComponentConfig &config = (*components)[0]; ASSERT_EQ(config.description, "3rd party adapter"); ASSERT_EQ(config.lib, "libconfigdemo.z.so"); diff --git a/services/distributeddataservice/service/test/crypto_manager_test.cpp b/services/distributeddataservice/service/test/crypto_manager_test.cpp index a78020761ca1deef628312729da7642591afd3ca..d285af1bb6b91fa9c8406a8a92e61c700848617a 100644 --- a/services/distributeddataservice/service/test/crypto_manager_test.cpp +++ b/services/distributeddataservice/service/test/crypto_manager_test.cpp @@ -17,6 +17,7 @@ #include #include "gtest/gtest.h" +#include "file_ex.h" #include "types.h" using namespace testing::ext; using namespace OHOS::DistributedData; @@ -37,11 +38,13 @@ static const uint32_t ENCRYPT_KEY_LENGTH = 48; std::vector CryptoManagerTest::randomKey; void CryptoManagerTest::SetUpTestCase(void) { + OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "0"); randomKey = Random(KEY_LENGTH); } void CryptoManagerTest::TearDownTestCase(void) { + OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "1"); randomKey.assign(randomKey.size(), 0); } diff --git a/services/distributeddataservice/service/test/directory_manager_test.cpp b/services/distributeddataservice/service/test/directory_manager_test.cpp index ae9cb64868919b56daf23bb7f931f2848022401a..d9eed29a35975241764d072f090bc8f9b3da3adb 100644 --- a/services/distributeddataservice/service/test/directory_manager_test.cpp +++ b/services/distributeddataservice/service/test/directory_manager_test.cpp @@ -16,7 +16,7 @@ #include #include "accesstoken_kit.h" #include "bootstrap.h" -#include "directory_manager.h" +#include "directory/directory_manager.h" #include "nativetoken_kit.h" #include "types.h" diff --git a/services/distributeddataservice/adapter/autils/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/BUILD.gn old mode 100755 new mode 100644 similarity index 46% rename from services/distributeddataservice/adapter/autils/BUILD.gn rename to services/distributeddataservice/service/test/fuzztest/BUILD.gn index 48efe8f545f9af221876c3d8477714bf09edef58..59ad2cd8f59790fab04a7c4a76f39cfb158ae93c --- a/services/distributeddataservice/adapter/autils/BUILD.gn +++ b/services/distributeddataservice/service/test/fuzztest/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2023 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -10,34 +10,23 @@ # 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("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") -ohos_static_library("distributeddata_autils_static") { - sources = [ - "src/constant.cpp", - "src/directory_utils.cpp", - "src/thread_pool/kv_store_task.cpp", - "src/thread_pool/kv_store_thread.cpp", - "src/thread_pool/kv_store_thread_pool.cpp", - "src/thread_pool/kv_store_thread_pool_impl.cpp", - ] - - include_dirs = [ - "../include/autils", - "../include/log", - "../include/dfx", - "${kv_store_common_path}", - ] - - cflags_cc = [ "-fvisibility=hidden" ] +######################################################################################### +group("fuzztest") { + testonly = true - external_deps = [ - "c_utils:utils", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + deps = [ + "cloudservicestub_fuzzer:fuzztest", + "datashareservicestub_fuzzer:fuzztest", + "kvdbservicestub_fuzzer:fuzztest", + "objectservicestub_fuzzer:fuzztest", + "rdbresultsetstub_fuzzer:fuzztest", + "rdbservicestub_fuzzer:fuzztest", ] - subsystem_name = "distributeddatamgr" - part_name = "datamgr_service" - defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] + if (datamgr_service_udmf) { + deps += [ "udmfservice_fuzzer:fuzztest" ] + } } diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d39a5b8267016c0560e7a643db72767f62fd877e --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn @@ -0,0 +1,113 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("CloudServiceStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/cloud", + "${data_service_path}/service/config/include", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/object", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/rdb", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${dataobject_path}/frameworks/innerkitsimpl/include", + "${relational_store_path}/interfaces/inner_api/cloud_data/include", + "${relational_store_path}/interfaces/inner_api/rdb/include", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/cloudservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/cloud/cloud_service_impl.cpp", + "${data_service_path}/service/cloud/cloud_service_stub.cpp", + "${data_service_path}/service/cloud/sync_manager.cpp", + "${data_service_path}/service/rdb/rdb_asset_loader.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", + "${data_service_path}/service/rdb/rdb_cursor.cpp", + "${data_service_path}/service/rdb/rdb_general_store.cpp", + "${data_service_path}/service/rdb/rdb_notifier_proxy.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", + "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", + "${data_service_path}/service/rdb/rdb_service_impl.cpp", + "${data_service_path}/service/rdb/rdb_service_stub.cpp", + "${data_service_path}/service/rdb/rdb_store_observer_impl.cpp", + "${data_service_path}/service/rdb/rdb_syncer.cpp", + "${data_service_path}/service/rdb/rdb_watcher.cpp", + "${data_service_path}/service/rdb/value_proxy.cpp", + "cloudservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "relational_store:native_rdb", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":CloudServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1dada5adfc7697857845403aca1850a326461264 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "cloudservicestub_fuzzer.h" + +#include +#include + +#include "cloud_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::CloudData; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.CloudData.CloudServer"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 4; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr cloudServiceStub = std::make_shared(); + cloudServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..c007ebba589b7ea13961acac7845188f30ecaa8d --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_CLOUD_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_CLOUD_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "cloudservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_CLOUD_SERVICE_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6688d10b90ac14e65940c461c21179821007d100 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -0,0 +1,126 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("DataShareServiceStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/data_share/common", + "${data_service_path}/service/data_share/data", + "${data_service_path}/service/data_share/strategies", + "${data_service_path}/service/data_share/subscriber_managers", + "${data_service_path}/service/data_share", + "${datashare_path}/frameworks/native/common/include", + "${datashare_path}/interfaces/inner_api/common/include", + "${datashare_path}/interfaces/inner_api/consumer/include", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/datashareservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/data_share/common/app_connect_manager.cpp", + "${data_service_path}/service/data_share/common/bundle_mgr_proxy.cpp", + "${data_service_path}/service/data_share/common/db_delegate.cpp", + "${data_service_path}/service/data_share/common/div_strategy.cpp", + "${data_service_path}/service/data_share/common/extension_connect_adaptor.cpp", + "${data_service_path}/service/data_share/common/extension_mgr_proxy.cpp", + "${data_service_path}/service/data_share/common/kv_delegate.cpp", + "${data_service_path}/service/data_share/common/rdb_delegate.cpp", + "${data_service_path}/service/data_share/common/scheduler_manager.cpp", + "${data_service_path}/service/data_share/common/seq_strategy.cpp", + "${data_service_path}/service/data_share/common/uri_utils.cpp", + "${data_service_path}/service/data_share/data/published_data.cpp", + "${data_service_path}/service/data_share/data/resultset_json_formatter.cpp", + "${data_service_path}/service/data_share/data/template_data.cpp", + "${data_service_path}/service/data_share/data_share_obs_proxy.cpp", + "${data_service_path}/service/data_share/data_share_service_impl.cpp", + "${data_service_path}/service/data_share/data_share_service_stub.cpp", + "${data_service_path}/service/data_share/data_share_types_util.cpp", + "${data_service_path}/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", + "${data_service_path}/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", + "${data_service_path}/service/data_share/strategies/delete_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/check_is_single_app_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/cross_permission_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/empty_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/load_config_common_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/load_config_data_info_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/load_config_from_bundle_info_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/permission_strategy.cpp", + "${data_service_path}/service/data_share/strategies/general/process_single_app_user_cross_strategy.cpp", + "${data_service_path}/service/data_share/strategies/get_data_strategy.cpp", + "${data_service_path}/service/data_share/strategies/insert_strategy.cpp", + "${data_service_path}/service/data_share/strategies/publish_strategy.cpp", + "${data_service_path}/service/data_share/strategies/query_strategy.cpp", + "${data_service_path}/service/data_share/strategies/rdb_notify_strategy.cpp", + "${data_service_path}/service/data_share/strategies/subscribe_strategy.cpp", + "${data_service_path}/service/data_share/strategies/template_strategy.cpp", + "${data_service_path}/service/data_share/strategies/update_strategy.cpp", + "${data_service_path}/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp", + "${data_service_path}/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp", + "datashareservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service/data_share:data_share_service", + "${data_service_path}/service/data_share/gaussdb_rd:gaussdb_rd", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "data_share:datashare_common", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "ipc:ipc_core", + "relational_store:native_rdb", + "relational_store:rdb_bms_adapter", + "relational_store:rdb_data_share_adapter", + "samgr:samgr_proxy", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":DataShareServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7fb0269f2d493c312b7c0026f6bee6575b53ea58 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "datashareservicestub_fuzzer.h" + +#include +#include + +#include "data_share_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DataShare; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.DataShare.IDataShare"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 16; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr dataShareServiceStub = std::make_shared(); + dataShareServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..28399e52d198b12eb999b22616319c0c90132dd3 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_DATA_SHARE_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_DATA_SHARE_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "datashareservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_DATA_SHARE_SERVICE_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..8998072c19865af556eeeb126a33989bc68d2150 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -0,0 +1,110 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("KvdbServiceStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/config/include", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/permission/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/kvdbservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.cpp", + "${data_service_path}/service/kvdb/auth_delegate.cpp", + "${data_service_path}/service/kvdb/kvdb_exporter.cpp", + "${data_service_path}/service/kvdb/kvdb_service_impl.cpp", + "${data_service_path}/service/kvdb/kvdb_service_stub.cpp", + "${data_service_path}/service/kvdb/kvstore_sync_manager.cpp", + "${data_service_path}/service/kvdb/query_helper.cpp", + "${data_service_path}/service/kvdb/store_cache.cpp", + "${data_service_path}/service/kvdb/upgrade.cpp", + "${data_service_path}/service/kvdb/user_delegate.cpp", + "${data_service_path}/service/matrix/src/device_matrix.cpp", + "${data_service_path}/service/matrix/src/matrix_event.cpp", + "${data_service_path}/service/permission/src/permit_delegate.cpp", + "kvdbservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":KvdbServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b01aa99967f793421d1ff0747fcd14bcbceae904 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "kvdbservicestub_fuzzer.h" + +#include +#include + +#include "kvdb_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DistributedKv; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedKv.KVFeature"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 16; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr kvdbServiceStub = std::make_shared(); + kvdbServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..9fba238a6cf9cee15cd6cdf4c785235ebc5932f1 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_KVDB_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_KVDB_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "kvdbservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_KVDB_SERVICE_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..cd27ac04164ed5af25bc97a4454c60f494d3a01f --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -0,0 +1,102 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("ObjectServiceStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/config/include", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/object", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${dataobject_path}/frameworks/innerkitsimpl/include", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/objectservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.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_manager.cpp", + "${data_service_path}/service/object/object_service_impl.cpp", + "${data_service_path}/service/object/object_service_stub.cpp", + "objectservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":ObjectServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..410f53b1885bcab750e9b615e0c9acc590f76ed0 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "objectservicestub_fuzzer.h" + +#include +#include + +#include "object_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DistributedObject; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedObject.IObjectService"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 4; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr objectServiceStub = std::make_shared(); + objectServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..019e06f5f660c8e2097558524def59e6a4e05597 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_OBJECT_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_OBJECT_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "objectservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_OBJECT_SERVICE_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ef1263e825e2a9b46ff299b4ff94ab778578457f --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn @@ -0,0 +1,86 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("RdbResultSetStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/rdb", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${relational_store_path}/interfaces/inner_api/cloud_data/include", + "${relational_store_path}/interfaces/inner_api/rdb/include", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/rdbresultsetstub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", + "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", + "rdbresultsetstub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "relational_store:native_rdb", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":RdbResultSetStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a154212224b16d60e43742a50c7622bc55fd7042 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp @@ -0,0 +1,58 @@ +/* + * 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 "rdbresultsetstub_fuzzer.h" + +#include +#include + +#include "rdb_result_set_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DistributedRdb; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS::NativeRdb.IResultSet"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 24; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + MessageOption option; + std::shared_ptr dbResultSet; + std::shared_ptr rdbResultSetStub = std::make_shared(dbResultSet); + rdbResultSetStub->OnRemoteRequest(code, request, reply, option); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..b8f8cc3703e020b88e5ae9befa89fb227bbcbb72 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_RDB_RESULT_SET_STUB_FUZZER_H +#define DATAMGR_SERVICE_RDB_RESULT_SET_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "rdbresultsetstub_fuzzer" + +#endif // DATAMGR_SERVICE_RDB_RESULT_SET_STUB_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..9fef09470c932bc9f5d706e3864e2d35da2b8e5e --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -0,0 +1,111 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("RdbServiceStubFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/cloud", + "${data_service_path}/service/config/include", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/data_share", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/object", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/rdb", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${dataobject_path}/frameworks/innerkitsimpl/include", + "${relational_store_path}/interfaces/inner_api/cloud_data/include", + "${relational_store_path}/interfaces/inner_api/rdb/include", + "//third_party/json/single_include", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/rdbservicestub_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/rdb/rdb_asset_loader.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", + "${data_service_path}/service/rdb/rdb_cursor.cpp", + "${data_service_path}/service/rdb/rdb_general_store.cpp", + "${data_service_path}/service/rdb/rdb_notifier_proxy.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", + "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", + "${data_service_path}/service/rdb/rdb_service_impl.cpp", + "${data_service_path}/service/rdb/rdb_service_stub.cpp", + "${data_service_path}/service/rdb/rdb_store_observer_impl.cpp", + "${data_service_path}/service/rdb/rdb_syncer.cpp", + "${data_service_path}/service/rdb/rdb_watcher.cpp", + "${data_service_path}/service/rdb/value_proxy.cpp", + "rdbservicestub_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "relational_store:native_rdb", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":RdbServiceStubFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa7737e8a951fb777ae699293a004716e86ab002 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "rdbservicestub_fuzzer.h" + +#include +#include + +#include "rdb_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::DistributedRdb; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedRdb.IRdbService"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 10; + +bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr rdbServiceStub = std::make_shared(); + rdbServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..582118e945c66c0176dfb4a0f4328120a1cbd0a8 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_RDB_SERVICE_STUB_FUZZER_H +#define DATAMGR_SERVICE_RDB_SERVICE_STUB_FUZZER_H + +#define FUZZ_PROJECT_NAME "rdbservicestub_fuzzer" + +#endif // DATAMGR_SERVICE_RDB_SERVICE_STUB_FUZZER_HH \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4656e9aa1061f4e7e75f2e9d794fa9c8a3666f52 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn @@ -0,0 +1,71 @@ +# 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. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("UdmfServiceFuzzTest") { + module_out_path = "datamgr_service/service" + + include_dirs = [ + "${udmf_path}/framework/common", + "${udmf_path}/interfaces/innerkits/common", + "${udmf_path}/interfaces/innerkits/data", + "${data_service_path}/framework/include", + "${data_service_path}/service/udmf/lifecycle", + "${data_service_path}/service/udmf/permission", + "${data_service_path}/service/udmf/preprocess", + "${data_service_path}/service/udmf/store", + "${data_service_path}/service/udmf", + "${kv_store_path}/frameworks/common", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/udmfservice_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "udmfservice_fuzzer.cpp" ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service/udmf:udmf_server", + ] + + external_deps = [ + "ability_base:zuri", + "ability_runtime:uri_permission_mgr", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "udmf:udmf_client", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":UdmfServiceFuzzTest" ] +} +############################################################################### diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/corpus/init b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/corpus/init new file mode 100644 index 0000000000000000000000000000000000000000..2b595da0c26af63ffb2d5f4132c086b2e5986fce --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * 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. + */ + +FUZZ \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/project.xml b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/project.xml new file mode 100644 index 0000000000000000000000000000000000000000..3fdba3e8b151bbb9026792021977b81e8a1851a6 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dda466ece40a6b5b4e32995210de1da3d2c57ea2 --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp @@ -0,0 +1,56 @@ +/* + * 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 "udmfservice_fuzzer.h" + +#include +#include + +#include "udmf_service_impl.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::UDMF; + +namespace OHOS { +const std::u16string INTERFACE_TOKEN = u"OHOS.UDMF.UdmfService"; +const uint32_t CODE_MIN = 0; +const uint32_t CODE_MAX = 10; + +bool OnRemoteRequestFuzz(const uint8_t* data, size_t size) +{ + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + std::shared_ptr udmfServiceStub = std::make_shared(); + udmfServiceStub->OnRemoteRequest(code, request, reply); + return true; +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::OnRemoteRequestFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.h b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.h new file mode 100644 index 0000000000000000000000000000000000000000..d86d273e4424aeb50d7c2d1a3854d2e8be9e6fab --- /dev/null +++ b/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_SERVICE_FUZZER_H +#define UDMF_SERVICE_FUZZER_H + +#define FUZZ_PROJECT_NAME "udmfservice_fuzzer" + +#endif // UDMF_SERVICE_FUZZER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/db_store_mock.cpp b/services/distributeddataservice/service/test/mock/db_store_mock.cpp index 87639965c2b44870b3de0d12a3528b3a020bf1a4..cd1e2df6145ae0f541d900eb5d181bc6f0541f61 100644 --- a/services/distributeddataservice/service/test/mock/db_store_mock.cpp +++ b/services/distributeddataservice/service/test/mock/db_store_mock.cpp @@ -136,7 +136,7 @@ DBStatus DBStoreMock::Sync(const std::vector &devices, SyncMode mod const std::function &)> &onComplete, bool wait) { std::map result; - for (auto &device : devices) { + for (const auto &device : devices) { result[device] = OK; } onComplete(result); @@ -263,7 +263,7 @@ DBStatus DBStoreMock::GetEntries(ConcurrentMap &store, const Key &ke store.ForEach([&entries, &keyPrefix](const Key &key, Value &value) { auto it = std::search(key.begin(), key.end(), keyPrefix.begin(), keyPrefix.end()); if (it == key.begin()) { - entries.push_back({ key, value }); + entries.push_back({key, value}); } return false; }); @@ -273,7 +273,7 @@ DBStatus DBStoreMock::GetEntries(ConcurrentMap &store, const Key &ke DBStatus DBStoreMock::PutBatch(ConcurrentMap &store, const std::vector &entries) { for (auto &entry : entries) { - entries_.InsertOrAssign(entry.key, entry.value); + store.InsertOrAssign(entry.key, entry.value); } DBChangeDataMock changeData({}, entries, {}); observers_.ForEachCopies([&changeData](const auto &observer, auto &keys) mutable { diff --git a/services/distributeddataservice/service/test/value_proxy_test.cpp b/services/distributeddataservice/service/test/value_proxy_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66767e320e4d67b8165346bfabe808ea07dc8cfd --- /dev/null +++ b/services/distributeddataservice/service/test/value_proxy_test.cpp @@ -0,0 +1,247 @@ +/* + * 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. + */ + +#define LOG_TAG "CloudDataTest" +#include +#include "log_print.h" +#include "value_proxy.h" +namespace Test { +using namespace testing::ext; +using namespace OHOS::DistributedRdb; +class ValueProxyTest : public testing::Test { +}; + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, VBucketsNormal2GaussDB, TestSize.Level0) +{ + std::vector dbVBuckets; + OHOS::DistributedData::VBuckets extends = { + {{"#gid", {"0000000"}}, {"#flag", {true }}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}}, + {{"#gid", {"0000001"}}} + }; + dbVBuckets = ValueProxy::Convert(std::move(extends)); + ASSERT_EQ(dbVBuckets.size(), 2); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, VBucketsGaussDB2Normal, TestSize.Level0) +{ + std::vector dbVBuckets = { + {{"#gid", {"0000000"}}, {"#flag", {true }}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}}, + {{"#gid", {"0000001"}}} + }; + OHOS::DistributedData::VBuckets extends; + extends = ValueProxy::Convert(std::move(dbVBuckets)); + ASSERT_EQ(extends.size(), 2); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, VBucketsNormal2Rdb, TestSize.Level0) +{ + using RdbBucket = OHOS::NativeRdb::ValuesBucket; + std::vector rdbVBuckets; + OHOS::DistributedData::VBuckets extends = { + {{"#gid", {"0000000"}}, {"#flag", {true }}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}}, + {{"#gid", {"0000001"}}} + }; + rdbVBuckets = ValueProxy::Convert(std::move(extends)); + ASSERT_EQ(rdbVBuckets.size(), 2); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, VBucketsRdb2Normal, TestSize.Level0) +{ + using RdbBucket = OHOS::NativeRdb::ValuesBucket; + using RdbValue = OHOS::NativeRdb::ValueObject; + std::vector rdbVBuckets = { + RdbBucket(std::map { + {"#gid", {"0000000"}}, + {"#flag", {true }}, + {"#value", {int64_t(100)}}, + {"#float", {double(100)}} + }), + RdbBucket(std::map { + {"#gid", {"0000001"}} + }) + }; + OHOS::DistributedData::VBuckets extends; + extends = ValueProxy::Convert(std::move(rdbVBuckets)); + ASSERT_EQ(extends.size(), 2); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, ConvertIntMapTest, TestSize.Level0) +{ + std::map testMap = { { "name", 1 }, { "school", 2 }, { "address", 3 } }; + auto res = ValueProxy::Convert(testMap); + auto testMap2 = std::map(res); + ASSERT_EQ(testMap2.find("name")->second, 1); + + auto errorMap = std::map(res); + ASSERT_EQ(errorMap.size(), 0); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, ConvertAssetMapGaussDB2NormalTest, TestSize.Level0) +{ + DistributedDB::Asset dbAsset0 { .name = "dbname", .uri = "dburi" }; + DistributedDB::Asset dbAsset1 { .name = "dbname", .uri = "dburi" }; + std::map dbMap { { "asset0", dbAsset0 }, { "asset1", dbAsset1 } }; + OHOS::DistributedData::VBucket transferredAsset = ValueProxy::Convert(dbMap); + ASSERT_EQ(transferredAsset.size(), 2); + auto asset = std::get(transferredAsset.find("asset0")->second); + ASSERT_EQ(asset.name, "dbname"); + + DistributedDB::Assets dbAssets { dbAsset0, dbAsset1 }; + std::map dbAssetsMap { {"dbAssets", dbAssets} }; + OHOS::DistributedData::VBucket transferredAssets = ValueProxy::Convert(dbAssetsMap); + ASSERT_EQ(transferredAssets.size(), 1); + auto assets = std::get(transferredAssets.find("dbAssets")->second); + ASSERT_EQ(assets.size(), 2); + auto dataAsset = assets.begin(); + ASSERT_EQ(dataAsset->name, "dbname"); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2GaussDBTest, TestSize.Level0) +{ + using NormalAsset = OHOS::DistributedData::Asset; + using NormalAssets = OHOS::DistributedData::Assets; + NormalAsset nAsset0 { .name = "name", .uri = "uri" }; + NormalAsset nAsset1 { .name = "name", .uri = "uri" }; + std::map nMap { { "asset0", nAsset0 }, { "asset1", nAsset1 } }; + DistributedDB::VBucket transferredAsset = ValueProxy::Convert(nMap); + ASSERT_EQ(transferredAsset.size(), 2); + auto asset = std::get(transferredAsset.find("asset0")->second); + ASSERT_EQ(asset.name, "name"); + + NormalAssets nAssets { nAsset0, nAsset1 }; + std::map nAssetsMap { { "Assets", nAssets } }; + DistributedDB::VBucket transferredAssets = ValueProxy::Convert(nAssetsMap); + ASSERT_EQ(transferredAssets.size(), 1); + auto assets = std::get(transferredAssets.find("Assets")->second); + ASSERT_EQ(assets.size(), 2); + auto dataAsset = assets.begin(); + ASSERT_EQ(dataAsset->name, "name"); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, ConvertAssetMapRdb2NormalTest, TestSize.Level0) +{ + using RdbAsset = OHOS::NativeRdb::AssetValue; + using RdbAssets = std::vector; + RdbAsset dbAsset0 { .name = "dbname", .uri = "dburi" }; + RdbAsset dbAsset1 { .name = "dbname", .uri = "dburi" }; + std::map dbMap { { "asset0", dbAsset0 }, { "asset1", dbAsset1 } }; + OHOS::DistributedData::VBucket transferredAsset = ValueProxy::Convert(dbMap); + ASSERT_EQ(transferredAsset.size(), 2); + auto asset = std::get(transferredAsset.find("asset0")->second); + ASSERT_EQ(asset.name, "dbname"); + + RdbAssets dbAssets { dbAsset0, dbAsset1 }; + std::map dbAssetsMap { {"dbAssets", dbAssets} }; + OHOS::DistributedData::VBucket transferredAssets = ValueProxy::Convert(dbAssetsMap); + ASSERT_EQ(transferredAssets.size(), 1); + auto assets = std::get(transferredAssets.find("dbAssets")->second); + ASSERT_EQ(assets.size(), 2); + auto dataAsset = assets.begin(); + ASSERT_EQ(dataAsset->name, "dbname"); +} + +/** +* @tc.name: GetSchema +* @tc.desc: GetSchema from cloud when no schema in meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2RdbTest, TestSize.Level0) +{ + using RdbAsset = OHOS::NativeRdb::AssetValue; + using RdbAssets = std::vector; + using NormalAsset = OHOS::DistributedData::Asset; + using NormalAssets = OHOS::DistributedData::Assets; + NormalAsset nAsset0 { .name = "name", .uri = "uri" }; + NormalAsset nAsset1 { .name = "name", .uri = "uri" }; + std::map nMap { { "asset0", nAsset0 }, { "asset1", nAsset1 } }; + OHOS::NativeRdb::ValuesBucket transferredAsset = ValueProxy::Convert(nMap); + ASSERT_EQ(transferredAsset.Size(), 2); + OHOS::NativeRdb::ValueObject rdbObject; + transferredAsset.GetObject("asset0", rdbObject); + RdbAsset rdbAsset; + rdbObject.GetAsset(rdbAsset); + ASSERT_EQ(rdbAsset.name, "name"); + + NormalAssets nAssets { nAsset0, nAsset1 }; + std::map nAssetsMap { { "Assets", nAssets } }; + OHOS::NativeRdb::ValuesBucket transferredAssets = ValueProxy::Convert(nAssetsMap); + ASSERT_EQ(transferredAssets.Size(), 1); + OHOS::NativeRdb::ValueObject rdbObject2; + transferredAssets.GetObject("Assets", rdbObject2); + RdbAssets rdbAssets; + rdbObject2.GetAssets(rdbAssets); + ASSERT_EQ(rdbAssets.size(), 2); + auto dataAsset = rdbAssets.begin(); + ASSERT_EQ(dataAsset->name, "name"); +} +} // namespace Test diff --git a/services/distributeddataservice/service/udmf/BUILD.gn b/services/distributeddataservice/service/udmf/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..4e33af71348067ff7bb2e149d7d99d311e3a8537 --- /dev/null +++ b/services/distributeddataservice/service/udmf/BUILD.gn @@ -0,0 +1,79 @@ +# 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("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +config("module_public_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${data_service_path}/framework/include", + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/service/udmf/lifecycle", + "${data_service_path}/service/udmf/permission", + "${data_service_path}/service/udmf/preprocess", + "${data_service_path}/service/udmf/store", + "${data_service_path}/service/udmf", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", + "${udmf_path}/framework/common", + "${udmf_path}/interfaces/innerkits/common", + "${udmf_path}/interfaces/innerkits/data", + ] +} + +ohos_shared_library("udmf_server") { + sources = [ + "data_manager.cpp", + "lifecycle/clean_after_get.cpp", + "lifecycle/clean_on_startup.cpp", + "lifecycle/clean_on_timeout.cpp", + "lifecycle/lifecycle_manager.cpp", + "lifecycle/lifecycle_policy.cpp", + "permission/checker_manager.cpp", + "permission/data_checker.cpp", + "permission/uri_permission_manager.cpp", + "preprocess/preprocess_utils.cpp", + "store/runtime_store.cpp", + "store/store_cache.cpp", + "udmf_service_impl.cpp", + "udmf_service_stub.cpp", + ] + + configs = [ ":module_public_config" ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + ] + + external_deps = [ + "ability_base:zuri", + "ability_runtime:uri_permission_mgr", + "access_token:libaccesstoken_sdk", + "app_file_service:remote_file_share_native", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "udmf:udmf_client", + ] + + subsystem_name = "distributeddatamgr" + + part_name = "datamgr_service" +} diff --git a/services/distributeddataservice/service/udmf/data_manager.cpp b/services/distributeddataservice/service/udmf/data_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..b9efa7f7cc68f9faf6320b06a32565a5c19df6d6 --- /dev/null +++ b/services/distributeddataservice/service/udmf/data_manager.cpp @@ -0,0 +1,375 @@ +/* + * 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. + */ +#define LOG_TAG "DataManager" + +#include "data_manager.h" + +#include "checker_manager.h" +#include "dfx_types.h" +#include "file.h" +#include "lifecycle/lifecycle_manager.h" +#include "log_print.h" +#include "preprocess_utils.h" +#include "uri_permission_manager.h" + +namespace OHOS { +namespace UDMF { +const std::string MSDP_PROCESS_NAME = "msdp_sa"; +const std::string DATA_PREFIX = "udmf://"; +DataManager::DataManager() +{ + authorizationMap_[UD_INTENTION_MAP.at(UD_INTENTION_DRAG)] = MSDP_PROCESS_NAME; + CheckerManager::GetInstance().LoadCheckers(); +} + +DataManager::~DataManager() +{ +} + +DataManager &DataManager::GetInstance() +{ + static DataManager instance; + return instance; +} + +int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key) +{ + if (unifiedData.IsEmpty()) { + ZLOGE("Invalid parameters, have no record"); + return E_INVALID_PARAMETERS; + } + + if (!UnifiedDataUtils::IsValidIntention(option.intention)) { + ZLOGE("Invalid parameters intention: %{public}d.", option.intention); + return E_INVALID_PARAMETERS; + } + + // imput runtime info before put it into store and save one privilege + if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) { + ZLOGE("Imputation failed"); + return E_UNKNOWN; + } + + std::string intention = unifiedData.GetRuntime()->key.intention; + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); + if (ret != E_OK) { + return ret; + } + } + + for (const auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::IdGenerator()); + } + + auto store = storeCache_.GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) { + ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + if (store->Put(unifiedData) != E_OK) { + ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + key = unifiedData.GetRuntime()->key.GetUnifiedKey(); + ZLOGD("Put unified data successful, key: %{public}s.", key.c_str()); + return E_OK; +} + +int32_t DataManager::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + int32_t res = store->Get(query.key, unifiedData); + if (res != E_OK) { + ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); + return res; + } + if (unifiedData.IsEmpty()) { + return E_OK; + } + std::shared_ptr runtime = unifiedData.GetRuntime(); + CheckerManager::CheckInfo info; + info.tokenId = query.tokenId; + if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info)) { + return E_NO_PERMISSION; + } + + if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = ProcessingUri(query, unifiedData); + if (ret != E_OK) { + ZLOGE("DragUriProcessing failed. ret=%{public}d", ret); + return E_NO_PERMISSION; + } + } + + if (LifeCycleManager::GetInstance().DeleteOnGet(key) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + PreProcessUtils::SetRemoteData(unifiedData); + return E_OK; +} + +int32_t DataManager::ProcessingUri(const QueryOption &query, UnifiedData &unifiedData) +{ + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + auto records = unifiedData.GetRecords(); + if (localDeviceId != unifiedData.GetRuntime()->deviceId) { + std::string uri; + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + uri = file->GetRemoteUri(); + file->SetUri(uri); // cross dev, need dis path. + } + } + } + + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { + return E_ERROR; + } + if (unifiedData.GetRuntime()->createPackage != bundleName) { + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + std::string uri = file->GetUri(); + if (!uri.empty() + && (UriPermissionManager::GetInstance().GrantUriPermission(uri, bundleName) != E_OK)) { + return E_NO_PERMISSION; + } + } + } + } + return E_OK; +} + +int32_t DataManager::RetrieveBatchData(const QueryOption &query, std::vector &unifiedDataSet) +{ + std::vector dataSet; + std::shared_ptr store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + ZLOGE("QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); + return E_OK; + } + for (auto &data : dataSet) { + PreProcessUtils::SetRemoteData(data); + unifiedDataSet.push_back(data); + } + return E_OK; +} + +int32_t DataManager::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + if (unifiedData.IsEmpty()) { + ZLOGE("Invalid parameters, unified data has no record."); + return E_INVALID_PARAMETERS; + } + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData data; + int32_t res = store->Get(query.key, data); + if (res != E_OK) { + ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); + return res; + } + if (data.IsEmpty()) { + ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::shared_ptr runtime = data.GetRuntime(); + runtime->lastModifiedTime = PreProcessUtils::GetTimeStamp(); + unifiedData.SetRuntime(*runtime); + for (auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::IdGenerator()); + } + if (store->Update(unifiedData) != E_OK) { + ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} +int32_t DataManager::DeleteData(const QueryOption &query, std::vector &unifiedDataSet) +{ + std::vector dataSet; + std::shared_ptr store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + ZLOGE("QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); + return E_OK; + } + std::shared_ptr runtime; + std::vector deleteKeys; + for (const auto &data : dataSet) { + runtime = data.GetRuntime(); + unifiedDataSet.push_back(data); + deleteKeys.push_back(runtime->key.key); + } + if (store->DeleteBatch(deleteKeys) != E_OK) { + ZLOGE("Remove data failed."); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t DataManager::GetSummary(const QueryOption &query, Summary &summary) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + if (store->GetSummary(query.key, summary) != E_OK) { + ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t DataManager::AddPrivilege(const QueryOption &query, const Privilege &privilege) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + std::string processName; + if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) { + return E_UNKNOWN; + } + + if (processName != authorizationMap_[key.intention]) { + ZLOGE("Process: %{public}s have no permission", processName.c_str()); + return E_NO_PERMISSION; + } + + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData data; + int32_t res = store->Get(query.key, data); + if (res != E_OK) { + ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); + return res; + } + + if (data.IsEmpty()) { + ZLOGE("Invalid parameters, unified data has no record, intention: %{public}s.", key.intention.c_str()); + return E_INVALID_PARAMETERS; + } + + data.GetRuntime()->privileges.emplace_back(privilege); + if (store->Update(data) != E_OK) { + ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t DataManager::Sync(const QueryOption &query, const std::vector &devices) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + if (store->Sync(devices) != E_OK) { + ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t DataManager::QueryDataCommon( + const QueryOption &query, std::vector &dataSet, std::shared_ptr &store) +{ + auto find = UD_INTENTION_MAP.find(query.intention); + std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; + if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::string dataPrefix = DATA_PREFIX + intention; + UnifiedKey key(query.key); + key.IsValid(); + if (intention.empty()) { + dataPrefix = key.key; + intention = key.intention; + } + ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str()); + store = storeCache_.GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { + ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); + return E_DB_ERROR; + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/autils/kv_store_thread_pool.h b/services/distributeddataservice/service/udmf/data_manager.h old mode 100644 new mode 100755 similarity index 31% rename from services/distributeddataservice/adapter/include/autils/kv_store_thread_pool.h rename to services/distributeddataservice/service/udmf/data_manager.h index 6b908a68b16092eca96c186339baf4cdec35da8c..69abcefbf3eb7e85ce2efa391dc3e5acd7dc0246 --- a/services/distributeddataservice/adapter/include/autils/kv_store_thread_pool.h +++ b/services/distributeddataservice/service/udmf/data_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,34 +13,43 @@ * limitations under the License. */ -#ifndef KV_STORE_THREAD_POOL_H -#define KV_STORE_THREAD_POOL_H +#ifndef UDMF_DATA_MANAGER_H +#define UDMF_DATA_MANAGER_H +#include #include -#include "kv_store_task.h" +#include +#include + +#include "error_code.h" +#include "store_cache.h" +#include "unified_data.h" +#include "unified_types.h" namespace OHOS { -namespace DistributedKv { -class KvStoreThreadPool { +namespace UDMF { +class DataManager { public: - KvStoreThreadPool(KvStoreThreadPool &&) = delete; - KvStoreThreadPool(const KvStoreThreadPool &) = delete; - KvStoreThreadPool &operator=(KvStoreThreadPool &&) = delete; - KvStoreThreadPool &operator=(const KvStoreThreadPool &) = delete; - KVSTORE_API virtual ~KvStoreThreadPool() {} + virtual ~DataManager(); + + static DataManager &GetInstance(); - KVSTORE_API static std::shared_ptr GetPool( - int poolSize, std::string poolName, bool startImmediately = false); - KVSTORE_API virtual void Stop() = 0; - KVSTORE_API virtual bool AddTask(KvStoreTask &&task) = 0; - KVSTORE_API static constexpr int MAX_POOL_SIZE = 64; // the max thread pool size - KVSTORE_API static constexpr int DEFAULT_POOL_SIZE = 8; // the default thread pool size - std::string GetPoolName(); -protected: - KvStoreThreadPool() = default; - std::string poolName_ = ""; + int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); + int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); + int32_t RetrieveBatchData(const QueryOption &query, std::vector &unifiedDataSet); + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData); + int32_t DeleteData(const QueryOption &query, std::vector &unifiedDataSet); + int32_t GetSummary(const QueryOption &query, Summary &summary); + int32_t AddPrivilege(const QueryOption &query, const Privilege &privilege); + int32_t Sync(const QueryOption &query, const std::vector &devices); + +private: + DataManager(); + int32_t QueryDataCommon(const QueryOption &query, std::vector &dataSet, std::shared_ptr &store); + int32_t ProcessingUri(const QueryOption &query, UnifiedData &unifiedData); + StoreCache storeCache_; + std::map authorizationMap_; }; -} // namespace DistributedKv +} // namespace UDMF } // namespace OHOS - -#endif // KV_STORE_THREAD_POOL_H +#endif // UDMF_DATA_MANAGER_H diff --git a/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp b/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54fc55458f0c4f40d03ab5175cdee2c236e9dad5 --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp @@ -0,0 +1,21 @@ +/* + * 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 "clean_after_get.h" + +namespace OHOS { +namespace UDMF { +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h b/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h new file mode 100644 index 0000000000000000000000000000000000000000..1e94b5fbd98af7ab344021cd06ff917d218b99a5 --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_CLEAN_AFTER_GET_H +#define UDMF_CLEAN_AFTER_GET_H +#include "lifecycle_policy.h" + +namespace OHOS { +namespace UDMF { +class CleanAfterGet : public LifeCyclePolicy { +public: +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_CLEAN_AFTER_GET_H diff --git a/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp b/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eef045ff90bd94a6724d0e52ef8d83fd304c1519 --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp @@ -0,0 +1,30 @@ +/* + * 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 "clean_on_startup.h" + +namespace OHOS { +namespace UDMF { +Status CleanOnStartup::DeleteOnTimeout(const std::string &intention) +{ + return E_OK; +} + +Status CleanOnStartup::DeleteOnGet(const UnifiedKey &key) +{ + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h b/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h new file mode 100644 index 0000000000000000000000000000000000000000..b269743aa5617be3c2513563c6bc9f422afcc8fe --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_CLEAN_ON_STARTUP_H +#define UDMF_CLEAN_ON_STARTUP_H +#include "lifecycle_policy.h" + +namespace OHOS { +namespace UDMF { +class CleanOnStartup : public LifeCyclePolicy { +public: + Status DeleteOnTimeout(const std::string &intention) override; + Status DeleteOnGet(const UnifiedKey &key) override; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_CLEAN_ON_STARTUP_H diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_task.cpp b/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp similarity index 55% rename from services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_task.cpp rename to services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp index b6de8ace9dcdaf6bc335b69aefe338607bc6f059..6b36eadfd8ea07e11db5b94827b8b7399885b88d 100644 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_task.cpp +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,28 +13,18 @@ * limitations under the License. */ -#define LOG_TAG "KvStoreTask" - -#include "kv_store_task.h" -#include "log_print.h" +#include "clean_on_timeout.h" namespace OHOS { -namespace DistributedKv { -KvStoreTask::KvStoreTask(std::function lambda) -{ - task_ = std::move(lambda); - name_ = std::string(); -} - -KvStoreTask::KvStoreTask(std::function lambda, const std::string &taskName) +namespace UDMF { +Status CleanOnTimeout::DeleteOnStart(const std::string &intention) { - task_ = std::move(lambda); - name_ = taskName; + return LifeCyclePolicy::DeleteOnTimeout(intention); } -void KvStoreTask::operator()() +Status CleanOnTimeout::DeleteOnGet(const UnifiedKey &key) { - task_(); + return E_OK; } -} // namespace DistributedKv +} // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h b/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h new file mode 100644 index 0000000000000000000000000000000000000000..d86be2584fe12bfbd66957e8d1aa1dad1e11876c --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_CLEAN_ON_TIMEOUT_H +#define UDMF_CLEAN_ON_TIMEOUT_H +#include "lifecycle_policy.h" + +namespace OHOS { +namespace UDMF { +class CleanOnTimeout : public LifeCyclePolicy { +public: + Status DeleteOnStart(const std::string &intention) override; + Status DeleteOnGet(const UnifiedKey &key) override; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_CLEAN_ON_TIMEOUT_H diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c285644f28c7ee23c4040e70acc59ae2e5ee56de --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp @@ -0,0 +1,92 @@ +/* + * 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. + */ +#define LOG_TAG "LifeCycleManager" + +#include "lifecycle_manager.h" + +#include +#include + +#include "log_print.h" + +namespace OHOS { +namespace UDMF { +std::shared_ptr LifeCycleManager::executorPool_ = std::make_shared(2, 1); + +std::unordered_map> LifeCycleManager::intentionPolicyMap_ = { + { UD_INTENTION_MAP.at(UD_INTENTION_DRAG), std::make_shared() }, +}; + +LifeCycleManager &LifeCycleManager::GetInstance() +{ + static LifeCycleManager instance; + return instance; +} + +Status LifeCycleManager::DeleteOnGet(const UnifiedKey &key) +{ + auto findPolicy = intentionPolicyMap_.find(key.intention); + if (findPolicy == intentionPolicyMap_.end()) { + ZLOGE("Invalid intention, intention: %{public}s.", key.intention.c_str()); + return E_INVALID_PARAMETERS; + } + auto policy = findPolicy->second; + return policy->DeleteOnGet(key); +} + +Status LifeCycleManager::DeleteOnStart() +{ + Status status = E_OK; + std::shared_ptr LifeCyclePolicy; + for (const auto &intentionPolicyPair : intentionPolicyMap_) { + LifeCyclePolicy = GetPolicy(intentionPolicyPair.first); + status = status == E_OK ? LifeCyclePolicy->DeleteOnStart(intentionPolicyPair.first) : status; + } + return status; +} + +Status LifeCycleManager::DeleteOnSchedule() +{ + ExecutorPool::TaskId taskId = + executorPool_->Schedule(&LifeCycleManager::DeleteOnTimeout, LifeCyclePolicy::INTERVAL); + if (taskId == ExecutorPool::INVALID_TASK_ID) { + ZLOGE("ExecutorPool Schedule failed."); + return E_ERROR; + } + ZLOGI("ScheduleTask start, TaskId: %{public}" PRIu64 ".", taskId); + return E_OK; +} + +std::shared_ptr LifeCycleManager::GetPolicy(const std::string &intention) +{ + auto findPolicy = intentionPolicyMap_.find(intention); + if (findPolicy == intentionPolicyMap_.end()) { + return nullptr; + } + return findPolicy->second; +} + +Status LifeCycleManager::DeleteOnTimeout() +{ + Status status = E_OK; + std::shared_ptr LifeCyclePolicy; + for (const auto &intentionPolicyPair : intentionPolicyMap_) { + LifeCyclePolicy = LifeCycleManager::GetInstance().GetPolicy(intentionPolicyPair.first); + status = status == E_OK ? LifeCyclePolicy->DeleteOnTimeout(intentionPolicyPair.first) : status; + } + return status; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/autils/directory_utils.h b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h similarity index 40% rename from services/distributeddataservice/adapter/include/autils/directory_utils.h rename to services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h index 67ba84dda6bbe4c17c3f9b9358d90153ffbd1347..e73032d9e06cbe19fbbe303a4ed12d6c439e00e8 100644 --- a/services/distributeddataservice/adapter/include/autils/directory_utils.h +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,39 +12,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef UDMF_LIFECYCLE_MANAGER_H +#define UDMF_LIFECYCLE_MANAGER_H -#ifndef DIRECTORY_UTILS_H -#define DIRECTORY_UTILS_H - +#include +#include #include -#include -#include "visibility.h" +#include +#include + +#include "clean_after_get.h" +#include "clean_on_startup.h" +#include "clean_on_timeout.h" +#include "executor_pool.h" +#include "lifecycle_policy.h" namespace OHOS { -namespace DistributedKv { -class DirectoryUtils { +namespace UDMF { +class LifeCycleManager { public: - KVSTORE_API static bool ChangeModeFileOnly(const std::string &path, const mode_t &mode); - - KVSTORE_API static bool ChangeModeDirOnly(const std::string &path, const mode_t &mode); - - KVSTORE_API static bool CreateDirectory(const std::string &path); + static LifeCycleManager &GetInstance(); + Status DeleteOnGet(const UnifiedKey &key); + Status DeleteOnStart(); + Status DeleteOnSchedule(); private: - DirectoryUtils() = default; - - ~DirectoryUtils() = default; - - static std::string ExcludeDelimiterAtPathTail(const std::string &path); - - static std::string IncludeDelimiterAtPathTail(const std::string &path); - - // change the mode of the specified file or directory. - static inline bool ChangeMode(const std::string &name, const mode_t &mode) - { - return (chmod(name.c_str(), mode) == 0); - } + static std::shared_ptr executorPool_; + static std::unordered_map> intentionPolicyMap_; + static std::shared_ptr GetPolicy(const std::string &intention); + static Status DeleteOnTimeout(); }; -} // namespace DistributedKv +} // namespace UDMF } // namespace OHOS -#endif // DIRECTORY_UTILS_H +#endif // UDMF_LIFECYCLE_MANAGER_H diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e790fb94a4ee964e99ae4efb1a0280ca3225aa5 --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp @@ -0,0 +1,101 @@ +/* + * 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. + */ +#define LOG_TAG "LifeCyclePolicy" + +#include "lifecycle_policy.h" + +#include + +#include "log_print.h" +#include "preprocess/preprocess_utils.h" + +namespace OHOS { +namespace UDMF { +using namespace std::chrono; +const LifeCyclePolicy::Duration LifeCyclePolicy::INTERVAL = milliseconds(60 * 60 * 1000); +const std::string LifeCyclePolicy::DATA_PREFIX = "udmf://"; + +Status LifeCyclePolicy::DeleteOnGet(const UnifiedKey &key) +{ + auto store = storeCache_.GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + if (store->Delete(key.key) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +Status LifeCyclePolicy::DeleteOnStart(const std::string &intention) +{ + auto store = storeCache_.GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + if (store->Clear() != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +Status LifeCyclePolicy::DeleteOnTimeout(const std::string &intention) +{ + auto store = storeCache_.GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + std::vector timeoutKeys; + auto status = GetTimeoutKeys(store, INTERVAL, timeoutKeys); + if (status != E_OK) { + ZLOGE("Get timeout keys failed."); + return E_DB_ERROR; + } + if (store->DeleteBatch(timeoutKeys) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +Status LifeCyclePolicy::GetTimeoutKeys( + const std::shared_ptr &store, Duration interval, std::vector &timeoutKeys) +{ + std::vector datas; + auto status = store->GetBatchData(DATA_PREFIX, datas); + if (status != E_OK) { + ZLOGE("Get data failed."); + return E_DB_ERROR; + } + if (datas.empty()) { + ZLOGD("entries is empty."); + return E_OK; + } + auto curTime = PreProcessUtils::GetTimeStamp(); + for (const auto &data : datas) { + if (curTime > data.GetRuntime()->createTime + duration_cast(interval).count() + || curTime < data.GetRuntime()->createTime) { + timeoutKeys.push_back(data.GetRuntime()->key.key); + } + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h new file mode 100644 index 0000000000000000000000000000000000000000..45f8e63ac6487e91d467aedf73a577f5f82ac891 --- /dev/null +++ b/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_LIFECYCLE_POLICY_H +#define UDMF_LIFECYCLE_POLICY_H + +#include +#include + +#include "store_cache.h" +#include "unified_key.h" + +namespace OHOS { +namespace UDMF { +class LifeCyclePolicy { +public: + using Duration = std::chrono::steady_clock::duration; + static const Duration INTERVAL; + virtual ~LifeCyclePolicy() = default; + virtual Status DeleteOnGet(const UnifiedKey &key); + virtual Status DeleteOnStart(const std::string &intention); + virtual Status DeleteOnTimeout(const std::string &intention); + virtual Status GetTimeoutKeys( + const std::shared_ptr &store, Duration interval, std::vector &timeoutKeys); + +private: + static const std::string DATA_PREFIX; + StoreCache storeCache_; +}; +} // namespace UDMF +} // namespace OHOS + +#endif // UDMF_LIFECYCLE_POLICY_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/permission/checker_manager.cpp b/services/distributeddataservice/service/udmf/permission/checker_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..1e9253980a27dfa91fdeb5cbd0e150dc26d167e4 --- /dev/null +++ b/services/distributeddataservice/service/udmf/permission/checker_manager.cpp @@ -0,0 +1,58 @@ +/* + * 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 "checker_manager.h" + +namespace OHOS { +namespace UDMF { +const std::string DATA_CHECKER = "DataChecker"; +CheckerManager &CheckerManager::GetInstance() +{ + static CheckerManager instance; + return instance; +} + +void CheckerManager::RegisterChecker(const std::string &checker, std::function getter) +{ + getters_.ComputeIfAbsent(checker, [&getter](const auto &) { + return move(getter); + }); +} + +void CheckerManager::LoadCheckers() +{ + getters_.ForEach([this] (const auto &key, const auto &val) { + if (this->checkers_.find(key) != this->checkers_.end()) { + return false; + } + auto *checker = val(); + if (checker == nullptr) { + return false; + } + this->checkers_[key] = checker; + return false; + }); +} + +bool CheckerManager::IsValid(const std::vector &privileges, const CheckInfo &info) +{ + auto it = checkers_.find(DATA_CHECKER); + if (it == checkers_.end()) { + return true; + } + return it->second->IsValid(privileges, info); +} +} // namespace UDMF +} // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/permission/checker_manager.h b/services/distributeddataservice/service/udmf/permission/checker_manager.h new file mode 100755 index 0000000000000000000000000000000000000000..3145fd0cc4d0f139385f7a171d45529893ff7aa0 --- /dev/null +++ b/services/distributeddataservice/service/udmf/permission/checker_manager.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_CHECKER_MANAGER_H +#define UDMF_CHECKER_MANAGER_H + +#include + +#include "concurrent_map.h" +#include "unified_types.h" + +namespace OHOS { +namespace UDMF { +class CheckerManager { +public: + struct CheckInfo { + uint32_t tokenId; + }; + + class Checker { + public: + virtual bool IsValid(const std::vector &privileges, const CheckInfo &info) = 0; + protected: + ~Checker() = default; + }; + + static CheckerManager &GetInstance(); + + void RegisterChecker(const std::string &checker, std::function getter); + void LoadCheckers(); + bool IsValid(const std::vector &privileges, const CheckInfo &info); + +private: + std::map checkers_; + ConcurrentMap> getters_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_CHECKER_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/permission/data_checker.cpp b/services/distributeddataservice/service/udmf/permission/data_checker.cpp new file mode 100755 index 0000000000000000000000000000000000000000..ac0588f9dfbcce8d59c223d050f195cffe799466 --- /dev/null +++ b/services/distributeddataservice/service/udmf/permission/data_checker.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "DataChecker" + +#include "data_checker.h" + +#include "utils/anonymous.h" +#include "log_print.h" + +namespace OHOS { +namespace UDMF { +__attribute__((used)) DataChecker DataChecker::instance_; +DataChecker::DataChecker() noexcept +{ + CheckerManager::GetInstance().RegisterChecker( + "DataChecker", [this]() -> auto { return this; }); +} + +DataChecker::~DataChecker() +{ +} + +bool DataChecker::IsValid(const std::vector &privileges, const CheckerManager::CheckInfo &info) +{ + for (const auto &privilege : privileges) { + if (privilege.tokenId == info.tokenId) { + return true; + } + } + ZLOGE("Invalid parameters, %{public}s", DistributedData::Anonymous::Change(std::to_string(info.tokenId)).c_str()); + return false; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/autils/time_utils.h b/services/distributeddataservice/service/udmf/permission/data_checker.h old mode 100644 new mode 100755 similarity index 54% rename from services/distributeddataservice/adapter/include/autils/time_utils.h rename to services/distributeddataservice/service/udmf/permission/data_checker.h index a67f12f7c41fa0f3bdeb9734a4131c1585149293..5aec008f8df7eac1bb061da46bacd1863c35318d --- a/services/distributeddataservice/adapter/include/autils/time_utils.h +++ b/services/distributeddataservice/service/udmf/permission/data_checker.h @@ -1,38 +1,35 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TIME_UTILS_H -#define TIME_UTILS_H - -#include -#include - -namespace OHOS { -namespace DistributedKv { -constexpr int64_t SEC_TO_MICROSEC = 1000000; - -class TimeUtils final { -public: - // micro seconds since 1970 - static inline uint64_t CurrentTimeMicros() - { - struct timeval tv = { 0, 0 }; - gettimeofday(&tv, nullptr); - return (tv.tv_sec * SEC_TO_MICROSEC + tv.tv_usec); - } -}; -} // namespace DistributedKv -} // namespace OHOS -#endif +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_DATA_CHECKER_H +#define UDMF_DATA_CHECKER_H + +#include "checker_manager.h" + +namespace OHOS { +namespace UDMF { +class DataChecker : public CheckerManager::Checker { +public: + DataChecker() noexcept; + ~DataChecker(); + + bool IsValid(const std::vector &privileges, const CheckerManager::CheckInfo &info) override; + +private: + static DataChecker instance_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_DATA_CHECKER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp b/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d5771ce6b68742987b6d2d430a233e8bf9d4bf6e --- /dev/null +++ b/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "UriPermissionManager" + +#include "uri_permission_manager.h" + +#include "want.h" +#include "uri.h" +#include "uri_permission_manager_client.h" + +#include "log_print.h" + +namespace OHOS { +namespace UDMF { +UriPermissionManager &UriPermissionManager::GetInstance() +{ + static UriPermissionManager instance; + return instance; +} + +Status UriPermissionManager::GrantUriPermission(const std::string &path, const std::string &bundleName) +{ + Uri uri(path); + int autoRemove = 1; + auto status = AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermission( + uri, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, bundleName, autoRemove); + if (status != ERR_OK) { + ZLOGE("GrantUriPermission failed, %{public}d", status); + return E_ERROR; + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/include/autils/kv_store_task.h b/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h old mode 100644 new mode 100755 similarity index 55% rename from services/distributeddataservice/adapter/include/autils/kv_store_task.h rename to services/distributeddataservice/service/udmf/permission/uri_permission_manager.h index 30891bb0d4338202d6c56b41623224c79e1037c0..db32e3114015599fc3c45656df8bc0fe4e028ad2 --- a/services/distributeddataservice/adapter/include/autils/kv_store_task.h +++ b/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h @@ -1,39 +1,33 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef KV_STORE_TASK_H -#define KV_STORE_TASK_H - -#include -#include -#include "visibility.h" - -namespace OHOS { -namespace DistributedKv { -class KvStoreTask { -public: - KVSTORE_API ~KvStoreTask() {} - KVSTORE_API KvStoreTask(std::function lambda); - KVSTORE_API KvStoreTask(std::function lambda, const std::string &taskName); - KVSTORE_API void operator()(); - -private: - std::function task_; - std::string name_; -}; -} // namespace DistributedKv -} // namespace OHOS - -#endif // TASK_H +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_URI_PERMISSION_MANAGER_H +#define UDMF_URI_PERMISSION_MANAGER_H + +#include +#include + +#include "error_code.h" + +namespace OHOS { +namespace UDMF { +class UriPermissionManager { +public: + static UriPermissionManager &GetInstance(); + Status GrantUriPermission(const std::string &path, const std::string &bundleName); +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_URI_PERMISSION_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp new file mode 100755 index 0000000000000000000000000000000000000000..0e95ffd26729a9bb15fa70d71788418e16ff5081 --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -0,0 +1,179 @@ +/* + * 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. + */ +#define LOG_TAG "PreProcessUtils" + +#include "preprocess_utils.h" + +#include + +#include "accesstoken_kit.h" +#include "bundlemgr/bundle_mgr_client_impl.h" +#include "device_manager_adapter.h" +#include "error_code.h" +#include "file.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "remote_file_share.h" +#include "uri.h" +namespace OHOS { +namespace UDMF { +static constexpr int ID_LEN = 32; +const char SPECIAL = '^'; +using namespace Security::AccessToken; +using namespace OHOS::AppFileService::ModuleRemoteFileShare; + +int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option) +{ + auto it = UD_INTENTION_MAP.find(option.intention); + if (it == UD_INTENTION_MAP.end()) { + return E_UNKNOWN; + } + std::string bundleName; + GetHapBundleNameByToken(option.tokenId, bundleName); + std::string intention = it->second; + UnifiedKey key(intention, bundleName, IdGenerator()); + Privilege privilege; + privilege.tokenId = option.tokenId; + Runtime runtime; + runtime.key = key; + runtime.privileges.emplace_back(privilege); + runtime.createTime = GetTimeStamp(); + runtime.sourcePackage = bundleName; + runtime.createPackage = bundleName; + runtime.deviceId = GetLocalDeviceId(); + data.SetRuntime(runtime); + return E_OK; +} + +std::string PreProcessUtils::IdGenerator() +{ + std::random_device randomDevice; + int minimum = 48; + int maximum = 121; + std::uniform_int_distribution distribution(minimum, maximum); + std::stringstream idStr; + for (int32_t i = 0; i < ID_LEN; i++) { + auto asc = distribution(randomDevice); + asc = asc >= SPECIAL ? asc + 1 : asc; + idStr << static_cast(asc); + } + return idStr.str(); +} + +time_t PreProcessUtils::GetTimeStamp() +{ + std::chrono::time_point tp = + std::chrono::time_point_cast(std::chrono::system_clock::now()); + time_t timestamp = tp.time_since_epoch().count(); + return timestamp; +} + +int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId) +{ + Security::AccessToken::HapTokenInfo tokenInfo; + auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + ZLOGE("GetHapUidByToken failed, result = %{public}d.", result); + return E_ERROR; + } + return tokenInfo.userID; +} + +bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) +{ + Security::AccessToken::HapTokenInfo hapInfo; + if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) + != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + return false; + } + bundleName = hapInfo.bundleName; + return true; +} + +bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) +{ + Security::AccessToken::NativeTokenInfo nativeInfo; + if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, nativeInfo) + != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + return false; + } + processName = nativeInfo.processName; + return true; +} + +std::string PreProcessUtils::GetLocalDeviceId() +{ + auto info = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice(); + std::string encryptedUuid = DistributedData::DeviceManagerAdapter::GetInstance().CalcClientUuid(" ", info.uuid); + return encryptedUuid; +} + +void PreProcessUtils::SetRemoteData(UnifiedData &data) +{ + if (data.IsEmpty()) { + ZLOGD("invalid data."); + return; + } + std::shared_ptr runtime = data.GetRuntime(); + if (runtime->deviceId == GetLocalDeviceId()) { + ZLOGD("not remote data."); + return; + } + ZLOGD("is remote data."); + auto records = data.GetRecords(); + for (auto record : records) { + auto type = record->GetType(); + if (IsFileType(type)) { + auto file = static_cast(record.get()); + UDDetails details = file->GetDetails(); + details.insert({"isRemote", "true"}); + file->SetDetails(details); + } + } +} + +bool PreProcessUtils::IsFileType(UDType udType) +{ + return (udType == UDType::FILE || udType == UDType::IMAGE || udType == UDType::VIDEO || udType == UDType::AUDIO + || udType == UDType::FOLDER); +} + +int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) +{ + int32_t userId = GetHapUidByToken(tokenId); + std::string bundleName = data.GetRuntime()->createPackage; + for (const auto &record : data.GetRecords()) { + if (record != nullptr && IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + if (file->GetUri().empty()) { + continue; + } + Uri uri(file->GetUri()); + if (uri.GetAuthority().empty()) { + continue; + } + struct HmdfsUriInfo dfsUriInfo; + int ret = RemoteFileShare::GetDfsUriFromLocal(file->GetUri(), userId, dfsUriInfo); + if (ret != 0 || dfsUriInfo.uriStr.empty()) { + ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d.", ret, userId); + return E_FS_ERROR; + } + file->SetRemoteUri(dfsUriInfo.uriStr); + } + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..129b42c13f7d3260df7adace17e3b07b617c4d7d --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UDMF_PREPROCESS_UTILS_H +#define UDMF_PREPROCESS_UTILS_H + +#include +#include +#include +#include + +#include "unified_data.h" +#include "unified_meta.h" + +namespace OHOS { +namespace UDMF { +class PreProcessUtils { +public: + static int32_t RuntimeDataImputation(UnifiedData &data, CustomOption &option); + static std::string IdGenerator(); + static time_t GetTimeStamp(); + static int32_t GetHapUidByToken(uint32_t tokenId); + static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); + static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); + static std::string GetLocalDeviceId(); + static void SetRemoteData(UnifiedData &data); + static bool IsFileType(UDType udType); + static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_PREPROCESS_UTILS_H \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/executor_factory.h b/services/distributeddataservice/service/udmf/same_process_ipc_guard.h similarity index 46% rename from services/distributeddataservice/service/kvdb/executor_factory.h rename to services/distributeddataservice/service/udmf/same_process_ipc_guard.h index 42d05757d001b58fa2218b8963601abcb4216dc0..02ecb47e84f960720b8d33826b1660d3f9a12acb 100644 --- a/services/distributeddataservice/service/kvdb/executor_factory.h +++ b/services/distributeddataservice/service/udmf/same_process_ipc_guard.h @@ -1,36 +1,43 @@ -/* -* 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. -*/ -#ifndef DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H -#define DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H - -#include "kv_store_thread_pool.h" -namespace OHOS::DistributedData { -using OHOS::DistributedKv::KvStoreTask; -using OHOS::DistributedKv::KvStoreThreadPool; -class ExecutorFactory { -public: - API_EXPORT static ExecutorFactory &GetInstance(); - API_EXPORT bool Execute(KvStoreTask &&task); - -private: - ExecutorFactory(); - ~ExecutorFactory(); - - static constexpr int POOL_SIZE = 4; - - std::shared_ptr threadPool_; -}; -} // namespace OHOS::DistributedData -#endif // DISTRIBUTEDDATAMGR_DATAMGR_EXECUTOR_FACTORY_H +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef UDMF_SAMEPROCESSIPCGUARD_H +#define UDMF_SAMEPROCESSIPCGUARD_H + +#include + +#include "ipc_skeleton.h" + +namespace OHOS { +namespace UDMF { +class SameProcessIpcGuard { +public: + SameProcessIpcGuard() + { + identity = IPCSkeleton::ResetCallingIdentity(); + } + + ~SameProcessIpcGuard() + { + IPCSkeleton::SetCallingIdentity(identity); + } + +private: + std::string identity; +}; +} // namespace UDMF +} // namespace OHOS + +#endif // UDMF_SAMEPROCESSIPCGUARD_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp new file mode 100755 index 0000000000000000000000000000000000000000..05ad7c4072ae9d55045a4c64d9bb4c49629ad122 --- /dev/null +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -0,0 +1,313 @@ +/* + * 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. + */ +#define LOG_TAG "RuntimeStore" + +#include "runtime_store.h" + +#include +#include + +#include "log_print.h" +#include "same_process_ipc_guard.h" +#include "tlv_util.h" + +namespace OHOS { +namespace UDMF { +using namespace DistributedKv; +const AppId RuntimeStore::APP_ID = { "distributeddata" }; +const std::string RuntimeStore::DATA_PREFIX = "udmf://"; +const std::string RuntimeStore::BASE_DIR = "/data/service/el1/public/database/distributeddata"; + +RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_({ storeId }) +{ + UpdateTime(); + ZLOGI("Construct runtimeStore: %{public}s.", storeId_.storeId.c_str()); +} + +RuntimeStore::~RuntimeStore() +{ + ZLOGI("Destruct runtimeStore: %{public}s.", storeId_.storeId.c_str()); + Close(); +} + +Status RuntimeStore::Put(const UnifiedData &unifiedData) +{ + UpdateTime(); + std::vector entries; + std::string unifiedKey = unifiedData.GetRuntime()->key.GetUnifiedKey(); + // add unified record + for (const auto &record : unifiedData.GetRecords()) { + if (record == nullptr) { + ZLOGE("record is nullptr."); + return E_INVALID_PARAMETERS; + } + + std::vector recordBytes; + auto recordTlv = TLVObject(recordBytes); + if (!TLVUtil::Writing(record, recordTlv)) { + ZLOGI("Marshall unified record failed."); + return E_WRITE_PARCEL_ERROR; + } + + Entry entry = { Key(unifiedKey + "/" + record->GetUid()), Value(recordBytes) }; + entries.push_back(entry); + } + // add runtime info + std::vector runtimeBytes; + auto runtimeTlv = TLVObject(runtimeBytes); + if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv)) { + ZLOGI("Marshall runtime info failed."); + return E_WRITE_PARCEL_ERROR; + } + Entry entry = { Key(unifiedKey), Value(runtimeBytes) }; + entries.push_back(entry); + auto status = PutEntries(entries); + return status; +} + +Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) +{ + UpdateTime(); + std::vector entries; + if (GetEntries(key, entries) != E_OK) { + ZLOGI("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); + return E_DB_ERROR; + } + if (entries.empty()) { + ZLOGD("entries is empty."); + return E_OK; + } + return UnMarshalEntries(key, entries, unifiedData); +} + +Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) +{ + UpdateTime(); + UnifiedData unifiedData; + if (Get(key, unifiedData) != E_OK) { + ZLOGE("Get unified data failed."); + return E_DB_ERROR; + } + + for (const auto &record : unifiedData.GetRecords()) { + int64_t recordSize = record->GetSize(); + auto it = summary.summary.find(UD_TYPE_MAP.at(record->GetType())); + if (it == summary.summary.end()) { + summary.summary[UD_TYPE_MAP.at(record->GetType())] = recordSize; + } else { + summary.summary[UD_TYPE_MAP.at(record->GetType())] += recordSize; + } + summary.totalSize += recordSize; + } + return E_OK; +} + +Status RuntimeStore::Update(const UnifiedData &unifiedData) +{ + UpdateTime(); + std::string key = unifiedData.GetRuntime()->key.key; + if (Delete(key) != E_OK) { + ZLOGE("Delete unified data failed."); + return E_DB_ERROR; + } + if (Put(unifiedData) != E_OK) { + ZLOGE("Put unified data failed."); + return E_DB_ERROR; + } + return E_OK; +} + +Status RuntimeStore::Delete(const std::string &key) +{ + UpdateTime(); + std::vector entries; + if (GetEntries(key, entries) != E_OK) { + ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); + return E_DB_ERROR; + } + if (entries.empty()) { + ZLOGD("entries is empty."); + return E_OK; + } + std::vector keys; + for (const auto &entry : entries) { + keys.push_back(entry.key); + } + return DeleteEntries(keys); +} + +Status RuntimeStore::DeleteBatch(const std::vector &unifiedKeys) +{ + UpdateTime(); + ZLOGD("called!"); + if (unifiedKeys.empty()) { + ZLOGD("No need to delete!"); + return E_OK; + } + for (const std::string &unifiedKey : unifiedKeys) { + if (Delete(unifiedKey) != E_OK) { + ZLOGE("Delete failed, key: %{public}s.", unifiedKey.c_str()); + return E_DB_ERROR; + } + } + return E_OK; +} + +Status RuntimeStore::Sync(const std::vector &devices) +{ + UpdateTime(); + SameProcessIpcGuard ipcGuard; + DistributedKv::Status status = kvStore_->Sync(devices, SyncMode::PULL); + if (status != DistributedKv::Status::SUCCESS) { + ZLOGE("Sync kvStore failed, status: %{public}d.", status); + return E_DB_ERROR; + } + return E_OK; +} + +Status RuntimeStore::Clear() +{ + UpdateTime(); + return Delete(DATA_PREFIX); +} + +Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) +{ + UpdateTime(); + std::vector entries; + auto status = GetEntries(dataPrefix, entries); + if (status != E_OK) { + ZLOGE("GetEntries failed, dataPrefix: %{public}s.", dataPrefix.c_str()); + return E_DB_ERROR; + } + if (entries.empty()) { + ZLOGD("entries is empty."); + return E_OK; + } + std::vector keySet; + for (const auto &entry : entries) { + std::string keyStr = entry.key.ToString(); + if (std::count(keyStr.begin(), keyStr.end(), '/') == SLASH_COUNT_IN_KEY) { + keySet.emplace_back(keyStr); + } + } + + for (const std::string &key : keySet) { + UnifiedData data; + if (UnMarshalEntries(key, entries, data) != E_OK) { + return E_READ_PARCEL_ERROR; + } + unifiedDataSet.emplace_back(data); + } + return E_OK; +} + +void RuntimeStore::Close() +{ + dataManager_.CloseKvStore(APP_ID, storeId_); +} + +bool RuntimeStore::Init() +{ + Options options; + options.autoSync = false; + options.createIfMissing = true; + options.rebuild = true; + options.backup = false; + options.securityLevel = SecurityLevel::S1; + options.baseDir = BASE_DIR; + options.area = Area::EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + SameProcessIpcGuard ipcGuard; + DistributedKv::Status status = dataManager_.GetSingleKvStore(options, APP_ID, storeId_, kvStore_); + if (status != DistributedKv::Status::SUCCESS) { + ZLOGE("GetKvStore: %{public}s failed, status: %{public}d.", storeId_.storeId.c_str(), status); + return false; + } + return true; +} + +Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vector &entries) +{ + DataQuery query; + query.KeyPrefix(dataPrefix); + query.OrderByWriteTime(true); + auto status = kvStore_->GetEntries(query, entries); + if (status != DistributedKv::Status::SUCCESS) { + ZLOGE("KvStore getEntries failed, status: %{public}d.", static_cast(status)); + return E_DB_ERROR; + } + return E_OK; +} + +Status RuntimeStore::PutEntries(const std::vector &entries) +{ + size_t size = entries.size(); + DistributedKv::Status status; + for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { + std::vector batchEntries( + entries.begin() + index, entries.begin() + std::min(index + MAX_BATCH_SIZE, size)); + status = kvStore_->PutBatch(batchEntries); + if (status != DistributedKv::Status::SUCCESS) { + ZLOGE("KvStore putBatch failed, status: %{public}d.", status); + return E_DB_ERROR; + } + } + return E_OK; +} + +Status RuntimeStore::DeleteEntries(const std::vector &keys) +{ + size_t size = keys.size(); + DistributedKv::Status status; + for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { + std::vector batchKeys(keys.begin() + index, keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); + status = kvStore_->DeleteBatch(batchKeys); + if (status != DistributedKv::Status::SUCCESS) { + ZLOGE("KvStore deleteBatch failed, status: %{public}d.", status); + return E_DB_ERROR; + } + } + return E_OK; +} + +Status RuntimeStore::UnMarshalEntries(const std::string &key, std::vector &entries, UnifiedData &unifiedData) +{ + for (const auto &entry : entries) { + std::string keyStr = entry.key.ToString(); + if (keyStr == key) { + Runtime runtime; + auto runtimeTlv = TLVObject(const_cast &>(entry.value.Data())); + if (!TLVUtil::Reading(runtime, runtimeTlv)) { + ZLOGE("Unmarshall runtime info failed."); + return E_READ_PARCEL_ERROR; + } + unifiedData.SetRuntime(runtime); + break; + } + if (keyStr.find(key) == 0) { + std::shared_ptr record; + auto recordTlv = TLVObject(const_cast &>(entry.value.Data())); + if (!TLVUtil::Reading(record, recordTlv)) { + ZLOGE("Unmarshall unified record failed."); + return E_READ_PARCEL_ERROR; + } + unifiedData.AddRecord(record); + } + } + return E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h new file mode 100755 index 0000000000000000000000000000000000000000..d819e64c9bf258ecba2da5156b1b233f54aba384 --- /dev/null +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_RUNTIMESTORE_H +#define UDMF_RUNTIMESTORE_H + +#include "distributed_kv_data_manager.h" +#include "single_kvstore.h" + +#include "store.h" + +namespace OHOS { +namespace UDMF { +class RuntimeStore final : public Store { +public: + explicit RuntimeStore(const std::string &storeId); + ~RuntimeStore(); + Status Put(const UnifiedData &unifiedData) override; + Status Get(const std::string &key, UnifiedData &unifiedData) override; + Status GetSummary(const std::string &key, Summary &summary) override; + Status Update(const UnifiedData &unifiedData) override; + Status Delete(const std::string &key) override; + Status DeleteBatch(const std::vector &unifiedKeys) override; + Status Sync(const std::vector &devices) override; + Status Clear() override; + Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) override; + void Close() override; + bool Init() override; + +private: + static const DistributedKv::AppId APP_ID; + static const std::string DATA_PREFIX; + static const std::string BASE_DIR; + static constexpr std::int32_t SLASH_COUNT_IN_KEY = 4; + static constexpr std::int32_t MAX_BATCH_SIZE = 128; + DistributedKv::DistributedKvDataManager dataManager_; + std::shared_ptr kvStore_; + DistributedKv::StoreId storeId_; + Status GetEntries(const std::string &dataPrefix, std::vector &entries); + Status PutEntries(const std::vector &entries); + Status DeleteEntries(const std::vector &keys); + Status UnMarshalEntries( + const std::string &key, std::vector &entries, UnifiedData &unifiedData); +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_RUNTIMESTORE_H diff --git a/services/distributeddataservice/service/udmf/store/store.h b/services/distributeddataservice/service/udmf/store/store.h new file mode 100755 index 0000000000000000000000000000000000000000..519a79b731e911112089a2eae4857f25bd2aa3d3 --- /dev/null +++ b/services/distributeddataservice/service/udmf/store/store.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_STORE_H +#define UDMF_STORE_H + +#include +#include + +#include "error_code.h" +#include "unified_data.h" +#include "unified_key.h" +#include "unified_types.h" + +namespace OHOS { +namespace UDMF { +class Store { +public: + using Time = std::chrono::steady_clock::time_point; + virtual Status Put(const UnifiedData &unifiedData) = 0; + virtual Status Get(const std::string &key, UnifiedData &unifiedData) = 0; + virtual Status GetSummary(const std::string &key, Summary &summary) = 0; + virtual Status Update(const UnifiedData &unifiedData) = 0; + virtual Status Delete(const std::string &key) = 0; + virtual Status DeleteBatch(const std::vector &unifiedKeys) = 0; + virtual Status Sync(const std::vector &devices) = 0; + virtual Status Clear() = 0; + virtual bool Init() = 0; + virtual void Close() = 0; + virtual Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) = 0; + + bool operator<(const Time &time) const + { + std::shared_lock lock(timeMutex_); + return time_ < time; + } + + void UpdateTime() + { + std::unique_lock lock(timeMutex_); + time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + } +private: + static constexpr int64_t INTERVAL = 1; // 1 min + mutable Time time_; + mutable std::shared_mutex timeMutex_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_STORE_H diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp new file mode 100755 index 0000000000000000000000000000000000000000..7f53f27c331143df9b74fc435b5618f557b85f42 --- /dev/null +++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -0,0 +1,76 @@ +/* + * 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. + */ +#define LOG_TAG "StoreCache" + +#include "store_cache.h" +#include + +#include "log_print.h" +#include "runtime_store.h" +#include "unified_meta.h" + +namespace OHOS { +namespace UDMF { +std::shared_ptr StoreCache::executorPool_ = std::make_shared(2, 1); + +std::shared_ptr StoreCache::GetStore(std::string intention) +{ + std::shared_ptr store; + stores_.Compute(intention, [&store](const auto &intention, std::shared_ptr &storePtr) -> bool { + if (storePtr != nullptr) { + store = storePtr; + return true; + } + + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG) + || intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) { + storePtr = std::make_shared(intention); + if (!storePtr->Init()) { + ZLOGE("Init runtime store failed."); + return false; + } + store = storePtr; + return true; + } + return false; + }); + + std::unique_lock lock(taskMutex_); + if (taskId_ == ExecutorPool::INVALID_TASK_ID) { + taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); + } + return store; +} + +void StoreCache::GarbageCollect() +{ + auto current = std::chrono::steady_clock::now(); + stores_.EraseIf([¤t](auto &key, std::shared_ptr &storePtr) { + if (*storePtr < current) { + ZLOGD("GarbageCollect, stores:%{public}s time limit, will be close.", key.c_str()); + return true; + } + return false; + }); + std::unique_lock lock(taskMutex_); + if (!stores_.Empty()) { + ZLOGE("GarbageCollect, stores size:%{public}zu", stores_.Size()); + taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); + } else { + taskId_ = ExecutorPool::INVALID_TASK_ID; + } +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.h b/services/distributeddataservice/service/udmf/store/store_cache.h old mode 100644 new mode 100755 similarity index 46% rename from services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.h rename to services/distributeddataservice/service/udmf/store/store_cache.h index c0c745bde03c7513eb317cbde9eff080d781a0a4..59807f747daf5108f147db13954b04f5bc2f5916 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread.h +++ b/services/distributeddataservice/service/udmf/store/store_cache.h @@ -1,40 +1,45 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef KV_STORE_THREAD_H -#define KV_STORE_THREAD_H - -#include -#include "kv_store_thread_pool.h" - -namespace OHOS { -namespace DistributedKv { -class KvStoreThread { -public: - explicit KvStoreThread(KvStoreThreadPool *threadPool, const std::string &name); - KvStoreThread(KvStoreThread &&thread) = delete; - KvStoreThread(const KvStoreThread &) = delete; - KvStoreThread &operator=(KvStoreThread &&) = delete; - KvStoreThread &operator=(const KvStoreThread &) = delete; - void Run(KvStoreThreadPool *threadPool); - void Join(); - ~KvStoreThread(); -private: - std::thread realThread_; -}; -} // namespace DistributedKv -} // namespace OHOS - -#endif // KV_STORE_THREAD_H +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_STORE_CACHE_H +#define UDMF_STORE_CACHE_H + +#include +#include + +#include "concurrent_map.h" +#include "executor_pool.h" +#include "store.h" +#include "unified_meta.h" + +namespace OHOS { +namespace UDMF { +class StoreCache { +public: + std::shared_ptr GetStore(std::string intention); + +private: + void GarbageCollect(); + + ConcurrentMap> stores_; + std::mutex taskMutex_; + ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; + + static constexpr int64_t INTERVAL = 1; // 1 min + static std::shared_ptr executorPool_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_STORE_CACHE_H diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp new file mode 100755 index 0000000000000000000000000000000000000000..b343283bdc90f86b07923efe2f7dd0f535a3cadf --- /dev/null +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -0,0 +1,147 @@ +/* + * 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. + */ +#define LOG_TAG "UdmfServiceImpl" + +#include "udmf_service_impl.h" + +#include "iservice_registry.h" + +#include "data_manager.h" +#include "lifecycle/lifecycle_manager.h" +#include "log_print.h" +#include "preprocess_utils.h" +#include "reporter.h" + +namespace OHOS { +namespace UDMF { +using FeatureSystem = DistributedData::FeatureSystem; +using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; +using Reporter = OHOS::DistributedDataDfx::Reporter; +__attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; +UdmfServiceImpl::Factory::Factory() +{ + ZLOGI("Register udmf creator!"); + FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() { + if (product_ == nullptr) { + product_ = std::make_shared(); + } + return product_; + }); +} + +UdmfServiceImpl::Factory::~Factory() +{ + product_ = nullptr; +} + +int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) +{ + ZLOGD("start"); + int32_t res = E_OK; + UdmfBehaviourMsg msg; + auto find = UD_INTENTION_MAP.find(option.intention); + msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; + msg.operation = "insert"; + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) { + msg.appId = "unknown"; + res = E_ERROR; + } else { + msg.appId = bundleName; + res = DataManager::GetInstance().SaveData(option, unifiedData, key); + } + auto errFind = ERROR_MAP.find(res); + msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; + msg.dataType = unifiedData.GetTypes(); + msg.dataSize = unifiedData.GetSize(); + Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); + return res; +} + +int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData) +{ + ZLOGD("start"); + int32_t res = E_OK; + UdmfBehaviourMsg msg; + auto find = UD_INTENTION_MAP.find(query.intention); + msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; + msg.operation = "insert"; + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { + msg.appId = "unknown"; + res = E_ERROR; + } else { + msg.appId = bundleName; + res = DataManager::GetInstance().RetrieveData(query, unifiedData); + } + auto errFind = ERROR_MAP.find(res); + msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; + msg.dataType = unifiedData.GetTypes(); + msg.dataSize = unifiedData.GetSize(); + Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); + return res; +} + +int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) +{ + ZLOGD("start"); + return DataManager::GetInstance().RetrieveBatchData(query, unifiedDataSet); +} + +int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData) +{ + ZLOGD("start"); + return DataManager::GetInstance().UpdateData(query, unifiedData); +} + +int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector &unifiedDataSet) +{ + ZLOGD("start"); + return DataManager::GetInstance().DeleteData(query, unifiedDataSet); +} + +int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) +{ + ZLOGD("start"); + return DataManager::GetInstance().GetSummary(query, summary); +} + +int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege) +{ + ZLOGD("start"); + return DataManager::GetInstance().AddPrivilege(query, privilege); +} + +int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) +{ + ZLOGD("start"); + return DataManager::GetInstance().Sync(query, devices); +} + +int32_t UdmfServiceImpl::OnInitialize() +{ + ZLOGD("start"); + Status status = LifeCycleManager::GetInstance().DeleteOnStart(); + if (status != E_OK) { + ZLOGE("DeleteOnStart execute failed, status: %{public}d", status); + } + status = LifeCycleManager::GetInstance().DeleteOnSchedule(); + if (status != E_OK) { + ZLOGE("ScheduleTask start failed, status: %{public}d", status); + } + return DistributedData::FeatureSystem::STUB_SUCCESS; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h old mode 100644 new mode 100755 similarity index 32% rename from services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.h rename to services/distributeddataservice/service/udmf/udmf_service_impl.h index 10051ff1f03e189ca0703840b0301171e366de30..30b9dafd5be0142600e4fd5c71af2cee22acc334 --- a/services/distributeddataservice/adapter/autils/src/thread_pool/kv_store_thread_pool_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,41 +13,44 @@ * limitations under the License. */ -#ifndef KV_STORE_THREAD_POOL_IMPL_H -#define KV_STORE_THREAD_POOL_IMPL_H +#ifndef UDMF_SERVICE_IMPL_H +#define UDMF_SERVICE_IMPL_H -#include -#include -#include -#include "kv_store_thread_pool.h" -#include "kv_store_thread.h" +#include + +#include "udmf_service_stub.h" namespace OHOS { -namespace DistributedKv { -class KvStoreThreadPoolImpl : public KvStoreThreadPool { +namespace UDMF { +/* + * UDMF server implementation + */ +class UdmfServiceImpl final : public UdmfServiceStub { public: - KvStoreThreadPoolImpl(int threadNum, std::string poolName, bool startImmediately); - KvStoreThreadPoolImpl() = delete; - KvStoreThreadPoolImpl(const KvStoreThreadPoolImpl &) = delete; - KvStoreThreadPoolImpl(KvStoreThreadPoolImpl &&) = delete; - KvStoreThreadPoolImpl& operator=(const KvStoreThreadPoolImpl &) = delete; - KvStoreThreadPoolImpl& operator=(KvStoreThreadPoolImpl &&) = delete; - bool AddTask(KvStoreTask &&task) override; - void Stop() final; - KvStoreTask ScheduleTask(); - bool IsRunning() const; - virtual ~KvStoreThreadPoolImpl(); + UdmfServiceImpl() = default; + ~UdmfServiceImpl() = default; + + int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; + int32_t GetData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) override; + int32_t UpdateData(const QueryOption &query, UnifiedData &unifiedData) override; + int32_t DeleteData(const QueryOption &query, std::vector &unifiedDataSet) override; + int32_t GetSummary(const QueryOption &query, Summary &summary) override; + int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; + int32_t Sync(const QueryOption &query, const std::vector &devices) override; + int32_t OnInitialize() override; + private: - std::mutex taskListMutex{}; - std::list taskList{}; - std::condition_variable has_task{}; - std::list threadList{}; - int threadNum; - void Start(); - bool running = false; - static constexpr int MAX_THREAD_NAME_SIZE = 11; + class Factory { + public: + Factory(); + ~Factory(); + + private: + std::shared_ptr product_; + }; + static Factory factory_; }; -} // namespace DistributedKv +} // namespace UDMF } // namespace OHOS - -#endif // KV_STORE_THREAD_POOL_IMPL_H +#endif // UDMF_SERVICE_IMPL_H diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp new file mode 100755 index 0000000000000000000000000000000000000000..ca92a0fbf8bbe8b00517da6dc08765ee554508c1 --- /dev/null +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -0,0 +1,247 @@ +/* + * 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. + */ +#define LOG_TAG "UdmfServiceStub" + +#include "udmf_service_stub.h" + +#include + +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "udmf_types_util.h" +#include "unified_data.h" +#include "unified_meta.h" + +namespace OHOS { +namespace UDMF { +constexpr UdmfServiceStub::Handler + UdmfServiceStub::HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)]; +int UdmfServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start##code = %{public}u", code); + std::u16string myDescripter = UdmfServiceStub::GetDescriptor(); + std::u16string remoteDescripter = data.ReadInterfaceToken(); + if (myDescripter != remoteDescripter) { + ZLOGE("end##descriptor checked fail"); + return -1; + } + if (static_cast(UdmfServiceInterfaceCode::CODE_HEAD) > code || + code >= static_cast(UdmfServiceInterfaceCode::CODE_BUTT)) { + return -1; + } + return (this->*HANDLERS[code])(data, reply); +} + +int32_t UdmfServiceStub::OnSetData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + CustomOption customOption; + UnifiedData unifiedData; + if (!ITypesUtil::Unmarshal(data, customOption, unifiedData)) { + ZLOGE("Unmarshal customOption or unifiedData failed!"); + return E_READ_PARCEL_ERROR; + } + if (unifiedData.IsEmpty()) { + ZLOGE("Empty data without any record!"); + return E_INVALID_PARAMETERS; + } + if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { + ZLOGE("Exceeded data limit!"); + return E_INVALID_PARAMETERS; + } + for (const auto &record : unifiedData.GetRecords()) { + if (record == nullptr) { + ZLOGE("record is nullptr!"); + return E_INVALID_PARAMETERS; + } + if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { + ZLOGE("Exceeded record limit!"); + return E_INVALID_PARAMETERS; + } + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + customOption.tokenId = token; + std::string key; + int32_t status = SetData(customOption, unifiedData, key); + 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; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + ZLOGE("Unmarshal queryOption failed!"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + UnifiedData unifiedData; + int32_t status = GetData(query, unifiedData); + if (!ITypesUtil::Marshal(reply, status, unifiedData)) { + ZLOGE("Marshal status or unifiedData failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetBatchData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + ZLOGE("Unmarshal queryOption failed!"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + std::vector unifiedDataSet; + int32_t status = GetBatchData(query, unifiedDataSet); + if (!ITypesUtil::Marshal(reply, status, unifiedDataSet)) { + ZLOGE("Marshal status or unifiedDataSet failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnUpdateData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + UnifiedData unifiedData; + if (!ITypesUtil::Unmarshal(data, query, unifiedData)) { + ZLOGE("Unmarshal queryOption or unifiedData failed!"); + return E_READ_PARCEL_ERROR; + } + if (unifiedData.IsEmpty()) { + ZLOGE("Empty data without any record!"); + return E_INVALID_PARAMETERS; + } + if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { + ZLOGE("Exceeded data limit!"); + return E_INVALID_PARAMETERS; + } + for (const auto &record : unifiedData.GetRecords()) { + if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { + ZLOGE("Exceeded record limit!"); + return E_INVALID_PARAMETERS; + } + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t status = UpdateData(query, unifiedData); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnDeleteData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + ZLOGE("Unmarshal queryOption failed!"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + std::vector unifiedDataSet; + int32_t status = DeleteData(query, unifiedDataSet); + if (!ITypesUtil::Marshal(reply, status, unifiedDataSet)) { + ZLOGE("Marshal status or unifiedDataSet failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetSummary(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + if (!ITypesUtil::Unmarshal(data, query)) { + ZLOGE("Unmarshal query failed"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + Summary summary; + int32_t status = GetSummary(query, summary); + if (!ITypesUtil::Marshal(reply, status, summary)) { + ZLOGE("Marshal summary failed, key: %{public}s", query.key.c_str()); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnAddPrivilege(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + Privilege privilege; + if (!ITypesUtil::Unmarshal(data, query, privilege)) { + ZLOGE("Unmarshal query and privilege failed"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t status = AddPrivilege(query, privilege); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status failed, key: %{public}s", query.key.c_str()); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnSync(MessageParcel &data, MessageParcel &reply) +{ + ZLOGI("start"); + QueryOption query; + std::vector devices; + if (!ITypesUtil::Unmarshal(data, query, devices)) { + ZLOGE("Unmarshal query and devices failed"); + return E_READ_PARCEL_ERROR; + } + uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); + query.tokenId = token; + int32_t status = Sync(query, devices); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status failed, key: %{public}s", query.key.c_str()); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +/* + * Check whether the caller has the permission to access data. + */ +bool UdmfServiceStub::VerifyPermission(const std::string &permission) +{ +#ifdef UDMF_PERMISSION_ENABLED + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); + return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED; +#else + return true; +#endif // UDMF_PERMISSION_ENABLED +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.h b/services/distributeddataservice/service/udmf/udmf_service_stub.h new file mode 100755 index 0000000000000000000000000000000000000000..d3a739999eff4280cb5d19a98be564dab15c4aa2 --- /dev/null +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_SERVICE_STUB_H +#define UDMF_SERVICE_STUB_H + +#include +#include + +#include "feature/feature_system.h" +#include "message_parcel.h" + +#include "distributeddata_udmf_ipc_interface_code.h" +#include "error_code.h" +#include "udmf_service.h" + +namespace OHOS { +namespace UDMF { +/* + * UDMF server stub + */ +class UdmfServiceStub : public UdmfService, public DistributedData::FeatureSystem::Feature { +public: + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; + +private: + int32_t OnSetData(MessageParcel &data, MessageParcel &reply); + int32_t OnGetData(MessageParcel &data, MessageParcel &reply); + int32_t OnGetBatchData(MessageParcel &data, MessageParcel &reply); + int32_t OnUpdateData(MessageParcel &data, MessageParcel &reply); + int32_t OnDeleteData(MessageParcel &data, MessageParcel &reply); + int32_t OnGetSummary(MessageParcel &data, MessageParcel &reply); + int32_t OnAddPrivilege(MessageParcel &data, MessageParcel &reply); + int32_t OnSync(MessageParcel &data, MessageParcel &reply); + + bool VerifyPermission(const std::string &permission); + + const std::string READ_PERMISSION = "ohos.permission.READ_UDMF_DATA"; + const std::string WRITE_PERMISSION = "ohos.permission.WRITE_UDMF_DATA"; + const std::string SYNC_PERMISSION = "ohos.permission.SYNC_UDMF_DATA"; + + using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); + static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { + &UdmfServiceStub::OnSetData, + &UdmfServiceStub::OnGetData, + &UdmfServiceStub::OnGetBatchData, + &UdmfServiceStub::OnUpdateData, + &UdmfServiceStub::OnDeleteData, + &UdmfServiceStub::OnGetSummary, + &UdmfServiceStub::OnAddPrivilege, + &UdmfServiceStub::OnSync + }; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_SERVICE_STUB_H diff --git a/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn b/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn index d223694029b9c52221fc57e871e4275fc1a37772..2cc4e27734b93c9ab1a459852dcdae3d541667ff 100644 --- a/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn +++ b/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn @@ -69,7 +69,7 @@ ohos_fuzztest("SchemaQueryFuzzTest") { external_deps = [ "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] } diff --git a/test/fuzztest/autolaunch_fuzzer/BUILD.gn b/test/fuzztest/autolaunch_fuzzer/BUILD.gn index fb3e4402dca8637e48a9dc91c7ef701aa02b0a7a..92344ab4c02b9b97f49192a543f9048af666b183 100644 --- a/test/fuzztest/autolaunch_fuzzer/BUILD.gn +++ b/test/fuzztest/autolaunch_fuzzer/BUILD.gn @@ -89,7 +89,7 @@ ohos_fuzztest("AutoLaunchFuzzTest") { external_deps = [ "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", ] } diff --git a/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn b/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn index 9ee8840fe0628534ba4f8cfba0ad1cba72e4b125..d6de3de8e84b3ce70dae1eb3e0860047fc55e02c 100644 --- a/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn +++ b/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn @@ -90,7 +90,7 @@ ohos_fuzztest("KvStoreDiskSizeFuzzTest") { external_deps = [ "c_utils:utils", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", ] }