• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "device_profile_storage_manager.h"
17 
18 #include <chrono>
19 #include <thread>
20 
21 #include "device_profile_errors.h"
22 #include "device_profile_log.h"
23 #include "device_profile_utils.h"
24 #include "dp_device_manager.h"
25 #include "dp_radar_helper.h"
26 #include "hisysevent.h"
27 #include "hitrace_meter.h"
28 #include "sync_coordinator.h"
29 
30 #include "ipc_object_proxy.h"
31 #include "ipc_skeleton.h"
32 #include "iservice_registry.h"
33 #include "subscribe_info.h"
34 #include "subscribe_manager.h"
35 #include "system_ability_definition.h"
36 
37 namespace OHOS {
38 namespace DeviceProfile {
39 using namespace OHOS::HiviewDFX;
40 using namespace std::chrono_literals;
41 using namespace OHOS::DistributedKv;
42 
43 namespace {
44 const std::string TAG = "DeviceProfileStorageManager";
45 
46 const std::string SERVICE_TYPE = "type";
47 const std::string SERVICES = "services";
48 const std::string DP_SYNC_FAILED = "DP_SYNC_FAILED";
49 const std::string DP_SYNC_EVENT = "DP_SYNC_EVENT";
50 const std::string FAULT_CODE_KEY = "FAULT_CODE";
51 const std::string DP_DEVICE_PUT_TRACE = "DP_DEVICE_PUT";
52 const std::string DP_DEVICE_GET_TRACE = "DP_DEVICE_GET";
53 const std::string DP_DEVICE_DELETE_TRACE = "DP_DEVICE_DELETE";
54 const std::string DP_DEVICE_SYNC_TRACE = "DP_DEVICE_SYNC";
55 constexpr int32_t RETRY_TIMES_WAIT_KV_DATA = 600;
56 constexpr int32_t FIX_TASK_ID = 0;
57 constexpr int32_t DELAY_TIME_MS = 100;
58 constexpr int32_t INDENT = -1;
59 const char INDENT_CHAR = ' ';
60 }
61 
62 IMPLEMENT_SINGLE_INSTANCE(DeviceProfileStorageManager);
63 
Init()64 bool DeviceProfileStorageManager::Init()
65 {
66     std::lock_guard<std::mutex> lock(initLock_);
67     if (!inited_) {
68         if (!SyncCoordinator::GetInstance().Init()) {
69             HILOGE("SyncCoordinator init failed");
70             return false;
71         }
72         DpDeviceManager::GetInstance().GetLocalDeviceUdid(localUdid_);
73         if (localUdid_.empty()) {
74             HILOGE("get local udid failed");
75             return false;
76         }
77         onlineSyncTbl_ = std::make_shared<OnlineSyncTable>();
78         kvStoreDeathRecipientDp_ = sptr<IRemoteObject::DeathRecipient>(new KvStoreDeathRecipientDp());
79         auto runner = AppExecFwk::EventRunner::Create("dpstorage");
80         storageHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
81         if (storageHandler_ == nullptr) {
82             return false;
83         }
84         inited_ = true;
85     }
86 
87     bool isKvServiceLoad = WaitKvDataService();
88     if (!isKvServiceLoad) {
89         HILOGE("WaitKvDataService fail!");
90         std::lock_guard<std::mutex> autoLock(serviceLock_);
91         profileItems_.clear();
92         kvDataServiceFailed_ = true;
93         return false;
94     }
95     HILOGI("WaitKvDataService success!");
96     auto callback = std::bind(&DeviceProfileStorageManager::OnKvStoreInitDone, this);
97     onlineSyncTbl_->RegisterKvStoreInitCallback(callback);
98     onlineSyncTbl_->Init();
99 
100     HILOGI("init succeeded");
101     return true;
102 }
103 
WaitKvDataService()104 bool DeviceProfileStorageManager::WaitKvDataService()
105 {
106     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
107     if (samgrProxy == nullptr) {
108         HILOGE("get samgrProxy failed");
109         return false;
110     }
111     int32_t retryTimes = RETRY_TIMES_WAIT_KV_DATA;
112     do {
113         auto kvDataSvr = samgrProxy->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
114         if (kvDataSvr != nullptr) {
115             IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(kvDataSvr.GetRefPtr());
116             if (proxy != nullptr && !proxy->IsObjectDead()) {
117                 HILOGI("get service succeed");
118                 proxy->AddDeathRecipient(kvStoreDeathRecipientDp_);
119                 return true;
120             }
121         }
122         HILOGD("waiting for service...");
123         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_TIME_MS));
124         if (--retryTimes <= 0) {
125             HILOGE("waiting service timeout(60)s");
126             return false;
127         }
128     } while (true);
129     return false;
130 }
131 
GenerateKey(const std::string & udid,const std::string & key,KeyType keyType)132 std::string DeviceProfileStorageManager::GenerateKey(const std::string& udid,
133     const std::string& key, KeyType keyType)
134 {
135     std::string tmp;
136     tmp.append(udid).append("/").append(std::to_string(static_cast<int8_t>(keyType))).append("/").append(key);
137     return tmp;
138 }
139 
PutDeviceProfile(const ServiceCharacteristicProfile & profile)140 int32_t DeviceProfileStorageManager::PutDeviceProfile(const ServiceCharacteristicProfile& profile)
141 {
142     HITRACE_METER_NAME(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_PUT_TRACE);
143     if (onlineSyncTbl_ == nullptr) {
144         HILOGE("onlineSyncTbl is nullptr!");
145         return ERR_DP_INIT_DB_FAILED;
146     }
147     if (kvDataServiceFailed_ || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
148         HILOGE("kvstore init failed");
149         return ERR_DP_INIT_DB_FAILED;
150     }
151 
152     std::vector<std::string> keys;
153     std::vector<std::string> values;
154     std::string serviceId = profile.GetServiceId();
155     keys.emplace_back(GenerateKey(localUdid_, serviceId, KeyType::SERVICE));
156     values.emplace_back(profile.GetCharacteristicProfileJson());
157     std::unique_lock<std::mutex> autoLock(serviceLock_);
158     if (servicesJson_[serviceId] == nullptr) {
159         nlohmann::json j;
160         j[SERVICE_TYPE] = profile.GetServiceType();
161         servicesJson_[serviceId] = j;
162         keys.emplace_back(GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST));
163         values.emplace_back(servicesJson_.dump(INDENT, INDENT_CHAR, false, nlohmann::json::error_handler_t::ignore));
164     }
165 
166     int32_t errCode = ERR_OK;
167     if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
168         autoLock.unlock();
169         if (keys.size() > 1) {
170             errCode = onlineSyncTbl_->PutDeviceProfileBatch(keys, values);
171         } else {
172             errCode = onlineSyncTbl_->PutDeviceProfile(keys[0], values[0]);
173         }
174     } else {
175         for (size_t i = 0; i < keys.size(); i++) {
176             profileItems_[keys[i]] = values[i];
177         }
178     }
179     struct RadarInfo info = {
180         .funcName = "PutDeviceProfile",
181         .stageRes = (errCode == ERR_OK) ?
182             static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL),
183         .toCallPkg = kvNAME,
184         .hostName = DpRadarHelper::GetInstance().GetHostNameByServiceId(serviceId),
185         .localUdid = localUdid_,
186         .errCode = ERR_DP_ADD_DATA_FAILED,
187     };
188     if (!DpRadarHelper::GetInstance().ReportAddData(info)) {
189         HILOGE("ReportAddData failed");
190     }
191     return errCode;
192 }
193 
GetDeviceProfile(const std::string & udid,const std::string & serviceId,ServiceCharacteristicProfile & profile)194 int32_t DeviceProfileStorageManager::GetDeviceProfile(const std::string& udid,
195     const std::string& serviceId, ServiceCharacteristicProfile& profile)
196 {
197     HITRACE_METER_NAME(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_GET_TRACE);
198     if (onlineSyncTbl_ == nullptr) {
199         HILOGE("onlineSyncTbl is nullptr!");
200         return ERR_DP_INIT_DB_FAILED;
201     }
202     if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
203         HILOGE("kvstore init failed");
204         return ERR_DP_INIT_DB_FAILED;
205     }
206 
207     std::string key;
208     std::string value;
209     int32_t result = ERR_OK;
210     if (udid.empty()) {
211         key = GenerateKey(localUdid_, serviceId, KeyType::SERVICE);
212         SetServiceType(udid, serviceId, profile);
213     } else {
214         std::string queryUdid;
215         if (!DpDeviceManager::GetInstance().TransformDeviceId(udid, queryUdid,
216             DeviceIdType::UDID)) {
217             HILOGE("transform to networkid failed");
218             return ERR_DP_INVALID_PARAMS;
219         }
220         key = GenerateKey(queryUdid, serviceId, KeyType::SERVICE);
221         SetServiceType(queryUdid, serviceId, profile);
222     }
223     std::unique_lock<std::mutex> autoLock(serviceLock_);
224     auto itItem = profileItems_.find(key);
225     if (itItem != profileItems_.end()) {
226         value = profileItems_[key];
227     } else {
228         autoLock.unlock();
229         result = onlineSyncTbl_->GetDeviceProfile(udid, key, value);
230     }
231     struct RadarInfo info = {
232         .funcName = "GetDeviceProfile",
233         .stageRes = (result == ERR_OK) ?
234             static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL),
235         .toCallPkg = kvNAME,
236         .hostName = DpRadarHelper::GetInstance().GetHostNameByServiceId(serviceId),
237         .localUdid = localUdid_,
238         .errCode = ERR_DP_GET_DATA_FAILED,
239     };
240     if (!DpRadarHelper::GetInstance().ReportGetData(info)) {
241         HILOGE("ReportGetData failed");
242     }
243     profile.SetServiceId(serviceId);
244     profile.SetCharacteristicProfileJson(value);
245     return result;
246 }
247 
SetServiceType(const std::string & udid,const std::string & serviceId,ServiceCharacteristicProfile & profile)248 void DeviceProfileStorageManager::SetServiceType(const std::string& udid,
249     const std::string& serviceId, ServiceCharacteristicProfile& profile)
250 {
251     std::unique_lock<std::mutex> autoLock(serviceLock_);
252     if (udid.empty()) {
253         auto jsonData = servicesJson_[serviceId];
254         if (jsonData != nullptr) {
255             profile.SetServiceType(jsonData[SERVICE_TYPE]);
256         }
257         return;
258     }
259     if (onlineSyncTbl_ == nullptr) {
260         HILOGE("onlineSyncTbl is nullptr");
261         return;
262     }
263     std::string value;
264     std::string key = GenerateKey(udid, SERVICES, KeyType::SERVICE_LIST);
265     int32_t result = onlineSyncTbl_->GetDeviceProfile(key, value);
266     if (result != ERR_OK) {
267         HILOGE("get service type failed");
268         return;
269     }
270     auto jsonData = nlohmann::json::parse(value, nullptr, false);
271     if (jsonData.is_discarded()) {
272         HILOGE("parse error");
273         return;
274     }
275     auto typeData = jsonData[serviceId];
276     if (typeData != nullptr && typeData[SERVICE_TYPE] != nullptr) {
277         profile.SetServiceType(typeData[SERVICE_TYPE]);
278     }
279 }
280 
DeleteDeviceProfile(const std::string & serviceId)281 int32_t DeviceProfileStorageManager::DeleteDeviceProfile(const std::string& serviceId)
282 {
283     HITRACE_METER_NAME(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_DELETE_TRACE);
284     if (onlineSyncTbl_ == nullptr) {
285         HILOGE("onlineSyncTbl_ is null");
286         return ERR_DP_INVALID_PARAMS;
287     }
288     if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
289         HILOGE("kvstore init failed");
290         return ERR_DP_INIT_DB_FAILED;
291     }
292     std::unique_lock<std::mutex> autoLock(serviceLock_);
293     if (servicesJson_[serviceId] == nullptr) {
294         HILOGW("can't find service %{public}s", serviceId.c_str());
295         return ERR_DP_INVALID_PARAMS;
296     }
297     nlohmann::json original = servicesJson_[serviceId];
298     servicesJson_.erase(serviceId);
299     std::string servicesKey = GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST);
300     std::string servicesValue = servicesJson_.dump();
301     int32_t errCode = ERR_OK;
302     std::string serviceKey = GenerateKey(localUdid_, serviceId, KeyType::SERVICE);
303     struct RadarInfo info = {
304         .funcName = "DeleteDeviceProfile",
305         .toCallPkg = kvNAME,
306         .hostName = DpRadarHelper::GetInstance().GetHostNameByServiceId(serviceId),
307         .localUdid = localUdid_,
308     };
309     if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
310         errCode = onlineSyncTbl_->DeleteDeviceProfile(serviceKey);
311         if (errCode != ERR_OK) {
312             servicesJson_[serviceId] = std::move(original);
313             return errCode;
314         }
315         errCode = onlineSyncTbl_->PutDeviceProfile(servicesKey, servicesValue);
316         info.stageRes = (errCode == ERR_OK) ?
317             static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL);
318         info.errCode = ERR_DP_DELETE_DATA_FAILED;
319         if (errCode != ERR_OK) {
320             HILOGW("update services failed, errorCode = %{public}d", errCode);
321         }
322     } else {
323         info.stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
324         profileItems_.erase(serviceKey);
325         profileItems_[servicesKey] = std::move(servicesValue);
326     }
327     if (!DpRadarHelper::GetInstance().ReportDeleteData(info)) {
328         HILOGE("ReportDeleteData failed");
329     }
330     return errCode;
331 }
332 
RemoveUnBoundDeviceProfile(const std::string & udid)333 int32_t DeviceProfileStorageManager::RemoveUnBoundDeviceProfile(const std::string& udid)
334 {
335     if (onlineSyncTbl_ == nullptr || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
336         HILOGE("kvstore init failed");
337         return ERR_DP_INIT_DB_FAILED;
338     }
339 
340     std::unique_lock<std::mutex> autoLock(serviceLock_);
341     if (onlineSyncTbl_->GetInitStatus() != StorageInitStatus::INIT_SUCCEED) {
342         HILOGE("kvstore not init");
343         return ERR_DP_NOT_INIT_DB;
344     }
345 
346     int32_t errCode = ERR_OK;
347     std::string networkId;
348     if (!DpDeviceManager::GetInstance().TransformDeviceId(udid, networkId, DeviceIdType::NETWORKID)) {
349         HILOGE("udid transform to networkid failed, udid = %{public}s",
350             DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
351         return ERR_DP_GET_NETWORKID_FAILED;
352     }
353 
354     errCode = onlineSyncTbl_->RemoveDeviceData(networkId);
355     return errCode;
356 }
357 
RemoveRemoteDeviceProfile()358 int32_t DeviceProfileStorageManager::RemoveRemoteDeviceProfile()
359 {
360     if (onlineSyncTbl_ == nullptr || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
361         HILOGE("kvstore init failed");
362         return ERR_DP_INIT_DB_FAILED;
363     }
364 
365     if (onlineSyncTbl_->GetInitStatus() != StorageInitStatus::INIT_SUCCEED) {
366         HILOGE("kvstore not init");
367         return ERR_DP_NOT_INIT_DB;
368     }
369     int errCode = onlineSyncTbl_->RemoveDeviceData("");
370     return errCode;
371 }
372 
SyncDeviceProfile(const SyncOptions & syncOptions,const sptr<IRemoteObject> & profileEventNotifier)373 int32_t DeviceProfileStorageManager::SyncDeviceProfile(const SyncOptions& syncOptions,
374     const sptr<IRemoteObject>& profileEventNotifier)
375 {
376     if (onlineSyncTbl_ == nullptr || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
377         HILOGE("kvstore init failed");
378         return ERR_DP_INIT_DB_FAILED;
379     }
380     if (!CheckSyncOption(syncOptions)) {
381         HILOGW("device list has offline device");
382         return ERR_DP_INVALID_PARAMS;
383     }
384     int32_t result = NotifySyncStart(profileEventNotifier);
385     if (result != ERR_OK) {
386         return result;
387     }
388     StartAsyncTrace(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_SYNC_TRACE, FIX_TASK_ID);
389     auto syncTask = [syncOptions, this]() {
390         HILOGI("start sync");
391         ReportBehaviorEvent(DP_SYNC_EVENT);
392         auto devicesList = syncOptions.GetDeviceList();
393         if (devicesList.empty()) {
394             DpDeviceManager::GetInstance().GetDeviceIdList(devicesList);
395         }
396         SyncCoordinator::GetInstance().SetSyncTrigger(false);
397         std::vector<std::string> devicesVector(std::vector<std::string> { devicesList.begin(), devicesList.end() });
398         int32_t result = onlineSyncTbl_->SyncDeviceProfile(devicesVector, syncOptions.GetSyncMode());
399         struct RadarInfo info = {
400             .stageRes = (result == ERR_OK) ?
401                 static_cast<int32_t>(StageRes::STAGE_IDLE) : static_cast<int32_t>(StageRes::STAGE_FAIL),
402             .bizState = (result == ERR_OK) ?
403                 static_cast<int32_t>(BizState::BIZ_STATE_START) : static_cast<int32_t>(BizState::BIZ_STATE_END),
404             .peerUdid = DpRadarHelper::GetInstance().GetStringUdidList(devicesList),
405             .errCode = ERR_DP_SYNC_DATA_FAILED,
406         };
407         if (!DpRadarHelper::GetInstance().ReportSyncData(info)) {
408             HILOGE("ReportSyncData failed");
409         }
410         if (result != ERR_OK) {
411             ReportFaultEvent(DP_SYNC_FAILED, FAULT_CODE_KEY, result);
412             HILOGE("sync failed result : %{public}d", result);
413             NotifySyncCompleted();
414             return;
415         }
416     };
417     if (!SyncCoordinator::GetInstance().DispatchSyncTask(syncTask)) {
418         HILOGE("post sync task failed");
419         NotifySyncCompleted();
420         return ERR_DP_POST_TASK_FAILED;
421     }
422     return ERR_OK;
423 }
424 
NotifySyncStart(const sptr<IRemoteObject> & profileEventNotifier)425 int32_t DeviceProfileStorageManager::NotifySyncStart(const sptr<IRemoteObject>& profileEventNotifier)
426 {
427     {
428         std::lock_guard<std::mutex> autoLock(profileSyncLock_);
429         syncEventNotifier_ = profileEventNotifier;
430     }
431 
432     SubscribeInfo subscribeInfo;
433     subscribeInfo.profileEvent = ProfileEvent::EVENT_SYNC_COMPLETED;
434     std::list<SubscribeInfo> subscribeInfos;
435     subscribeInfos.emplace_back(subscribeInfo);
436     std::list<ProfileEvent> failedEvents;
437     if (SubscribeManager::GetInstance().SubscribeProfileEvents(
438         subscribeInfos, profileEventNotifier, failedEvents) != ERR_OK) {
439         HILOGE("subscribe sync event failed");
440         SyncCoordinator::GetInstance().ReleaseSync();
441         std::lock_guard<std::mutex> autoLock(profileSyncLock_);
442         syncEventNotifier_ = nullptr;
443         return ERR_DP_SUBSCRIBE_FAILED;
444     }
445     return ERR_OK;
446 }
447 
NotifySyncCompleted()448 void DeviceProfileStorageManager::NotifySyncCompleted()
449 {
450     HILOGI("called");
451     SyncCoordinator::GetInstance().ReleaseSync();
452     FinishAsyncTrace(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_SYNC_TRACE, FIX_TASK_ID);
453     std::lock_guard<std::mutex> autoLock(profileSyncLock_);
454     std::list<ProfileEvent> profileEvents;
455     profileEvents.emplace_back(ProfileEvent::EVENT_SYNC_COMPLETED);
456     std::list<ProfileEvent> failedEvents;
457     int32_t ret = SubscribeManager::GetInstance().UnsubscribeProfileEvents(
458         profileEvents, syncEventNotifier_, failedEvents);
459     if (ret != ERR_OK) {
460         HILOGW("unsubscribe sync event failed");
461     }
462     syncEventNotifier_ = nullptr;
463 }
464 
NotifySubscriberDied(const sptr<IRemoteObject> & profileEventNotifier)465 void DeviceProfileStorageManager::NotifySubscriberDied(const sptr<IRemoteObject>& profileEventNotifier)
466 {
467     HILOGI("called");
468     std::lock_guard<std::mutex> autoLock(profileSyncLock_);
469     if (profileEventNotifier != syncEventNotifier_) {
470         return;
471     }
472 
473     SyncCoordinator::GetInstance().ReleaseSync();
474     syncEventNotifier_ = nullptr;
475 }
476 
CheckSyncOption(const SyncOptions & syncOptions)477 bool DeviceProfileStorageManager::CheckSyncOption(const SyncOptions& syncOptions)
478 {
479     std::list<std::shared_ptr<DeviceInfo>> onlineDevices;
480     DpDeviceManager::GetInstance().GetDeviceList(onlineDevices);
481     std::list<std::string> onlineDeviceIds;
482     for (const auto& onlineDevice : onlineDevices) {
483         if (onlineDevice != nullptr) {
484             onlineDeviceIds.emplace_back(onlineDevice->GetNetworkId());
485         }
486     }
487 
488     // check whether deviceId is online
489     auto syncDeviceIds = syncOptions.GetDeviceList();
490     for (const auto& syncDeviceId : syncDeviceIds) {
491         auto iter = find(onlineDeviceIds.begin(), onlineDeviceIds.end(), syncDeviceId);
492         if (iter == onlineDeviceIds.end()) {
493             HILOGE("deviceId: %{public}s is not online", DeviceProfileUtils::AnonymizeDeviceId(syncDeviceId).c_str());
494             return false;
495         }
496     }
497     return true;
498 }
499 
RestoreServiceItemLocked(const std::string & value)500 void DeviceProfileStorageManager::RestoreServiceItemLocked(const std::string& value)
501 {
502     auto restoreItems = nlohmann::json::parse(value, nullptr, false);
503     if (restoreItems.is_discarded()) {
504         HILOGE("parse error");
505         return;
506     }
507     for (const auto& [key, value] : servicesJson_.items()) {
508         restoreItems[key] = value;
509     }
510     servicesJson_ = std::move(restoreItems);
511 }
512 
FlushProfileItems()513 void DeviceProfileStorageManager::FlushProfileItems()
514 {
515     std::string services;
516     std::string servicesKey = GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST);
517     if (onlineSyncTbl_ == nullptr) {
518         HILOGE("onlineSyncTbl is nullptr");
519         return;
520     }
521     int32_t errCode = onlineSyncTbl_->GetDeviceProfile(servicesKey, services);
522     std::unique_lock<std::mutex> autoLock(serviceLock_);
523     if (errCode == ERR_OK) {
524         RestoreServiceItemLocked(services);
525     }
526 
527     std::vector<std::string> keys;
528     std::vector<std::string> values;
529     size_t itemSize = profileItems_.size();
530     HILOGI("profile item size = %{public}zu", itemSize);
531     if (itemSize == 0) {
532         return;
533     }
534     keys.reserve(itemSize);
535     values.reserve(itemSize);
536     // update service list to avoid overwriting the value in db storage
537     profileItems_[servicesKey] = servicesJson_.dump();
538     for (const auto& [key, value] : profileItems_) {
539         keys.emplace_back(key);
540         values.emplace_back(value);
541     }
542     profileItems_.clear();
543     autoLock.unlock();
544 
545     errCode = onlineSyncTbl_->PutDeviceProfileBatch(keys, values);
546     if (errCode != ERR_OK) {
547         HILOGE("put failed, errCode = %{public}d", errCode);
548     }
549 }
550 
RegisterCallbacks()551 void DeviceProfileStorageManager::RegisterCallbacks()
552 {
553     HILOGI("called");
554     int32_t errCode = ERR_OK;
555     if (onlineSyncTbl_ != nullptr && kvStoreObserver_ != nullptr) {
556         errCode = onlineSyncTbl_->SubscribeKvStore(kvStoreObserver_);
557         HILOGI("SubscribeKvStore errCode = %{public}d", errCode);
558     }
559     if (onlineSyncTbl_ != nullptr && kvStoreSyncCallback_ != nullptr) {
560         errCode = onlineSyncTbl_->RegisterSyncCallback(kvStoreSyncCallback_);
561         HILOGI("RegisterSyncCallback errCode = %{public}d", errCode);
562     }
563 }
564 
OnKvStoreInitDone()565 void DeviceProfileStorageManager::OnKvStoreInitDone()
566 {
567     RegisterCallbacks();
568     FlushProfileItems();
569 }
570 
SubscribeKvStore(const std::shared_ptr<KvStoreObserver> & observer)571 int32_t DeviceProfileStorageManager::SubscribeKvStore(const std::shared_ptr<KvStoreObserver>& observer)
572 {
573     std::lock_guard<std::mutex> autoLock(callbackLock_);
574     kvStoreObserver_ = observer;
575     if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
576         return onlineSyncTbl_->SubscribeKvStore(observer);
577     }
578     return ERR_OK;
579 }
580 
UnSubscribeKvStore(const std::shared_ptr<KvStoreObserver> & observer)581 int32_t DeviceProfileStorageManager::UnSubscribeKvStore(const std::shared_ptr<KvStoreObserver>& observer)
582 {
583     std::lock_guard<std::mutex> autoLock(callbackLock_);
584     kvStoreObserver_ = nullptr;
585     if (onlineSyncTbl_ == nullptr) {
586         HILOGE("onlineSyncTbl is nullptr");
587         return ERR_DP_INVALID_PARAMS;
588     }
589     return onlineSyncTbl_->UnSubscribeKvStore(observer);
590 }
591 
RegisterSyncCallback(const std::shared_ptr<KvStoreSyncCallback> & sycnCb)592 int32_t DeviceProfileStorageManager::RegisterSyncCallback(const std::shared_ptr<KvStoreSyncCallback>& sycnCb)
593 {
594     std::lock_guard<std::mutex> autoLock(callbackLock_);
595     kvStoreSyncCallback_ = sycnCb;
596     if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
597         return onlineSyncTbl_->RegisterSyncCallback(sycnCb);
598     }
599     return ERR_OK;
600 }
601 
UnRegisterSyncCallback()602 int32_t DeviceProfileStorageManager::UnRegisterSyncCallback()
603 {
604     std::lock_guard<std::mutex> autoLock(callbackLock_);
605     kvStoreSyncCallback_ = nullptr;
606     if (onlineSyncTbl_ == nullptr) {
607         HILOGE("onlineSyncTbl is nullptr");
608         return ERR_DP_INVALID_PARAMS;
609     }
610     return onlineSyncTbl_->UnRegisterSyncCallback();
611 }
612 
ReportBehaviorEvent(const std::string & event)613 void DeviceProfileStorageManager::ReportBehaviorEvent(const std::string& event)
614 {
615     int ret = HiSysEventWrite(HiSysEvent::Domain::DEVICE_PROFILE, event, HiSysEvent::EventType::BEHAVIOR);
616     if (ret != 0) {
617         HILOGE("hisysevent write failed! ret %{public}d.", ret);
618     }
619 }
620 
ReportFaultEvent(const std::string & event,const std::string & key,const int32_t result)621 void DeviceProfileStorageManager::ReportFaultEvent(const std::string& event,
622     const std::string& key, const int32_t result)
623 {
624     int ret = HiSysEventWrite(HiSysEvent::Domain::DEVICE_PROFILE, event, HiSysEvent::EventType::FAULT, key, result);
625     if (ret != 0) {
626         HILOGE("hisysevent write failed! ret %{public}d.", ret);
627     }
628 }
629 
DumpLocalProfile(std::string & result)630 void DeviceProfileStorageManager::DumpLocalProfile(std::string& result)
631 {
632     for (const auto& [key, value] : servicesJson_.items()) {
633         result.append("key:");
634         result.append(key);
635         result.append(" value:");
636         result.append(value.dump());
637         result.append("\n");
638     }
639 }
640 } // namespace DeviceProfile
641 } // namespace OHOS
642