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
260 std::string value;
261 std::string key = GenerateKey(udid, SERVICES, KeyType::SERVICE_LIST);
262 int32_t result = onlineSyncTbl_->GetDeviceProfile(key, value);
263 if (result != ERR_OK) {
264 HILOGE("get service type failed");
265 return;
266 }
267 auto jsonData = nlohmann::json::parse(value, nullptr, false);
268 if (jsonData.is_discarded()) {
269 HILOGE("parse error");
270 return;
271 }
272 auto typeData = jsonData[serviceId];
273 if (typeData != nullptr && typeData[SERVICE_TYPE] != nullptr) {
274 profile.SetServiceType(typeData[SERVICE_TYPE]);
275 }
276 }
277
DeleteDeviceProfile(const std::string & serviceId)278 int32_t DeviceProfileStorageManager::DeleteDeviceProfile(const std::string& serviceId)
279 {
280 HITRACE_METER_NAME(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_DELETE_TRACE);
281 if (onlineSyncTbl_ == nullptr) {
282 HILOGE("onlineSyncTbl_ is null");
283 return ERR_DP_INVALID_PARAMS;
284 }
285 if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
286 HILOGE("kvstore init failed");
287 return ERR_DP_INIT_DB_FAILED;
288 }
289 std::unique_lock<std::mutex> autoLock(serviceLock_);
290 if (servicesJson_[serviceId] == nullptr) {
291 HILOGW("can't find service %{public}s", serviceId.c_str());
292 return ERR_DP_INVALID_PARAMS;
293 }
294 nlohmann::json original = servicesJson_[serviceId];
295 servicesJson_.erase(serviceId);
296 std::string servicesKey = GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST);
297 std::string servicesValue = servicesJson_.dump();
298 int32_t errCode = ERR_OK;
299 std::string serviceKey = GenerateKey(localUdid_, serviceId, KeyType::SERVICE);
300 struct RadarInfo info = {
301 .funcName = "DeleteDeviceProfile",
302 .toCallPkg = kvNAME,
303 .hostName = DpRadarHelper::GetInstance().GetHostNameByServiceId(serviceId),
304 .localUdid = localUdid_,
305 };
306 if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
307 errCode = onlineSyncTbl_->DeleteDeviceProfile(serviceKey);
308 if (errCode != ERR_OK) {
309 servicesJson_[serviceId] = std::move(original);
310 return errCode;
311 }
312 errCode = onlineSyncTbl_->PutDeviceProfile(servicesKey, servicesValue);
313 info.stageRes = (errCode == ERR_OK) ?
314 static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL);
315 info.errCode = ERR_DP_DELETE_DATA_FAILED;
316 if (errCode != ERR_OK) {
317 HILOGW("update services failed, errorCode = %{public}d", errCode);
318 }
319 } else {
320 info.stageRes = static_cast<int32_t>(StageRes::STAGE_SUCC);
321 profileItems_.erase(serviceKey);
322 profileItems_[servicesKey] = std::move(servicesValue);
323 }
324 if (!DpRadarHelper::GetInstance().ReportDeleteData(info)) {
325 HILOGE("ReportDeleteData failed");
326 }
327 return errCode;
328 }
329
RemoveUnBoundDeviceProfile(const std::string & udid)330 int32_t DeviceProfileStorageManager::RemoveUnBoundDeviceProfile(const std::string& udid)
331 {
332 if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
333 HILOGE("kvstore init failed");
334 return ERR_DP_INIT_DB_FAILED;
335 }
336
337 std::unique_lock<std::mutex> autoLock(serviceLock_);
338 if (onlineSyncTbl_->GetInitStatus() != StorageInitStatus::INIT_SUCCEED) {
339 HILOGE("kvstore not init");
340 return ERR_DP_NOT_INIT_DB;
341 }
342
343 int32_t errCode = ERR_OK;
344 std::string networkId;
345 if (!DpDeviceManager::GetInstance().TransformDeviceId(udid, networkId, DeviceIdType::NETWORKID)) {
346 HILOGE("udid transform to networkid failed, udid = %{public}s",
347 DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
348 return ERR_DP_GET_NETWORKID_FAILED;
349 }
350
351 errCode = onlineSyncTbl_->RemoveDeviceData(networkId);
352 return errCode;
353 }
354
RemoveRemoteDeviceProfile()355 int32_t DeviceProfileStorageManager::RemoveRemoteDeviceProfile()
356 {
357 if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
358 HILOGE("kvstore init failed");
359 return ERR_DP_INIT_DB_FAILED;
360 }
361
362 if (onlineSyncTbl_->GetInitStatus() != StorageInitStatus::INIT_SUCCEED) {
363 HILOGE("kvstore not init");
364 return ERR_DP_NOT_INIT_DB;
365 }
366 int errCode = onlineSyncTbl_->RemoveDeviceData("");
367 return errCode;
368 }
369
SyncDeviceProfile(const SyncOptions & syncOptions,const sptr<IRemoteObject> & profileEventNotifier)370 int32_t DeviceProfileStorageManager::SyncDeviceProfile(const SyncOptions& syncOptions,
371 const sptr<IRemoteObject>& profileEventNotifier)
372 {
373 if (onlineSyncTbl_ == nullptr || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) {
374 HILOGE("kvstore init failed");
375 return ERR_DP_INIT_DB_FAILED;
376 }
377 if (!CheckSyncOption(syncOptions)) {
378 HILOGW("device list has offline device");
379 return ERR_DP_INVALID_PARAMS;
380 }
381 int32_t result = NotifySyncStart(profileEventNotifier);
382 if (result != ERR_OK) {
383 return result;
384 }
385 StartAsyncTrace(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_SYNC_TRACE, FIX_TASK_ID);
386 auto syncTask = [syncOptions, this]() {
387 HILOGI("start sync");
388 ReportBehaviorEvent(DP_SYNC_EVENT);
389 auto devicesList = syncOptions.GetDeviceList();
390 if (devicesList.empty()) {
391 DpDeviceManager::GetInstance().GetDeviceIdList(devicesList);
392 }
393 SyncCoordinator::GetInstance().SetSyncTrigger(false);
394 std::vector<std::string> devicesVector(std::vector<std::string> { devicesList.begin(), devicesList.end() });
395 int32_t result = onlineSyncTbl_->SyncDeviceProfile(devicesVector, syncOptions.GetSyncMode());
396 struct RadarInfo info = {
397 .stageRes = (result == ERR_OK) ?
398 static_cast<int32_t>(StageRes::STAGE_IDLE) : static_cast<int32_t>(StageRes::STAGE_FAIL),
399 .bizState = (result == ERR_OK) ?
400 static_cast<int32_t>(BizState::BIZ_STATE_START) : static_cast<int32_t>(BizState::BIZ_STATE_END),
401 .peerUdid = DpRadarHelper::GetInstance().GetStringUdidList(devicesList),
402 .errCode = ERR_DP_SYNC_DATA_FAILED,
403 };
404 if (!DpRadarHelper::GetInstance().ReportSyncData(info)) {
405 HILOGE("ReportSyncData failed");
406 }
407 if (result != ERR_OK) {
408 ReportFaultEvent(DP_SYNC_FAILED, FAULT_CODE_KEY, result);
409 HILOGE("sync failed result : %{public}d", result);
410 NotifySyncCompleted();
411 return;
412 }
413 };
414 if (!SyncCoordinator::GetInstance().DispatchSyncTask(syncTask)) {
415 HILOGE("post sync task failed");
416 NotifySyncCompleted();
417 return ERR_DP_POST_TASK_FAILED;
418 }
419 return ERR_OK;
420 }
421
NotifySyncStart(const sptr<IRemoteObject> & profileEventNotifier)422 int32_t DeviceProfileStorageManager::NotifySyncStart(const sptr<IRemoteObject>& profileEventNotifier)
423 {
424 {
425 std::lock_guard<std::mutex> autoLock(profileSyncLock_);
426 syncEventNotifier_ = profileEventNotifier;
427 }
428
429 SubscribeInfo subscribeInfo;
430 subscribeInfo.profileEvent = ProfileEvent::EVENT_SYNC_COMPLETED;
431 std::list<SubscribeInfo> subscribeInfos;
432 subscribeInfos.emplace_back(subscribeInfo);
433 std::list<ProfileEvent> failedEvents;
434 if (SubscribeManager::GetInstance().SubscribeProfileEvents(
435 subscribeInfos, profileEventNotifier, failedEvents) != ERR_OK) {
436 HILOGE("subscribe sync event failed");
437 SyncCoordinator::GetInstance().ReleaseSync();
438 std::lock_guard<std::mutex> autoLock(profileSyncLock_);
439 syncEventNotifier_ = nullptr;
440 return ERR_DP_SUBSCRIBE_FAILED;
441 }
442 return ERR_OK;
443 }
444
NotifySyncCompleted()445 void DeviceProfileStorageManager::NotifySyncCompleted()
446 {
447 HILOGI("called");
448 SyncCoordinator::GetInstance().ReleaseSync();
449 FinishAsyncTrace(HITRACE_TAG_DEVICE_PROFILE, DP_DEVICE_SYNC_TRACE, FIX_TASK_ID);
450 std::lock_guard<std::mutex> autoLock(profileSyncLock_);
451 std::list<ProfileEvent> profileEvents;
452 profileEvents.emplace_back(ProfileEvent::EVENT_SYNC_COMPLETED);
453 std::list<ProfileEvent> failedEvents;
454 int32_t ret = SubscribeManager::GetInstance().UnsubscribeProfileEvents(
455 profileEvents, syncEventNotifier_, failedEvents);
456 if (ret != ERR_OK) {
457 HILOGW("unsubscribe sync event failed");
458 }
459 syncEventNotifier_ = nullptr;
460 }
461
NotifySubscriberDied(const sptr<IRemoteObject> & profileEventNotifier)462 void DeviceProfileStorageManager::NotifySubscriberDied(const sptr<IRemoteObject>& profileEventNotifier)
463 {
464 HILOGI("called");
465 std::lock_guard<std::mutex> autoLock(profileSyncLock_);
466 if (profileEventNotifier != syncEventNotifier_) {
467 return;
468 }
469
470 SyncCoordinator::GetInstance().ReleaseSync();
471 syncEventNotifier_ = nullptr;
472 }
473
CheckSyncOption(const SyncOptions & syncOptions)474 bool DeviceProfileStorageManager::CheckSyncOption(const SyncOptions& syncOptions)
475 {
476 std::list<std::shared_ptr<DeviceInfo>> onlineDevices;
477 DpDeviceManager::GetInstance().GetDeviceList(onlineDevices);
478 std::list<std::string> onlineDeviceIds;
479 for (const auto& onlineDevice : onlineDevices) {
480 onlineDeviceIds.emplace_back(onlineDevice->GetNetworkId());
481 }
482
483 // check whether deviceId is online
484 auto syncDeviceIds = syncOptions.GetDeviceList();
485 for (const auto& syncDeviceId : syncDeviceIds) {
486 auto iter = find(onlineDeviceIds.begin(), onlineDeviceIds.end(), syncDeviceId);
487 if (iter == onlineDeviceIds.end()) {
488 HILOGE("deviceId: %{public}s is not online", DeviceProfileUtils::AnonymizeDeviceId(syncDeviceId).c_str());
489 return false;
490 }
491 }
492 return true;
493 }
494
RestoreServiceItemLocked(const std::string & value)495 void DeviceProfileStorageManager::RestoreServiceItemLocked(const std::string& value)
496 {
497 auto restoreItems = nlohmann::json::parse(value, nullptr, false);
498 if (restoreItems.is_discarded()) {
499 HILOGE("parse error");
500 return;
501 }
502 for (const auto& [key, value] : servicesJson_.items()) {
503 restoreItems[key] = value;
504 }
505 servicesJson_ = std::move(restoreItems);
506 }
507
FlushProfileItems()508 void DeviceProfileStorageManager::FlushProfileItems()
509 {
510 std::string services;
511 std::string servicesKey = GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST);
512 int32_t errCode = onlineSyncTbl_->GetDeviceProfile(servicesKey, services);
513 std::unique_lock<std::mutex> autoLock(serviceLock_);
514 if (errCode == ERR_OK) {
515 RestoreServiceItemLocked(services);
516 }
517
518 std::vector<std::string> keys;
519 std::vector<std::string> values;
520 size_t itemSize = profileItems_.size();
521 HILOGI("profile item size = %{public}zu", itemSize);
522 if (itemSize == 0) {
523 return;
524 }
525 keys.reserve(itemSize);
526 values.reserve(itemSize);
527 // update service list to avoid overwriting the value in db storage
528 profileItems_[servicesKey] = servicesJson_.dump();
529 for (const auto& [key, value] : profileItems_) {
530 keys.emplace_back(key);
531 values.emplace_back(value);
532 }
533 profileItems_.clear();
534 autoLock.unlock();
535
536 errCode = onlineSyncTbl_->PutDeviceProfileBatch(keys, values);
537 if (errCode != ERR_OK) {
538 HILOGE("put failed, errCode = %{public}d", errCode);
539 }
540 }
541
RegisterCallbacks()542 void DeviceProfileStorageManager::RegisterCallbacks()
543 {
544 HILOGI("called");
545 int32_t errCode = ERR_OK;
546 if (kvStoreObserver_ != nullptr) {
547 errCode = onlineSyncTbl_->SubscribeKvStore(kvStoreObserver_);
548 HILOGI("SubscribeKvStore errCode = %{public}d", errCode);
549 }
550 if (kvStoreSyncCallback_ != nullptr) {
551 errCode = onlineSyncTbl_->RegisterSyncCallback(kvStoreSyncCallback_);
552 HILOGI("RegisterSyncCallback errCode = %{public}d", errCode);
553 }
554 }
555
OnKvStoreInitDone()556 void DeviceProfileStorageManager::OnKvStoreInitDone()
557 {
558 RegisterCallbacks();
559 FlushProfileItems();
560 }
561
SubscribeKvStore(const std::shared_ptr<KvStoreObserver> & observer)562 int32_t DeviceProfileStorageManager::SubscribeKvStore(const std::shared_ptr<KvStoreObserver>& observer)
563 {
564 std::lock_guard<std::mutex> autoLock(callbackLock_);
565 kvStoreObserver_ = observer;
566 if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
567 return onlineSyncTbl_->SubscribeKvStore(observer);
568 }
569 return ERR_OK;
570 }
571
UnSubscribeKvStore(const std::shared_ptr<KvStoreObserver> & observer)572 int32_t DeviceProfileStorageManager::UnSubscribeKvStore(const std::shared_ptr<KvStoreObserver>& observer)
573 {
574 std::lock_guard<std::mutex> autoLock(callbackLock_);
575 kvStoreObserver_ = nullptr;
576 return onlineSyncTbl_->UnSubscribeKvStore(observer);
577 }
578
RegisterSyncCallback(const std::shared_ptr<KvStoreSyncCallback> & sycnCb)579 int32_t DeviceProfileStorageManager::RegisterSyncCallback(const std::shared_ptr<KvStoreSyncCallback>& sycnCb)
580 {
581 std::lock_guard<std::mutex> autoLock(callbackLock_);
582 kvStoreSyncCallback_ = sycnCb;
583 if (onlineSyncTbl_ != nullptr && onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) {
584 return onlineSyncTbl_->RegisterSyncCallback(sycnCb);
585 }
586 return ERR_OK;
587 }
588
UnRegisterSyncCallback()589 int32_t DeviceProfileStorageManager::UnRegisterSyncCallback()
590 {
591 std::lock_guard<std::mutex> autoLock(callbackLock_);
592 kvStoreSyncCallback_ = nullptr;
593 return onlineSyncTbl_->UnRegisterSyncCallback();
594 }
595
ReportBehaviorEvent(const std::string & event)596 void DeviceProfileStorageManager::ReportBehaviorEvent(const std::string& event)
597 {
598 int ret = HiSysEventWrite(HiSysEvent::Domain::DEVICE_PROFILE, event, HiSysEvent::EventType::BEHAVIOR);
599 if (ret != 0) {
600 HILOGE("hisysevent write failed! ret %{public}d.", ret);
601 }
602 }
603
ReportFaultEvent(const std::string & event,const std::string & key,const int32_t result)604 void DeviceProfileStorageManager::ReportFaultEvent(const std::string& event,
605 const std::string& key, const int32_t result)
606 {
607 int ret = HiSysEventWrite(HiSysEvent::Domain::DEVICE_PROFILE, event, HiSysEvent::EventType::FAULT, key, result);
608 if (ret != 0) {
609 HILOGE("hisysevent write failed! ret %{public}d.", ret);
610 }
611 }
612
DumpLocalProfile(std::string & result)613 void DeviceProfileStorageManager::DumpLocalProfile(std::string& result)
614 {
615 for (const auto& [key, value] : servicesJson_.items()) {
616 result.append("key:");
617 result.append(key);
618 result.append(" value:");
619 result.append(value.dump());
620 result.append("\n");
621 }
622 }
623 } // namespace DeviceProfile
624 } // namespace OHOS
625