From 59e8751c187a448a5276f71a15ab10e528f1b2b6 Mon Sep 17 00:00:00 2001 From: wangzhaohao Date: Thu, 9 Jan 2025 22:02:10 +0800 Subject: [PATCH] add profil_data_manager Signed-off-by: wangzhaohao --- .../profiledatamanager/profile_data_manager.h | 76 ++ .../profile_data_manager.cpp | 869 ++++++++++++++++++ 2 files changed, 945 insertions(+) create mode 100644 services/core/include/profiledatamanager/profile_data_manager.h create mode 100644 services/core/src/profiledatamanager/profile_data_manager.cpp diff --git a/services/core/include/profiledatamanager/profile_data_manager.h b/services/core/include/profiledatamanager/profile_data_manager.h new file mode 100644 index 00000000..36f821d0 --- /dev/null +++ b/services/core/include/profiledatamanager/profile_data_manager.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DP_PROFILE_DATA_MANAGER_H +#define OHOS_DP_PROFILE_DATA_MANAGER_H + +#include + +#include "kvstore_observer.h" + +#include "device_profile.h" +#include "device_profile_dao.h" +#include "single_instance.h" +#include "service_profile_dao.h" +#include "characteristic_profile_filter_option.h" + +namespace OHOS { +namespace DistributedDeviceProfile { +class ProfileDataManager { + DECLARE_SINGLE_INSTANCE(ProfileDataManager); + +public: + int32_t PutDeviceProfile(DeviceProfile deviceProfile); + int32_t PutDeviceProfileBatch(std::vector deviceProfiles); + int32_t GetDeviceProfile(const std::string& deviceId, DeviceProfile& deviceProfile); + int32_t GetDeviceProfiles(DeviceProfileFilterOptions& options, + std::vector& deviceProfiles); + int32_t DeleteDeviceProfile(const DeviceProfile& deviceProfile); + int32_t DeleteDeviceProfileBatch(const std::vector& deviceProfiles); + int32_t PutServiceProfile(ServiceProfile& serviceProfile); + int32_t PutServiceProfileBatch(std::vector& serviceProfiles); + int32_t DeleteServiceProfile(const ServiceProfile& serviceProfile); + int32_t GetServiceProfile(const std::string& deviceId, const std::string& serviceId, + ServiceProfile& serviceProfile); + int32_t GetServiceProfiles(ServiceProfileFilterOptions& options,std::vector& serviceProfiles); + int32_t PutCharacteristicProfile(CharacteristicProfile& charProfile); + int32_t DeleteCharacteristicProfile(const CharacteristicProfile& charProfile); + int32_t PutCharacteristicProfileBatch(const std::vector& charProfiles); + int32_t DeleteCharacteristicProfileBatch(const std::vector& charProfiles); + int32_t GetCharacteristicProfile(CharacteristicProfileFilterOption& filterOptions, + CharacteristicProfile& charProfile); + + int32_t OnCloudChange(const std::vector& insertRecords, + const std::vector& updateRecords, const std::vector& delKeys); + int32_t OnPeerChange(const DistributedKv::ChangeNotification& changeNotification); + +private: + bool FilterInvaildSymbol(std::string str); + int32_t DeleteServiceProfileBatch(const std::vector& serviceProfiles); + int32_t DeleteCharProfileBatch(const std::vector& charProfiles); + void SetFilterOptions(ServiceProfileFilterOptions& serFilterOptions, + CharacteristicProfileFilterOption& charaFilterOptions, const CharacteristicProfile& charProfile); + int32_t ProcessInsertAndUpdate(const std::map>& entriesMap); + int32_t ProcessDelete(const std::map>& keysMap); + void GroupEntriesByUdid(const std::map& entries, + std::map>& entriesMap); + void GroupKeysByUdid(const std::vector& keys, + std::map>& keysMap); + void ConvertToEntriesMap(const std::vector& records, + std::map& entriesMap, bool isDelete); +}; +} // DistributedDeviceProfile +} // OHOS +#endif // OHOS_DP_PROFILE_DATA_MANAGER_H diff --git a/services/core/src/profiledatamanager/profile_data_manager.cpp b/services/core/src/profiledatamanager/profile_data_manager.cpp new file mode 100644 index 00000000..cbe0e9c0 --- /dev/null +++ b/services/core/src/profiledatamanager/profile_data_manager.cpp @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "profile_data_manager.h" + +#include "characteristic_profile_filter_option.h" +#include "characteristic_profile_dao.h" +#include "distributed_device_profile_constants.h" +#include "distributed_device_profile_errors.h" +#include "distributed_device_profile_log.h" +#include "multi_user_manager.h" +#include "profile_cache.h" +#include "profile_utils.h" +#include "service_profile_filter_opotions.h" +#include "content_sensor_manager_utils.h" + +namespace OHOS { +namespace DistributedDeviceProfile { +IMPLEMENT_SINGLE_INSTANCE(ProfileDataManager) + +namespace { +const std::string TAG = "ProfileDataManager"; +} +int32_t ProfileDataManager::PutDeviceProfile(DeviceProfile deviceProfile) +{ + if (deviceProfile.GetDeviceId().empty() || ProfileDataManager::FilterInvaildSymbol(deviceProfile.GetDeviceId())) { + HILOGE("deviceId invaild,deviceId=%{public}s", + ProfileUtils::GetAnonyString(deviceProfile.GetDeviceId()).c_str()); + } + if (deviceProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + deviceProfile.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + } else { + deviceProfile.SetUserId(0); + } + deviceProfile.SetAccountId(ProfileCache::GetInstance().GetLocalAccountId()); + DeviceProfileFilterOptions filterOptions; + filterOptions.AddDeviceIds(deviceProfile.GetDeviceId()); + filterOptions.SetUserId(deviceProfile.GetUserId()); + filterOptions.SetAccountId(deviceProfile.GetAccountId()); + std::vector oldDeviceProfiles; + DeviceProfileDao::GetInstance().GetDeviceProfiles(filterOptions, oldDeviceProfiles); + DeviceProfile oldDeviceProfile = oldDeviceProfiles[0]; + deviceProfile.SetId(oldDeviceProfile.GetId()); + int32_t ret = RET_INIT; + if (deviceProfile.GetId() <= 0) { + ret = DeviceProfileDao::GetInstance().PutDeviceProfile(deviceProfile); + } else { + ret = DeviceProfileDao::GetInstance().UpdateDeviceProfile(deviceProfile); + } + if (ret != DP_SUCCESS) { + HILOGE("PutDeviceProfile failed,ret=%{public}d", ret); + return ret; + } + return DP_SUCCESS; +} + +bool ProfileDataManager::FilterInvaildSymbol(std::string str) +{ + if (str.length() == 0 || str.length() > MAX_STRING_LEN) { + return false; + } + size_t found = str.find(SEPARATOR); + if (found == std::string::npos) { + return false; + } + size_t foundSlashes = str.find(SLASHES); + if (foundSlashes == std::string::npos) { + return false; + } + return true; +} + +int32_t ProfileDataManager::PutDeviceProfileBatch(std::vector deviceProfiles) +{ + if (deviceProfiles.empty()) { + HILOGE("deviceProfiles is empty"); + return DP_INVALID_PARAM; + } + // 循环写入deviceProfiles + int32_t ret = RET_INIT; + for (auto deviceProfile : deviceProfiles) { + int32_t putRet = PutDeviceProfile(deviceProfile); + if (ret != DP_SUCCESS) { + ret = putRet; + } + } + if (ret != DP_SUCCESS) { + HILOGE("PutDeviceProfiles failed,ret=%{public}d", ret); + return ret; + } + return DP_SUCCESS; +} + +void ProfileDataManager::SetFilterOptions(ServiceProfileFilterOptions& serFilterOptions, + CharacteristicProfileFilterOption& charaFilterOptions, const CharacteristicProfile& charProfile) +{ + std::string deviceId = charProfile.GetDeviceId(); + std::string characteristicKey = charProfile.GetCharacteristicKey(); + std::string serivceId = charProfile.GetServiceId(); + std::vector deviceIds; + std::vector serivceIds; + deviceIds.push_back(deviceId); + serivceIds.push_back(serivceId); + charaFilterOptions.SetUserId(charProfile.GetUserId()); + charaFilterOptions.SetDeviceId(deviceId); + charaFilterOptions.SetServiceId(serivceId); + charaFilterOptions.SetCharacteristicKey(characteristicKey); + serFilterOptions.SetUserId(charProfile.GetUserId()); + serFilterOptions.SetDeviceId(deviceId); + serFilterOptions.SetServiceIds(serivceIds); +} + +int32_t ProfileDataManager::PutCharacteristicProfile(CharacteristicProfile& charProfile) +{ + if (charProfile.GetDeviceId().empty() || charProfile.GetServiceId().empty() || + charProfile.GetCharacteristicKey().empty() || charProfile.GetCharacteristicValue().empty()) { + return DP_INVALID_PARAMS; + } + if (!FilterInvaildSymbol(charProfile.GetDeviceId()) || !FilterInvaildSymbol(charProfile.GetServiceId()) || + !FilterInvaildSymbol(charProfile.GetCharacteristicKey())) { + return DP_INVALID_PARAMS; + } + std::string localDeviceId = ProfileCache::GetInstance().GetLocalUdid(); + int32_t userId = MultiUserManager::GetInstance().GetCurrentForegroundUserID(); + if (localDeviceId == charProfile.GetDeviceId()) { + if (charProfile.GetUserId() != userId) { + charProfile.SetUserId(0); + } + } + CharacteristicProfileFilterOption charaFilterOptions; + ServiceProfileFilterOptions serFilterOptions; + SetFilterOptions(serFilterOptions, charaFilterOptions, charProfile); + std::vector serviceProfiles; + std::vector charProfiles; + // ServiceProfileDao::GetInstance().GetServiceProfiles(serFilterOptions, serviceProfiles); + CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(charaFilterOptions, charProfiles); + if (charProfiles.empty()) { + if (serviceProfiles.empty()) { + HILOGE("serviceProfiles is empty"); + return -1; + } + ServiceProfile serviceProfile = serviceProfiles[0]; + if (charProfile.GetServiceProfileId() == serviceProfile.GetId()) { + int32_t ret = CharacteristicProfileDao::GetInstance().PutCharacteristicProfile(charProfile); + if (ret != DP_SUCCESS) { + return ret; + } + } + return DP_SUCCESS; + } else { + CharacteristicProfile oldCharProfile = charProfiles[0]; + if ((charProfile.GetId() == oldCharProfile.GetId()) && + (charProfile.GetServiceProfileId() == oldCharProfile.GetServiceProfileId())) { + int32_t result = CharacteristicProfileDao::GetInstance().UpdateCharacteristicProfile(oldCharProfile, + charProfile); + if (result != DP_SUCCESS) { + return -1; + } + } + return DP_SUCCESS; + } +} + +int32_t ProfileDataManager::DeleteCharacteristicProfile(const CharacteristicProfile& charProfile) +{ + bool matchCondition = false; + if (charProfile.GetId() > 0) { + matchCondition = true; + } + std::string localUdid = ContentSensorManagerUtils::GetInstance().ObtainLocalUdid(); + if (!charProfile.GetDeviceId().empty() || !charProfile.GetServiceId().empty() || + !charProfile.GetCharacteristicKey().empty()) { + matchCondition = true; + } + if (matchCondition == false) { + return DP_INVALID_PARAMS; + } + //设置参数 + CharacteristicProfileFilterOption filterOptions; + std::string deviceId = charProfile.GetDeviceId(); + std::string characteristicKey = charProfile.GetCharacteristicKey(); + std::string serivceId = charProfile.GetServiceId(); + filterOptions.SetUserId(charProfile.GetUserId()); + filterOptions.SetDeviceId(deviceId); + filterOptions.SetServiceId(serivceId); + filterOptions.SetCharacteristicKey(characteristicKey); + std::vector charProfiles; + CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(filterOptions, charProfiles); + if (charProfiles.empty()) { + HILOGE("delete filed"); + return -1; + } + for (auto charProfile:charProfiles) { + int32_t result = CharacteristicProfileDao::GetInstance().DeleteCharacteristicProfile(charProfile); + if (result != DP_SUCCESS) { + return -1; + } + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::PutCharacteristicProfileBatch(const std::vector& charProfiles) +{ + if (charProfiles.empty()) { + HILOGE("charProfiles is empty"); + return DP_INVALID_PARAMS; + } + for (auto charProfile:charProfiles) { + int32_t result = PutCharacteristicProfile(charProfile); + if (result != DP_SUCCESS) { + return -1; + } + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::DeleteCharacteristicProfileBatch(const std::vector& charProfiles) +{ + if (charProfiles.empty()) { + HILOGE("charProfiles is empty"); + return DP_INVALID_PARAMS; + } + for (auto charProfile:charProfiles) { + int32_t result = DeleteCharacteristicProfile(charProfile); + if (result != DP_SUCCESS) { + return -1; + } + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::GetCharacteristicProfile(CharacteristicProfileFilterOption& filterOptions, + CharacteristicProfile& charProfile) +{ + if (filterOptions.GetDeviceId().empty() || filterOptions.GetServiceId().empty() || + filterOptions.GetCharacteristicKey().empty()) { + return DP_INVALID_PARAMS; + } + std::string localDeviceId = ProfileCache::GetInstance().GetLocalUdid(); + int32_t userId = MultiUserManager::GetInstance().GetCurrentForegroundUserID(); + if (localDeviceId == charProfile.GetDeviceId()) { + if (charProfile.GetUserId() != userId) { + charProfile.SetUserId(0); + } + } + std::vector charProfiles; + int32_t result = CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(filterOptions, charProfiles); + if (result == DP_SUCCESS) { + HILOGE("GetCharacteristicProfiles filed"); + return DP_GET_KV_DB_FAIL; + } + charProfile = charProfiles[0]; + return DP_SUCCESS; +} + +int32_t ProfileDataManager::GetDeviceProfile(const std::string& deviceId, DeviceProfile& deviceProfile) +{ + if (deviceId.empty() || deviceId.length() > MAX_STRING_LEN) { + HILOGE("deviceId is empty"); + return DP_INVALID_PARAM; + } + if (deviceId == ProfileCache::GetInstance().GetLocalUdid()) { + deviceProfile.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + deviceProfile.SetAccountId(""); + } else { + deviceProfile.SetUserId(0); + deviceProfile.SetAccountId(ProfileCache::GetInstance().GetLocalAccountId()); + } + DeviceProfileFilterOptions filterOptions; + filterOptions.AddDeviceIds(deviceId); + filterOptions.SetUserId(deviceProfile.GetUserId()); + filterOptions.SetAccountId(deviceProfile.GetAccountId()); + std::vector deviceProfiles; + int32_t ret = + DeviceProfileDao::GetInstance().GetDeviceProfiles(filterOptions, deviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("GetDeviceProfile failed,ret=%{public}d", ret); + return ret; + } + deviceProfile = deviceProfiles[0]; + return DP_SUCCESS; +} + +int32_t ProfileDataManager::GetDeviceProfiles(DeviceProfileFilterOptions& options, + std::vector& deviceProfiles) +{ + std::string localAccountId = ProfileCache::GetInstance().GetLocalAccountId(); + std::string localUdid = ProfileCache::GetInstance().GetLocalUdid(); + int32_t localUserId = MultiUserManager::GetInstance().GetCurrentForegroundUserID(); + options.SetAccountId(localAccountId); + int32_t ret = DeviceProfileDao::GetInstance().GetDeviceProfiles(options, deviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("GetDeviceProfile failed,ret=%{public}d", ret); + return ret; + } + for (auto iter = deviceProfiles.begin(); iter != deviceProfiles.end();) { + if (iter->GetDeviceId() == localUdid || iter->GetUserId() == localUserId) { + iter = deviceProfiles.erase(iter); + } else { + iter++; + } + } + if (deviceProfiles.empty()) { + HILOGE("GetDeviceProfile failed,deviceProfiles is empty"); + return DP_DEVICE_PROFILE_NOT_FOUND; + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::DeleteDeviceProfile(const DeviceProfile& deviceProfile) +{ + std::string localAccountId = ProfileCache::GetInstance().GetLocalAccountId(); + std::string localUdid = ProfileCache::GetInstance().GetLocalUdid(); + if (deviceProfile.GetDeviceId().empty() || + deviceProfile.GetDeviceId() == localUdid) { + HILOGE("deviceId is invaild"); + return DP_INVALID_PARAM; + } + DeviceProfileFilterOptions deviceProfileOptions; + deviceProfileOptions.AddDeviceIds(deviceProfile.GetDeviceId()); + deviceProfileOptions.SetUserId(0); + deviceProfileOptions.SetAccountId(localAccountId); + std::vector oldDeviceProfiles; + DeviceProfileDao::GetInstance().GetDeviceProfiles(deviceProfileOptions, oldDeviceProfiles); + if (oldDeviceProfiles.empty()) { + HILOGE("oldDeviceProfiles is empty"); + return DP_DEVICE_PROFILE_NOT_FOUND; + } + if (oldDeviceProfiles[0].GetDeviceId() == localUdid || oldDeviceProfiles[0].GetAccountId() != localAccountId) { + HILOGE("deviceId or accountId is local"); + return DP_DEVICE_PROFILE_NOT_FOUND; + } + ServiceProfileFilterOptions serviceProfileOptions; + serviceProfileOptions.AddDeviceProfileIds(oldDeviceProfiles[0].GetId()); + std::vector serviceProfiles; + ServiceProfileDao::GetInstance().GetServiceProfiles(serviceProfileOptions, serviceProfiles); + + int32_t ret = DeleteServiceProfileBatch(serviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("DeleteServiceProfileBatch failed,ret=%{public}d", ret); + return ret; + } + ret = DeviceProfileDao::GetInstance().DeleteDeviceProfile(oldDeviceProfiles[0]); + if (ret != DP_SUCCESS) { + HILOGE("DeleteDeviceProfile failed,ret=%{public}d", ret); + return ret; + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::DeleteDeviceProfileBatch(const std::vector& deviceProfiles) +{ + int32_t ret = RET_INIT; + for (auto& deviceProfile : deviceProfiles) { + if (deviceProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + HILOGI("deviceProfile.deviceId=localUdid,skip! deviceProfile: %{public}s", + deviceProfile.AnnoymizeDump().c_str()); + continue; + } + int32_t deleteRet = DeleteDeviceProfile(deviceProfile); + if (deleteRet != DP_SUCCESS) { + HILOGE("DeleteDeviceProfile fail, deviceProfile: %{public}s, errcode: %{public}d!", + deviceProfile.AnnoymizeDump().c_str(), deleteRet); + ret = deleteRet; + } + } + return ret; +} + +int32_t ProfileDataManager::PutServiceProfile(ServiceProfile& serviceProfile) +{ + if (serviceProfile.GetDeviceId().empty() || serviceProfile.GetServiceName().empty() || + serviceProfile.GetServiceType().empty() || FilterInvaildSymbol(serviceProfile.GetDeviceId()) || + FilterInvaildSymbol(serviceProfile.GetServiceName())) { + HILOGE("serviceProfile is invaild"); + return DP_INVALID_PARAM; + } + std::string accountId = ""; + if (serviceProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + serviceProfile.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + } else { + serviceProfile.SetUserId(0); + accountId = ProfileCache::GetInstance().GetLocalAccountId(); + } + ServiceProfileFilterOptions serOptions; + serOptions.SetDeviceId(serviceProfile.GetDeviceId()); + serOptions.SetUserId(serviceProfile.GetUserId()); + serOptions.SetAccountId(accountId); + serOptions.AddServiceIds(serviceProfile.GetServiceName()); + std::vector oldServiceProfiles; + ServiceProfileDao::GetInstance().GetServiceProfiles(serOptions, oldServiceProfiles); + if (oldServiceProfiles.empty()) { + DeviceProfile deviceProfile; + DeviceProfileFilterOptions devOptions; + devOptions.AddDeviceIds(serviceProfile.GetDeviceId()); + devOptions.SetUserId(serviceProfile.GetUserId()); + devOptions.SetAccountId(accountId); + std::vector deviceProfiles; + DeviceProfileDao::GetInstance().GetDeviceProfiles(devOptions, deviceProfiles); + if (deviceProfiles.empty()) { + HILOGE("GetDeviceProfiles is empty"); + return DP_DEVICE_PROFILE_NOT_FOUND; + } + deviceProfile = deviceProfiles[0]; + if (deviceProfile.GetDeviceId() != ProfileCache::GetInstance().GetLocalUdid() || + deviceProfile.GetAccountId() != accountId) { + HILOGE("deviceProfile is not local"); + return DP_DEVICE_PROFILE_NOT_FOUND; + } + serviceProfile.SetDeviceProfileId(deviceProfile.GetId()); + int32_t putRet = ServiceProfileDao::GetInstance().PutServiceProfile(serviceProfile); + if (putRet != DP_SUCCESS) { + HILOGE("PutServiceProfile failed,ret=%{public}d", putRet); + return putRet; + } + } else { + serviceProfile.SetId(oldServiceProfiles[0].GetId()); + serviceProfile.SetDeviceProfileId(oldServiceProfiles[0].GetDeviceProfileId()); + int32_t updateRet = ServiceProfileDao::GetInstance().UpdateServiceProfile(serviceProfile); + if (updateRet != DP_SUCCESS) { + HILOGE("UpdateServiceProfile failed,ret=%{public}d", updateRet); + return updateRet; + } + } + if (!serviceProfile.GetCharacteristicProfiles().empty()) { + for (auto& tempCharProfile : serviceProfile.GetCharacteristicProfiles()) { + CharacteristicProfile charProfile = tempCharProfile; + charProfile.SetServiceProfileId(serviceProfile.GetId()); + int32_t putRet = PutCharacteristicProfile(charProfile); + if (putRet != DP_SUCCESS) { + HILOGE("PutCharacteristicProfile failed,ret=%{public}d", putRet); + return putRet; + } + } + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::PutServiceProfileBatch(std::vector& serviceProfiles) +{ + if (serviceProfiles.empty() || serviceProfiles.size() > MAX_SERVICE_SIZE) { + HILOGE("serviceProfiles is empty or size is invaild"); + return DP_INVALID_PARAM; + } + int32_t ret = RET_INIT; + for (auto& serviceProfile : serviceProfiles) { + int32_t putRet = PutServiceProfile(serviceProfile); + if (putRet != DP_SUCCESS) { + ret = putRet; + } + } + if (ret != DP_SUCCESS) { + HILOGE("PutServiceProfileBatch failed,ret=%{public}d", ret); + return ret; + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::DeleteServiceProfile(const ServiceProfile& serviceProfile) +{ + if (serviceProfile.GetId() < 0 && + (serviceProfile.GetDeviceId().empty() || serviceProfile.GetServiceName().empty())) { + HILOGE("serviceProfile is invaild"); + return DP_INVALID_PARAM; + } + ServiceProfileFilterOptions serOptions; + if (serviceProfile.GetId() > 0) { + serOptions.AddServiceProfileIds(serviceProfile.GetId()); + } else { + serOptions.SetDeviceId(serviceProfile.GetDeviceId()); + serOptions.AddServiceIds(serviceProfile.GetServiceName()); + if (serviceProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + serOptions.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + } else { + serOptions.SetAccountId(ProfileCache::GetInstance().GetLocalAccountId()); + } + } + std::vector oldServiceProfiles; + ServiceProfileDao::GetInstance().GetServiceProfiles(serOptions, oldServiceProfiles); + if (oldServiceProfiles.empty()) { + HILOGE("oldServiceProfiles is empty"); + return DP_SERVICE_PROFILE_NOT_FOUND; + } + CharacteristicProfileFilterOption charOption; + charOption.SetServiceProfileId(oldServiceProfiles[0].GetId()); + std::vector charProfiles; + CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(charOption, charProfiles); + // todo: charProfiles和oldServiceProfiles[0]要一并删除 + for (auto& CharProfile : charProfiles) { + CharacteristicProfileDao::GetInstance().DeleteCharacteristicProfile(CharProfile); + } + ServiceProfileDao::GetInstance().DeleteServiceProfile(oldServiceProfiles[0]); + return DP_SUCCESS; +} + +int32_t ProfileDataManager::GetServiceProfile(const std::string& deviceId, const std::string& serviceId, + ServiceProfile& serviceProfile) +{ + if (deviceId.empty() || serviceId.empty()) { + HILOGE("deviceId or serviceId is empty"); + return DP_INVALID_PARAM; + } + ServiceProfileFilterOptions serOptions; + serOptions.SetDeviceId(deviceId); + serOptions.AddServiceIds(serviceId); + if (deviceId == ProfileCache::GetInstance().GetLocalUdid()) { + serOptions.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + } else { + serOptions.SetAccountId(ProfileCache::GetInstance().GetLocalAccountId()); + } + std::vector serviceProfiles; + int32_t ret = ServiceProfileDao::GetInstance().GetServiceProfiles(serOptions, serviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("GetServiceProfiles failed,ret=%{public}d", ret); + return ret; + } + serviceProfile = serviceProfiles[0]; + CharacteristicProfileFilterOption charOption; + std::vector charProfiles; + charOption.SetServiceProfileId(serviceProfile.GetId()); + ret = CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(charOption, charProfiles); + if (ret != DP_SUCCESS) { + HILOGE("GetCharacteristicProfiles failed,ret=%{public}d", ret); + return ret; + } + serviceProfile.SetCharacteristicProfiles(charProfiles); + return DP_SUCCESS; +} + +int32_t ProfileDataManager::GetServiceProfiles(ServiceProfileFilterOptions& options, + std::vector& serviceProfiles) +{ + if (options.GetDeviceId().empty()) { + HILOGE("deviceId is empty"); + return DP_INVALID_PARAM; + } + if (options.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + options.SetUserId(MultiUserManager::GetInstance().GetCurrentForegroundUserID()); + } else { + options.SetAccountId(ProfileCache::GetInstance().GetLocalAccountId()); + } + std::vector serviceProfilesTemp; + int32_t ret = ServiceProfileDao::GetInstance().GetServiceProfiles(options, serviceProfilesTemp); + if (ret != DP_SUCCESS) { + HILOGE("GetServiceProfiles failed,ret=%{public}d", ret); + return ret; + } + for (auto& serviceProfile : serviceProfilesTemp) { + CharacteristicProfileFilterOption charOption; + charOption.SetServiceProfileId(serviceProfile.GetId()); + std::vector charProfiles; + ret = CharacteristicProfileDao::GetInstance().GetCharacteristicProfiles(charOption, charProfiles); + if (ret != DP_SUCCESS) { + HILOGE("GetCharacteristicProfiles failed,ret=%{public}d", ret); + return ret; + } + serviceProfile.SetCharacteristicProfiles(charProfiles); + serviceProfiles.emplace_back(serviceProfile); + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::DeleteServiceProfileBatch(const std::vector& serviceProfiles) +{ + int32_t ret = RET_INIT; + for (auto& serviceProfile : serviceProfiles) { + if (serviceProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + HILOGI("serviceProfile.deviceId=localUdid,skip! serviceProfile: %{public}s", + serviceProfile.dump().c_str()); + continue; + } + int32_t deleteRet = DeleteServiceProfile(serviceProfile); + if (deleteRet != DP_SUCCESS) { + HILOGE("DeleteServiceProfile fail, serviceProfile: %{public}s, errcode: %{public}d!", + serviceProfile.dump().c_str(), deleteRet); + ret = deleteRet; + } + } + return RET_INIT; +} + +int32_t ProfileDataManager::OnCloudChange(const std::vector& insertRecords, + const std::vector& updateRecords, const std::vector& delKeys) +{ + std::map> entriesMap; + std::map> keysMap; + std::map insterEntries; + std::map updateEntries; + std::map entries; + ConvertToEntriesMap(insertRecords, insterEntries, false); + ConvertToEntriesMap(updateRecords, updateEntries, false); + entries.insert(insterEntries.begin(), insterEntries.end()); + entries.insert(updateEntries.begin(), updateEntries.end()); + GroupEntriesByUdid(entries, entriesMap); + GroupKeysByUdid(delKeys, keysMap); + int32_t ret = RET_INIT; + ret = ProcessInsertAndUpdate(entriesMap); + if (ret != DP_SUCCESS) { + HILOGE("ProcessInsertAndUpdate fail, errcode: %{public}d!", ret); + return ret; + } + ret = ProcessDelete(keysMap); + if (ret != DP_SUCCESS) { + HILOGE("ProcessDelete fail, errcode: %{public}d!", ret); + return ret; + } + return DP_SUCCESS; +} + + int32_t ProfileDataManager::OnPeerChange(const DistributedKv::ChangeNotification& changeNotification) + { + std::vector insertRecords = changeNotification.GetInsertEntries(); + std::vector updateRecords = changeNotification.GetUpdateEntries(); + std::vector deleteRecords = changeNotification.GetDeleteEntries(); + std::map insterEntries; + std::map updateEntries; + std::map changeEntries; + std::map deleteEntries; + ConvertToEntriesMap(insertRecords, insterEntries, false); + ConvertToEntriesMap(updateRecords, updateEntries, false); + ConvertToEntriesMap(deleteRecords, deleteEntries, true); + changeEntries.insert(insterEntries.begin(), insterEntries.end()); + changeEntries.insert(updateEntries.begin(), updateEntries.end()); + std::map> changeEntriesMap; + GroupEntriesByUdid(changeEntries, changeEntriesMap); + int32_t ret = ProcessInsertAndUpdate(changeEntriesMap); + if (ret != DP_SUCCESS) { + HILOGE("ProcessInsertAndUpdate failed, ret=%{public}d", ret); + return ret; + } + std::vector deleteKeys; + for (const auto& pair : deleteEntries) { + deleteKeys.emplace_back(pair.first); + } + std::map> deleteKeysMap; + GroupKeysByUdid(deleteKeys, deleteKeysMap); + ret = ProcessDelete(deleteKeysMap); + if (ret != DP_SUCCESS) { + HILOGE("ProcessDelete failed, ret=%{public}d", ret); + return ret; + } + return DP_SUCCESS; + } + +int32_t ProfileDataManager::ProcessInsertAndUpdate( + const std::map>& entriesMap) +{ + std::vector deviceProfiles; + std::vector serviceProfiles; + std::vector< CharacteristicProfile> charProfiles; + for (const auto& [udid, entries] : entriesMap) { + DeviceProfile deviceProfile; + ServiceProfile systemServiceProfile; + std::vector< CharacteristicProfile> systemCharProfiles; + systemServiceProfile.SetDeviceId(udid); + systemServiceProfile.SetServiceName(SYSTEM); + systemServiceProfile.SetServiceType(SYSTEM); + std::map tempDevEntries; + std::map> tempServiceEntries; + std::map> tempCharEntries; + for (const auto& [dbKey, dbValue] : entries) { + if (ProfileUtils::StartsWith(dbKey, DEV_PREFIX)) { + if (ProfileUtils::EndsWith(dbKey, OS_TYPE)) { + systemCharProfiles.emplace_back(udid, SYSTEM, TYPE, dbValue); + continue; + } + if (ProfileUtils::EndsWith(dbKey, OS_VERSION)) { + systemCharProfiles.emplace_back(udid, SYSTEM, EMUI_VERSION, dbValue); + continue; + } + if (ProfileUtils::EndsWith(dbKey, OS_SYS_CAPACITY)) { + systemCharProfiles.emplace_back(udid, SYSTEM, SYSTEM, dbValue); + continue; + } + tempDevEntries.insert({dbKey, dbValue}); + } + if (ProfileUtils::StartsWith(dbKey, SVR_PREFIX)) { + std::string serviceName = ProfileUtils::GetServiceNameByDBKey(dbKey); + tempServiceEntries[serviceName].insert({dbKey, dbValue}); + } + if (ProfileUtils::StartsWith(dbKey, CHAR_PREFIX)) { + std::string charKey = ProfileUtils::GetCharKeyByDBKey(dbKey); + tempCharEntries[charKey].insert({dbKey, dbValue}); + } + } + systemServiceProfile.SetCharacteristicProfiles(systemCharProfiles); + serviceProfiles.emplace_back(systemServiceProfile); + ProfileUtils::EntriesToDeviceProfile(tempDevEntries, deviceProfile); + deviceProfiles.emplace_back(deviceProfile); + for (const auto& [serviceName, serviceEntries] : tempServiceEntries) { + ServiceProfile serviceProfile; + ProfileUtils::EntriesToServiceProfile(serviceEntries, serviceProfile); + serviceProfiles.emplace_back(serviceProfile); + } + for (const auto& [charKey, charEntries] : tempCharEntries) { + CharacteristicProfile charProfile; + ProfileUtils::EntriesToCharProfile(charEntries, charProfile); + charProfiles.emplace_back(charProfile); + } + } + int32_t ret = PutDeviceProfileBatch(deviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("PutDeviceProfileBatch fail, errcode: %{public}d!", ret); + return ret; + } + ret = PutServiceProfileBatch(serviceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("PutServiceProfileBatch fail, errcode: %{public}d!", ret); + return ret; + } + PutCharacteristicProfileBatch(charProfiles); + if (ret != DP_SUCCESS) { + HILOGE("PutCharacteristicProfileBatch fail, errcode: %{public}d!", ret); + return ret; + } + return DP_SUCCESS; +} + +int32_t ProfileDataManager::ProcessDelete(const std::map>& keysMap) +{ + for (const auto& [udid, Keys] : keysMap) { + if (ProfileUtils::StartsWith(udid, DEV_PREFIX)) { + DeviceProfile deviceProfile; + ServiceProfile serviceProfile; + CharacteristicProfile characteristicProfile; + deviceProfile.SetDeviceId(udid); + serviceProfile.SetDeviceId(udid); + characteristicProfile.SetDeviceId(udid); + int32_t ret = RET_INIT; + ret = DeleteDeviceProfile(deviceProfile); + if (ret != DP_SUCCESS) { + HILOGE("DeleteDeviceProfile fail, errcode: %{public}d!", ret); + return ret; + } + ret = DeleteServiceProfile(serviceProfile); + if (ret != DP_SUCCESS) { + HILOGE("DeleteServiceProfile fail, errcode: %{public}d!", ret); + return ret; + } + ret = DeleteCharacteristicProfile(characteristicProfile); + if (ret != DP_SUCCESS) { + HILOGE("DeleteCharacteristicProfile fail, errcode: %{public}d!", ret); + return ret; + } + continue; + } + if (ProfileUtils::StartsWith(udid, SVR_PREFIX)) { + std::set serviceIds; + for (const auto& dbKey : Keys) { + if (dbKey.find(SERVICE_NAME) != std::string::npos) { + continue; + } + std::string serviceId = ProfileUtils::GetServiceNameByDBKey(dbKey); + serviceIds.insert(serviceId); + } + if (serviceIds.empty()) { + continue; + } + std::vector deleteServiceProfiles; + for (const auto& serviceId : serviceIds) { + ServiceProfile tempServiceProfile; + tempServiceProfile.SetDeviceId(udid); + tempServiceProfile.SetServiceName(serviceId); + deleteServiceProfiles.emplace_back(tempServiceProfile); + } + int32_t ret = DeleteServiceProfileBatch(deleteServiceProfiles); + if (ret != DP_SUCCESS) { + HILOGE("DeleteServiceProfileBatch fail, errcode: %{public}d!", ret); + return ret; + } + continue; + } + if (ProfileUtils::StartsWith(udid, CHAR_PREFIX)) { + std::set> serviceIdAndCharKeys; + for (const auto& dbKey : Keys) { + if (dbKey.find(CHARACTERISTIC_KEY) != std::string::npos) { + continue; + } + std::string serviceId = ProfileUtils::GetServiceNameByDBKey(dbKey); + std::string charKey = ProfileUtils::GetCharKeyByDBKey(dbKey); + serviceIdAndCharKeys.insert({serviceId, charKey}); + } + if (serviceIdAndCharKeys.empty()) { + continue; + } + std::vector deletecharProfiles; + for (const auto& [serviceId, charKey] : serviceIdAndCharKeys) { + CharacteristicProfile tempCharProfile; + tempCharProfile.SetDeviceId(udid); + tempCharProfile.SetServiceId(serviceId); + tempCharProfile.SetCharacteristicKey(charKey); + deletecharProfiles.emplace_back(tempCharProfile); + } + int32_t ret = DeleteCharProfileBatch(deletecharProfiles); + if (ret != DP_SUCCESS) { + HILOGE("DeleteCharProfileBatch fail, errcode: %{public}d!", ret); + return ret; + } + } + } + return DP_SUCCESS; +} + +void ProfileDataManager::GroupEntriesByUdid(const std::map& entries, + std::map>& entriesMap) +{ + for (const auto& [dbKey, dbValue] : entries) { + std::string udid = ProfileUtils::GetDeviceIdByDBKey(dbKey); + if (udid == ProfileCache::GetInstance().GetLocalUdid()) { + HILOGI("udid is localUdid, skip!"); + continue; + } + entriesMap[udid].insert({dbKey, dbValue}); + } +} + +void ProfileDataManager::GroupKeysByUdid(const std::vector &keys, + std::map> &keysMap) +{ + for (const auto& key : keys) { + std::string udid = ProfileUtils::GetDeviceIdByDBKey(key); + if (udid == ProfileCache::GetInstance().GetLocalUdid()) { + HILOGI("udid is localUdid, skip!"); + continue; + } + keysMap[udid].emplace_back(key); + } +} + +void ProfileDataManager::ConvertToEntriesMap(const std::vector &records, + std::map &entriesMap, bool isDelete) +{ + // todo ConvertToEntriesMap + return; +} + +int32_t ProfileDataManager::DeleteCharProfileBatch(const std::vector &charProfiles) +{ + int32_t ret = RET_INIT; + for (auto& charProfile : charProfiles) { + if (charProfile.GetDeviceId() == ProfileCache::GetInstance().GetLocalUdid()) { + HILOGI("charProfile.deviceId=localUdid,skip! charProfile: %{public}s", + charProfile.dump().c_str()); + continue; + } + int32_t deleteRet = DeleteCharacteristicProfile(charProfile); + if (deleteRet != DP_SUCCESS) { + HILOGE("DeleteServiceProfile fail, serviceProfile: %{public}s, errcode: %{public}d!", + charProfile.dump().c_str(), deleteRet); + ret = deleteRet; + } + } + return RET_INIT; +} + +} // namespace DistributedDeviceProfile +} // namespace OHOS -- Gitee