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