1 /*
2  * Copyright (c) 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_manager.h"
17 
18 #include <algorithm>
19 #include <dlfcn.h>
20 #include <list>
21 #include <thread>
22 
23 #include "datetime_ex.h"
24 #include "dm_constants.h"
25 
26 #include "content_sensor_manager_utils.h"
27 #include "distributed_device_profile_errors.h"
28 #include "distributed_device_profile_log.h"
29 #include "event_handler_factory.h"
30 #include "i_sync_completed_callback.h"
31 #include "kv_adapter.h"
32 #include "permission_manager.h"
33 #include "profile_cache.h"
34 #include "profile_control_utils.h"
35 #include "profile_utils.h"
36 #include "static_profile_manager.h"
37 
38 namespace OHOS {
39 namespace DistributedDeviceProfile {
40 constexpr const char *LIB_DP_ADAPTER_NAME = "libdeviceprofileadapter.z.so";
41 IMPLEMENT_SINGLE_INSTANCE(DeviceProfileManager);
42 namespace {
43     const std::string APP_ID = "distributed_device_profile_service";
44     const std::string STORE_ID = "dp_kv_store";
45     const std::string TAG = "DeviceProfileManager";
46     const std::unordered_set<std::string> NON_OHBASE_NEED_CLEAR_SVR_NAMES {
47         "collaborationFwk", "Nfc_Publish_Br_Mac_Address" };
48 }
49 
Init()50 int32_t DeviceProfileManager::Init()
51 {
52     HILOGI("call!");
53     int32_t initResult = DP_MANAGER_INIT_FAIL;
54     {
55         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
56         deviceProfileStore_ = std::make_shared<KVAdapter>(APP_ID, STORE_ID,
57             std::make_shared<KvDataChangeListener>(STORE_ID),
58             std::make_shared<KvSyncCompletedListener>(STORE_ID), std::make_shared<KvDeathRecipient>(STORE_ID),
59             DistributedKv::TYPE_DYNAMICAL);
60         initResult = deviceProfileStore_->Init();
61         if (initResult != DP_SUCCESS) {
62             HILOGE("deviceProfileStore init failed");
63             return initResult;
64         }
65         std::string localDeviceId = ContentSensorManagerUtils::GetInstance().ObtainLocalUdid();
66         std::string dbKeyPrefix = ProfileUtils::GenerateDeviceProfileKey(localDeviceId);
67         std::map<std::string, std::string> values;
68         int32_t status = deviceProfileStore_->GetByPrefix(dbKeyPrefix, values);
69         if (status == DP_SUCCESS) {
70             isFirst_.store(values.empty());
71         }
72     }
73     LoadDpSyncAdapter();
74     HILOGI("Init finish, res: %{public}d", initResult);
75     return initResult;
76 }
77 
UnInit()78 int32_t DeviceProfileManager::UnInit()
79 {
80     HILOGI("call!");
81     {
82         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
83         if (deviceProfileStore_ == nullptr) {
84             HILOGE("deviceProfileStore_ is nullptr");
85             return DP_KV_DB_PTR_NULL;
86         }
87         deviceProfileStore_->UnInit();
88         deviceProfileStore_ = nullptr;
89     }
90     {
91         std::lock_guard<std::mutex> lock(putTempCacheMutex_);
92         putTempCache_.clear();
93     }
94     UnloadDpSyncAdapter();
95     return DP_SUCCESS;
96 }
97 
ReInit()98 int32_t DeviceProfileManager::ReInit()
99 {
100     HILOGI("call!");
101     UnInit();
102     return Init();
103 }
104 
PutDeviceProfile(const DeviceProfile & deviceProfile)105 int32_t DeviceProfileManager::PutDeviceProfile(const DeviceProfile& deviceProfile)
106 {
107     HILOGI("deviceProfile: %{public}s", deviceProfile.AnnoymizeDump().c_str());
108     if (!ProfileUtils::IsDevProfileValid(deviceProfile)) {
109         HILOGE("the profile is invalid! deviceProfile: %{public}s", deviceProfile.AnnoymizeDump().c_str());
110         return DP_INVALID_PARAMS;
111     }
112     std::map<std::string, std::string> entries;
113     ProfileUtils::DeviceProfileToEntries(deviceProfile, entries);
114     if (isFirst_.load()) {
115         AddToPutTempCache(entries);
116         return DP_SUCCESS;
117     }
118     {
119         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
120         if (deviceProfileStore_ == nullptr) {
121             HILOGE("deviceProfileStore is nullptr!");
122             return DP_KV_DB_PTR_NULL;
123         }
124         if (deviceProfileStore_->PutBatch(entries) != DP_SUCCESS) {
125             HILOGE("PutDeviceProfile fail! deviceProfile: %{public}s", deviceProfile.AnnoymizeDump().c_str());
126             return DP_PUT_KV_DB_FAIL;
127         }
128     }
129     HILOGD("PutDeviceProfile success");
130     return DP_SUCCESS;
131 }
132 
PutServiceProfile(const ServiceProfile & serviceProfile)133 int32_t DeviceProfileManager::PutServiceProfile(const ServiceProfile& serviceProfile)
134 {
135     HILOGI("serviceProfile: %{public}s", serviceProfile.dump().c_str());
136     if (!ProfileUtils::IsSvrProfileValid(serviceProfile)) {
137         HILOGE("the profile is invalid!");
138         return DP_INVALID_PARAMS;
139     }
140     std::map<std::string, std::string> entries;
141     ProfileUtils::ServiceProfileToEntries(serviceProfile, entries);
142     if (isFirst_.load()) {
143         AddToPutTempCache(entries);
144         return DP_SUCCESS;
145     }
146     {
147         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
148         if (deviceProfileStore_ == nullptr) {
149             HILOGE("deviceProfileStore is nullptr!");
150             return DP_KV_DB_PTR_NULL;
151         }
152         if (deviceProfileStore_->PutBatch(entries) != DP_SUCCESS) {
153             HILOGE("PutServiceProfile fail! serviceProfile: %{public}s", serviceProfile.dump().c_str());
154             return DP_PUT_KV_DB_FAIL;
155         }
156     }
157     HILOGD("PutServiceProfile success");
158     return DP_SUCCESS;
159 }
160 
PutServiceProfileBatch(const std::vector<ServiceProfile> & serviceProfiles)161 int32_t DeviceProfileManager::PutServiceProfileBatch(const std::vector<ServiceProfile>& serviceProfiles)
162 {
163     HILOGD("call!");
164     std::map<std::string, std::string> entries;
165     for (const auto& serviceProfile : serviceProfiles) {
166         if (!ProfileUtils::IsSvrProfileValid(serviceProfile)) {
167             HILOGE("the profile is invalid! serviceProfile:%{public}s", serviceProfile.dump().c_str());
168             continue;
169         }
170         ProfileUtils::ServiceProfileToEntries(serviceProfile, entries);
171     }
172     if (isFirst_.load()) {
173         AddToPutTempCache(entries);
174         return DP_SUCCESS;
175     }
176     {
177         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
178         if (deviceProfileStore_ == nullptr) {
179             HILOGE("deviceProfileStore is nullptr!");
180             return DP_KV_DB_PTR_NULL;
181         }
182         if (deviceProfileStore_->PutBatch(entries) != DP_SUCCESS) {
183             HILOGE("PutServiceProfileBatch fail!");
184             return DP_PUT_KV_DB_FAIL;
185         }
186     }
187     HILOGD("PutServiceProfileBatch success");
188     return DP_SUCCESS;
189 }
190 
PutCharacteristicProfile(const CharacteristicProfile & charProfile)191 int32_t DeviceProfileManager::PutCharacteristicProfile(const CharacteristicProfile& charProfile)
192 {
193     HILOGI("charProfile: %{public}s", charProfile.dump().c_str());
194     if (!ProfileUtils::IsCharProfileValid(charProfile)) {
195         HILOGE("the profile is invalid!");
196         return DP_INVALID_PARAMS;
197     }
198     std::map<std::string, std::string> entries;
199     ProfileUtils::CharacteristicProfileToEntries(charProfile, entries);
200     if (isFirst_.load()) {
201         AddToPutTempCache(entries);
202         return DP_SUCCESS;
203     }
204     {
205         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
206         if (deviceProfileStore_ == nullptr) {
207             HILOGE("deviceProfileStore is nullptr!");
208             return DP_KV_DB_PTR_NULL;
209         }
210         if (deviceProfileStore_->PutBatch(entries) != DP_SUCCESS) {
211             HILOGE("PutCharacteristicProfile fail! charProfile: %{public}s", charProfile.dump().c_str());
212             return DP_PUT_KV_DB_FAIL;
213         }
214     }
215     HILOGD("PutCharacteristicProfile success");
216     return DP_SUCCESS;
217 }
218 
PutCharacteristicProfileBatch(const std::vector<CharacteristicProfile> & charProfiles)219 int32_t DeviceProfileManager::PutCharacteristicProfileBatch(const std::vector<CharacteristicProfile>& charProfiles)
220 {
221     HILOGD("call!");
222     std::map<std::string, std::string> entries;
223     for (const auto& charProfile : charProfiles) {
224         if (!ProfileUtils::IsCharProfileValid(charProfile)) {
225             HILOGE("the profile is invalid! charProfile:%{public}s", charProfile.dump().c_str());
226             continue;
227         }
228         ProfileUtils::CharacteristicProfileToEntries(charProfile, entries);
229     }
230     if (isFirst_.load()) {
231         AddToPutTempCache(entries);
232         return DP_SUCCESS;
233     }
234     {
235         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
236         if (deviceProfileStore_ == nullptr) {
237             HILOGE("deviceProfileStore is nullptr!");
238             return DP_KV_DB_PTR_NULL;
239         }
240         if (deviceProfileStore_->PutBatch(entries) != DP_SUCCESS) {
241             HILOGE("PutCharacteristicProfileBatch fail!");
242             return DP_PUT_KV_DB_FAIL;
243         }
244     }
245     HILOGD("PutCharacteristicProfileBatch success");
246     return DP_SUCCESS;
247 }
248 
GetDeviceProfile(const std::string & deviceId,DeviceProfile & deviceProfile)249 int32_t DeviceProfileManager::GetDeviceProfile(const std::string& deviceId, DeviceProfile& deviceProfile)
250 {
251     HILOGD("call!");
252     int32_t res = 0;
253     {
254         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
255         res = ProfileControlUtils::GetDeviceProfile(deviceProfileStore_, deviceId, deviceProfile);
256     }
257     if (res != DP_SUCCESS) {
258         HILOGE("GetDeviceProfile fail, reason: %{public}d!", res);
259         return res;
260     }
261     HILOGD("GetDeviceProfile success");
262     return DP_SUCCESS;
263 }
264 
GetServiceProfile(const std::string & deviceId,const std::string & serviceName,ServiceProfile & serviceProfile)265 int32_t DeviceProfileManager::GetServiceProfile(const std::string& deviceId, const std::string& serviceName,
266     ServiceProfile& serviceProfile)
267 {
268     HILOGD("call!");
269     int32_t res = 0;
270     {
271         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
272         res = ProfileControlUtils::GetServiceProfile(deviceProfileStore_, deviceId, serviceName,
273             serviceProfile);
274     }
275     if (res != DP_SUCCESS) {
276         HILOGE("GetServiceProfile fail, reason: %{public}d!", res);
277         return res;
278     }
279     HILOGD("GetServiceProfile success");
280     return DP_SUCCESS;
281 }
282 
GetCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & characteristicKey,CharacteristicProfile & charProfile)283 int32_t DeviceProfileManager::GetCharacteristicProfile(const std::string& deviceId, const std::string& serviceName,
284     const std::string& characteristicKey, CharacteristicProfile& charProfile)
285 {
286     HILOGD("call!");
287     int32_t res = 0;
288     {
289         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
290         res = ProfileControlUtils::GetCharacteristicProfile(deviceProfileStore_, deviceId, serviceName,
291             characteristicKey, charProfile);
292     }
293     if (res != DP_SUCCESS) {
294         HILOGE("GetCharacteristicProfile fail, reason: %{public}d!", res);
295         return res;
296     }
297     HILOGD("GetCharacteristicProfile success");
298     return DP_SUCCESS;
299 }
300 
DeleteServiceProfile(const std::string & deviceId,const std::string & serviceName)301 int32_t DeviceProfileManager::DeleteServiceProfile(const std::string& deviceId, const std::string& serviceName)
302 {
303     HILOGD("call!");
304     int32_t res = 0;
305     {
306         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
307         res = ProfileControlUtils::DeleteServiceProfile(deviceProfileStore_, deviceId, serviceName);
308     }
309     if (res != DP_SUCCESS) {
310         HILOGE("DeleteServiceProfile fail, reason: %{public}d!", res);
311         return res;
312     }
313     HILOGD("DeleteServiceProfile success");
314     return DP_SUCCESS;
315 }
316 
DeleteCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & characteristicKey)317 int32_t DeviceProfileManager::DeleteCharacteristicProfile(const std::string& deviceId, const std::string& serviceName,
318     const std::string& characteristicKey)
319 {
320     HILOGD("call!");
321     int32_t res = 0;
322     {
323         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
324         res = ProfileControlUtils::DeleteCharacteristicProfile(deviceProfileStore_, deviceId, serviceName,
325             characteristicKey);
326     }
327     if (res != DP_SUCCESS) {
328         HILOGE("DeleteCharacteristicProfile fail, reason: %{public}d!", res);
329         return res;
330     }
331     HILOGD("DeleteCharacteristicProfile success");
332     return DP_SUCCESS;
333 }
334 
GetAllDeviceProfile(std::vector<DeviceProfile> & deviceProfiles)335 int32_t DeviceProfileManager::GetAllDeviceProfile(std::vector<DeviceProfile>& deviceProfiles)
336 {
337     HILOGD("call!");
338     int32_t res = 0;
339     {
340         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
341         res = ProfileControlUtils::GetAllDeviceProfile(deviceProfileStore_, deviceProfiles);
342     }
343     if (res != DP_SUCCESS) {
344         HILOGE("GetAllDeviceProfile fail, reason: %{public}d!", res);
345         return res;
346     }
347     HILOGD("GetAllDeviceProfile success");
348     return DP_SUCCESS;
349 }
350 
GetAllServiceProfile(std::vector<ServiceProfile> & serviceProfiles)351 int32_t DeviceProfileManager::GetAllServiceProfile(std::vector<ServiceProfile>& serviceProfiles)
352 {
353     HILOGD("call!");
354     int32_t res = 0;
355     {
356         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
357         res = ProfileControlUtils::GetAllServiceProfile(deviceProfileStore_, serviceProfiles);
358     }
359     if (res != DP_SUCCESS) {
360         HILOGE("serviceProfiles fail, reason: %{public}d!", res);
361         return res;
362     }
363     HILOGD("serviceProfiles success");
364     return DP_SUCCESS;
365 }
366 
GetAllCharacteristicProfile(std::vector<CharacteristicProfile> & charProfiles)367 int32_t DeviceProfileManager::GetAllCharacteristicProfile(std::vector<CharacteristicProfile>& charProfiles)
368 {
369     HILOGD("call!");
370     int32_t res = 0;
371     {
372         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
373         res = ProfileControlUtils::GetAllCharacteristicProfile(deviceProfileStore_, charProfiles);
374     }
375     if (res != DP_SUCCESS) {
376         HILOGE("GetAllCharacteristicProfile fail, reason: %{public}d!", res);
377         return res;
378     }
379     HILOGD("GetAllCharacteristicProfile success");
380     return DP_SUCCESS;
381 }
382 
SyncDeviceProfile(const DistributedDeviceProfile::DpSyncOptions & syncOptions,sptr<IRemoteObject> syncCompletedCallback)383 int32_t DeviceProfileManager::SyncDeviceProfile(const DistributedDeviceProfile::DpSyncOptions& syncOptions,
384     sptr<IRemoteObject> syncCompletedCallback)
385 {
386     HILOGI("call!");
387     if (syncCompletedCallback == nullptr) {
388         HILOGE("Params is invalid!");
389         return DP_INVALID_PARAMS;
390     }
391     std::vector<std::string> ohBasedDevices;
392     std::vector<std::string> notOHBasedDevices;
393     ProfileUtils::FilterAndGroupOnlineDevices(syncOptions.GetDeviceList(), ohBasedDevices, notOHBasedDevices);
394     if (ohBasedDevices.empty() && notOHBasedDevices.empty()) {
395         HILOGE("Params is invalid!");
396         return DP_INVALID_PARAMS;
397     }
398     std::string callerDescriptor = PermissionManager::GetInstance().GetCallerProcName();
399     if (!ohBasedDevices.empty()) {
400         ProfileCache::GetInstance().AddSyncListener(callerDescriptor, syncCompletedCallback);
401         {
402             std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
403             if (deviceProfileStore_ == nullptr) {
404                 HILOGE("deviceProfileStore is nullptr");
405                 return DP_SYNC_DEVICE_FAIL;
406             }
407             int32_t syncResult = deviceProfileStore_->Sync(ohBasedDevices, syncOptions.GetSyncMode());
408             if (syncResult != DP_SUCCESS) {
409                 HILOGE("SyncDeviceProfile fail, res: %{public}d!", syncResult);
410                 return DP_SYNC_DEVICE_FAIL;
411             }
412         }
413     }
414     if (!notOHBasedDevices.empty()) {
415         auto syncTask = [this, notOHBasedDevices, callerDescriptor, syncCompletedCallback]() {
416             SyncWithNotOHBasedDevice(notOHBasedDevices, callerDescriptor, syncCompletedCallback);
417         };
418         std::thread(syncTask).detach();
419     }
420     HILOGI("SyncDeviceProfile success, caller: %{public}s!", callerDescriptor.c_str());
421     return DP_SUCCESS;
422 }
423 
LoadDpSyncAdapter()424 bool DeviceProfileManager::LoadDpSyncAdapter()
425 {
426     HILOGI("start.");
427     std::lock_guard<std::mutex> lock(isAdapterLoadLock_);
428     if (isAdapterSoLoaded_ && (dpSyncAdapter_ != nullptr)) {
429         return true;
430     }
431     int64_t beginTime = GetTickCount();
432     std::string soName = std::string(LIB_DP_ADAPTER_NAME);
433     if ((soName.length() == 0) || (soName.length() > PATH_MAX)) {
434         HILOGE("File %{public}s canonicalization failed", soName.c_str());
435         return false;
436     }
437     void *so_handle = dlopen(soName.c_str(), RTLD_NOW | RTLD_NOLOAD);
438     if (so_handle == nullptr) {
439         so_handle = dlopen(soName.c_str(), RTLD_NOW);
440     }
441     if (so_handle == nullptr) {
442         HILOGE("load dp sync adapter so %{public}s failed", soName.c_str());
443         return false;
444     }
445     dlerror();
446     auto func = (CreateDPSyncAdapterFuncPtr)dlsym(so_handle, "CreateDPSyncAdaptertObject");
447     if (dlerror() != nullptr || func == nullptr) {
448         dlclose(so_handle);
449         HILOGE("Create object function is not exist.");
450         return false;
451     }
452     auto adapter = func();
453     if (adapter == nullptr) {
454         dlclose(so_handle);
455         HILOGE("adapter is nullptr");
456         return false;
457     }
458     dpSyncAdapter_ = std::shared_ptr<IDPSyncAdapter>(adapter);
459     if (dpSyncAdapter_->Initialize() != DP_SUCCESS) {
460         dpSyncAdapter_->Release();
461         dpSyncAdapter_ = nullptr;
462         isAdapterSoLoaded_ = false;
463         HILOGE("dp sync adapter init failed");
464         return false;
465     }
466     isAdapterSoLoaded_ = true;
467     int64_t endTime = GetTickCount();
468     HILOGI("sucess. spend %{public}" PRId64 " ms", endTime - beginTime);
469     return true;
470 }
471 
UnloadDpSyncAdapter()472 void DeviceProfileManager::UnloadDpSyncAdapter()
473 {
474     HILOGD("start.");
475     std::lock_guard<std::mutex> lock(isAdapterLoadLock_);
476     if (dpSyncAdapter_ != nullptr) {
477         dpSyncAdapter_->Release();
478     }
479     dpSyncAdapter_ = nullptr;
480     std::string soPathName = std::string(LIB_DP_ADAPTER_NAME);
481     if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
482         HILOGE("File %{public}s canonicalization failed", soPathName.c_str());
483         return;
484     }
485     void *so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
486     if (so_handle != nullptr) {
487         HILOGI("dp sync adapter so_handle is not nullptr.");
488         dlclose(so_handle);
489         isAdapterSoLoaded_ = false;
490     }
491 }
492 
SyncWithNotOHBasedDevice(const std::vector<std::string> & notOHBasedDevices,const std::string & callerDescriptor,sptr<IRemoteObject> syncCompletedCallback)493 int32_t DeviceProfileManager::SyncWithNotOHBasedDevice(const std::vector<std::string>& notOHBasedDevices,
494     const std::string& callerDescriptor, sptr<IRemoteObject> syncCompletedCallback)
495 {
496     if (!LoadDpSyncAdapter()) {
497         HILOGE("dp service adapter load failed.");
498         SyncWithNotOHBasedDeviceFailed(notOHBasedDevices, syncCompletedCallback);
499         return DP_LOAD_SYNC_ADAPTER_FAILED;
500     }
501     for (const auto& deviceId : notOHBasedDevices) {
502         if (RunloadedFunction(deviceId, syncCompletedCallback) != DP_SUCCESS) {
503             HILOGE("Sync With NotOHBasedDevice Failed. deviceId:%{public}s",
504                 ProfileUtils::GetAnonyString(deviceId).c_str());
505             SyncWithNotOHBasedDeviceFailed({deviceId}, syncCompletedCallback);
506         }
507     }
508     return DP_SUCCESS;
509 }
510 
SyncWithNotOHBasedDeviceFailed(const std::vector<std::string> & notOHBasedDevices,sptr<IRemoteObject> syncCompletedCallback)511 void DeviceProfileManager::SyncWithNotOHBasedDeviceFailed(const std::vector<std::string>& notOHBasedDevices,
512     sptr<IRemoteObject> syncCompletedCallback)
513 {
514     std::map<std::string, SyncStatus> syncResults;
515     for (const auto& deviceId : notOHBasedDevices) {
516         syncResults[deviceId] = SyncStatus::FAILED;
517     }
518     sptr<ISyncCompletedCallback> syncListenerProxy = iface_cast<ISyncCompletedCallback>(syncCompletedCallback);
519     if (syncListenerProxy == nullptr) {
520         HILOGE("Cast to ISyncCompletedCallback failed");
521         return;
522     }
523     syncListenerProxy->OnSyncCompleted(syncResults);
524 }
525 
RunloadedFunction(const std::string & deviceId,sptr<IRemoteObject> syncCompletedCallback)526 int32_t DeviceProfileManager::RunloadedFunction(const std::string& deviceId, sptr<IRemoteObject> syncCompletedCallback)
527 {
528     std::lock_guard<std::mutex> lock(isAdapterLoadLock_);
529     if (dpSyncAdapter_ == nullptr) {
530         HILOGE("dpSyncAdapter is nullptr.");
531         return DP_LOAD_SYNC_ADAPTER_FAILED;
532     }
533     if (dpSyncAdapter_->DetectRemoteDPVersion(deviceId) != DP_SUCCESS) {
534         HILOGE("dp service adapter detect remote version failed.");
535         return DP_LOAD_SYNC_ADAPTER_FAILED;
536     }
537     const std::list<std::string> deviceIdList = { deviceId };
538     if (dpSyncAdapter_->SyncProfile(deviceIdList, syncCompletedCallback) != DP_SUCCESS) {
539         HILOGE("dp service adapter sync profile failed.");
540         return DP_LOAD_SYNC_ADAPTER_FAILED;
541     }
542     HILOGD("dp service adapter sync profile success.");
543     return DP_SUCCESS;
544 }
545 
GetEntriesByKeys(const std::vector<std::string> & keys)546 std::vector<DistributedKv::Entry> DeviceProfileManager::GetEntriesByKeys(const std::vector<std::string>& keys)
547 {
548     HILOGD("call!");
549     std::vector<DistributedKv::Entry> entries;
550     if (keys.empty()) {
551         HILOGE("keys empty.");
552         return entries;
553     }
554     {
555         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
556         if (deviceProfileStore_ == nullptr) {
557             HILOGE("dynamicProfileStore is nullptr!");
558             return entries;
559         }
560         for (const auto& key : keys) {
561             std::string value;
562             if (deviceProfileStore_->Get(key, value) != DP_SUCCESS) {
563                 continue;
564             }
565             DistributedKv::Entry entry;
566             DistributedKv::Key kvKey(key);
567             entry.key = kvKey;
568             entry.value = value;
569             entries.emplace_back(entry);
570         }
571     }
572     return entries;
573 }
574 
AddToPutTempCache(const std::map<std::string,std::string> & values)575 void DeviceProfileManager::AddToPutTempCache(const std::map<std::string, std::string>& values)
576 {
577     if (values.empty()) {
578         HILOGW("values empty!");
579         return;
580     }
581     HILOGI("values.size : %{public}zu", values.size());
582     {
583         std::lock_guard<std::mutex> lock(putTempCacheMutex_);
584         for (const auto& [key, value] : values) {
585             putTempCache_[key] = value;
586         }
587     }
588 }
589 
SavePutTempCache(std::map<std::string,std::string> & entries)590 int32_t DeviceProfileManager::SavePutTempCache(std::map<std::string, std::string>& entries)
591 {
592     HILOGI("business entries.size : %{public}zu", entries.size());
593     {
594         std::lock_guard<std::mutex> lock(putTempCacheMutex_);
595         if (!putTempCache_.empty()) {
596             for (const auto& [key, value] : putTempCache_) {
597                 entries[key] = value;
598             }
599         }
600     }
601     if (entries.empty()) {
602         HILOGW("all entries empty!");
603         isFirst_.store(false);
604         {
605             std::lock_guard<std::mutex> lock(putTempCacheMutex_);
606             putTempCache_.clear();
607         }
608         return DP_SUCCESS;
609     }
610     HILOGI("all entries.size : %{public}zu", entries.size());
611     int32_t ret = DP_SUCCESS;
612     {
613         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
614         if (deviceProfileStore_ == nullptr) {
615             HILOGE("deviceProfileStore is nullptr!");
616             return DP_GET_KV_DB_FAIL;
617         }
618         ret = deviceProfileStore_->PutBatch(entries);
619         if (ret != DP_SUCCESS) {
620             HILOGE("PutBatch fail! ret:%{public}d", ret);
621             return ret;
622         }
623     }
624     isFirst_.store(false);
625     {
626         std::lock_guard<std::mutex> lock(putTempCacheMutex_);
627         putTempCache_.clear();
628     }
629     HILOGI("put all entries success");
630     return ret;
631 }
632 
IsFirstInitDB()633 bool DeviceProfileManager::IsFirstInitDB()
634 {
635     return isFirst_.load();
636 }
637 
ResetFirst()638 void DeviceProfileManager::ResetFirst()
639 {
640     isFirst_.store(false);
641 }
642 
OnDeviceOnline(const DistributedHardware::DmDeviceInfo deviceInfo)643 void DeviceProfileManager::OnDeviceOnline(const DistributedHardware::DmDeviceInfo deviceInfo)
644 {
645     FixDataOnDeviceOnline(deviceInfo);
646     NotifyNotOHBaseOnline(deviceInfo);
647     if (ContentSensorManagerUtils::GetInstance().IsDeviceE2ESync()) {
648         HILOGI("need E2ESync, networkId:%{public}s", ProfileUtils::GetAnonyString(deviceInfo.networkId).c_str());
649         E2ESyncDynamicProfile(deviceInfo);
650         StaticProfileManager::GetInstance().E2ESyncStaticProfile(deviceInfo);
651     }
652 }
653 
FixDataOnDeviceOnline(const DistributedHardware::DmDeviceInfo deviceInfo)654 void DeviceProfileManager::FixDataOnDeviceOnline(const DistributedHardware::DmDeviceInfo deviceInfo)
655 {
656     std::string remoteNetworkId = deviceInfo.networkId;
657     HILOGD("remoteNetworkId=%{public}s", ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
658     if (remoteNetworkId.empty() || deviceInfo.extraData.empty()) {
659         HILOGE("networkId or extraData is empty!");
660         return;
661     }
662     auto task = [this, remoteNetworkId, extraData = deviceInfo.extraData]() {
663         std::string localUdid = ProfileCache::GetInstance().GetLocalUdid();
664         std::string localUuid = ProfileCache::GetInstance().GetLocalUuid();
665         if (localUdid.empty() || localUuid.empty()) {
666             HILOGE("Get local udid fail.");
667             return;
668         }
669         std::map<std::string, std::string> localDataByOwner;
670         if (GetProfilesByOwner(localUuid, localDataByOwner) != DP_SUCCESS) {
671             HILOGE("GetProfilesByOwner fail, localUuid=%{public}s", ProfileUtils::GetAnonyString(localUuid).c_str());
672             return;
673         }
674         FixLocalData(localUdid, localDataByOwner);
675         std::string remoteUdid;
676         if (ProfileCache::GetInstance().GetUdidByNetWorkId(remoteNetworkId, remoteUdid) != DP_SUCCESS ||
677             remoteUdid.empty()) {
678             HILOGE("Get remote udid failed. remoteNetworkId=%{public}s",
679                 ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
680             return;
681         }
682         if (!ProfileUtils::IsOHBasedDevice(extraData)) {
683             FixRemoteDataWhenPeerIsNonOH(remoteUdid);
684             return;
685         }
686         FixRemoteDataWhenPeerIsOHBase(remoteUdid, localDataByOwner);
687     };
688     auto handler = EventHandlerFactory::GetInstance().GetEventHandler();
689     if (handler == nullptr || !handler->PostTask(task)) {
690         HILOGE("Post FixDataOnDeviceOnline task faild");
691         return;
692     }
693 }
694 
DeleteBatchByKeys(const std::vector<std::string> & delKeys)695 int32_t DeviceProfileManager::DeleteBatchByKeys(const std::vector<std::string>& delKeys)
696 {
697     HILOGD("delKeys.size:%{public}zu", delKeys.size());
698     if (delKeys.empty()) {
699         HILOGW("delKeys is empty");
700         return DP_SUCCESS;
701     }
702     std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
703     if (deviceProfileStore_ == nullptr) {
704         HILOGE("dynamicProfileStore is nullptr!");
705         return DP_KV_DB_PTR_NULL;
706     }
707     if (deviceProfileStore_->DeleteBatch(delKeys) != DP_SUCCESS) {
708         HILOGE("DeleteBatch fail");
709         return DP_DEL_KV_DB_FAIL;
710     }
711     return DP_SUCCESS;
712 }
713 
GetProfilesByOwner(const std::string & uuid,std::map<std::string,std::string> & values)714 int32_t DeviceProfileManager::GetProfilesByOwner(const std::string& uuid, std::map<std::string, std::string>& values)
715 {
716     HILOGD("uuid:%{public}s", ProfileUtils::GetAnonyString(uuid).c_str());
717     if (uuid.empty()) {
718         HILOGW("uuid is empty");
719         return DP_INVALID_PARAM;
720     }
721     std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
722     if (deviceProfileStore_ == nullptr) {
723         HILOGE("dynamicProfileStore is nullptr!");
724         return DP_KV_DB_PTR_NULL;
725     }
726     if (deviceProfileStore_->GetDeviceEntries(uuid, values) != DP_SUCCESS) {
727         HILOGE("GetDeviceEntries fail, uuid=%{public}s", ProfileUtils::GetAnonyString(uuid).c_str());
728         return DP_GET_DEVICE_ENTRIES_FAIL;
729     }
730     return DP_SUCCESS;
731 }
732 
GetProfilesByKeyPrefix(const std::string & udid,std::map<std::string,std::string> & values)733 int32_t DeviceProfileManager::GetProfilesByKeyPrefix(const std::string& udid,
734     std::map<std::string, std::string>& values)
735 {
736     HILOGD("udid:%{public}s", ProfileUtils::GetAnonyString(udid).c_str());
737     if (udid.empty()) {
738         HILOGW("udid is empty");
739         return DP_INVALID_PARAM;
740     }
741     std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
742     if (deviceProfileStore_ == nullptr) {
743         HILOGE("dynamicProfileStore is nullptr!");
744         return DP_KV_DB_PTR_NULL;
745     }
746     if (deviceProfileStore_->GetByPrefix(DEV_PREFIX + SEPARATOR + udid, values) != DP_SUCCESS) {
747         HILOGE("Get dev profile by prefix fail, udid=%{public}s", ProfileUtils::GetAnonyString(udid).c_str());
748         return DP_GET_KV_DB_FAIL;
749     }
750     if (deviceProfileStore_->GetByPrefix(SVR_PREFIX + SEPARATOR + udid, values) != DP_SUCCESS) {
751         HILOGE("Get svr profile by prefix fail, udid=%{public}s", ProfileUtils::GetAnonyString(udid).c_str());
752         return DP_GET_KV_DB_FAIL;
753     }
754     if (deviceProfileStore_->GetByPrefix(CHAR_PREFIX + SEPARATOR + udid, values) != DP_SUCCESS) {
755         HILOGE("Get char profile by prefix fail, udid=%{public}s", ProfileUtils::GetAnonyString(udid).c_str());
756         return DP_GET_KV_DB_FAIL;
757     }
758     return DP_SUCCESS;
759 }
760 
NotifyNotOHBaseOnline(const DistributedHardware::DmDeviceInfo deviceInfo)761 void DeviceProfileManager::NotifyNotOHBaseOnline(const DistributedHardware::DmDeviceInfo deviceInfo)
762 {
763     std::string remoteNetworkId = deviceInfo.networkId;
764     HILOGD("networkId:%{public}s", ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
765     if (remoteNetworkId.empty()) {
766         HILOGE("networkId or extraData is empty!");
767         return;
768     }
769     if (ProfileUtils::IsOHBasedDevice(deviceInfo.extraData)) {
770         HILOGD("device is ohbase. remoteNetworkId=%{public}s", ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
771         return;
772     }
773     auto task = [this, remoteNetworkId, authForm = static_cast<int32_t>(deviceInfo.authForm)]() {
774         std::string remoteUdid;
775         if (ProfileCache::GetInstance().GetUdidByNetWorkId(remoteNetworkId, remoteUdid) != DP_SUCCESS ||
776             remoteUdid.empty()) {
777             HILOGE("Get remote deviceId failed. remoteNetworkId=%{public}s",
778                 ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
779             return;
780         }
781         std::lock_guard<std::mutex> lock(isAdapterLoadLock_);
782         if (dpSyncAdapter_ == nullptr) {
783             HILOGE("dpSyncAdapter is nullptr.");
784             return;
785         }
786         int32_t ret = dpSyncAdapter_->NotOHBaseDeviceOnline(remoteUdid, remoteNetworkId, ProfileUtils::IsP2p(authForm));
787         if (ret != DP_SUCCESS) {
788             HILOGE("NotOHBaseDeviceOnline fail. ret=%{public}d, remoteNetworkId=%{public}s, authForm=%{public}d",
789                 ret, ProfileUtils::GetAnonyString(remoteNetworkId).c_str(), authForm);
790             return;
791         }
792     };
793     auto handler = EventHandlerFactory::GetInstance().GetEventHandler();
794     if (handler == nullptr || !handler->PostTask(task)) {
795         HILOGE("Post NotifyNotOHBaseOnline task faild");
796         return;
797     }
798 }
799 
E2ESyncDynamicProfile(const DistributedHardware::DmDeviceInfo deviceInfo)800 void DeviceProfileManager::E2ESyncDynamicProfile(const DistributedHardware::DmDeviceInfo deviceInfo)
801 {
802     HILOGD("call!");
803     auto task = [this, deviceInfo]() {
804         std::string remoteNetworkId = deviceInfo.networkId;
805         HILOGD("networkId:%{public}s", ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
806         if (remoteNetworkId.empty()) {
807             HILOGE("networkId or extraData is empty!");
808             return;
809         }
810         if (!ProfileUtils::IsOHBasedDevice(deviceInfo.extraData)) {
811             HILOGI("device is not ohbase. remoteNetworkId=%{public}s",
812                 ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
813             return;
814         }
815         std::lock_guard<std::mutex> lock(dynamicStoreMutex_);
816         if (deviceProfileStore_ == nullptr) {
817             HILOGE("deviceProfileStore is nullptr");
818             return;
819         }
820         int32_t syncResult = deviceProfileStore_->Sync({remoteNetworkId}, SyncMode::PUSH_PULL);
821         if (syncResult != DP_SUCCESS) {
822             HILOGE("E2ESyncDynamicProfile fail, res: %{public}d!", syncResult);
823             return;
824         }
825         HILOGI("E2ESyncDynamicProfile success!");
826     };
827     auto handler = EventHandlerFactory::GetInstance().GetEventHandler();
828     if (handler == nullptr || !handler->PostTask(task)) {
829         HILOGE("Post E2ESyncDynamicProfile task fail!");
830         return;
831     }
832 }
833 
834 // Clean data that does not belong to the local.
FixLocalData(const std::string & localUdid,const std::map<std::string,std::string> & localDataByOwner)835 void DeviceProfileManager::FixLocalData(const std::string& localUdid,
836     const std::map<std::string, std::string>& localDataByOwner)
837 {
838     HILOGD("localUdid:%{public}s,localDataByOwner.size:%{public}zu",
839         ProfileUtils::GetAnonyString(localUdid).c_str(), localDataByOwner.size());
840     if (localDataByOwner.empty()) { return; }
841     std::map<std::string, std::string> localDataByKeyPrefix;
842     if (GetProfilesByKeyPrefix(localUdid, localDataByKeyPrefix) != DP_SUCCESS) {
843         HILOGE("GetProfilesByKeyPrefix fail, localUdid=%{public}s", ProfileUtils::GetAnonyString(localUdid).c_str());
844         return;
845     }
846     HILOGD("localDataByKeyPrefix.size:%{public}zu", localDataByKeyPrefix.size());
847     if (localDataByKeyPrefix.empty()) { return; }
848     std::vector<std::string> delKeys;
849     // cloud has local data, but the data is not written by local
850     for (const auto& [key, _] : localDataByKeyPrefix) {
851         if (localDataByOwner.find(key) == localDataByOwner.end()) {
852             HILOGI("delKey: %{public}s", ProfileUtils::GetDbKeyAnonyString(key).c_str());
853             delKeys.emplace_back(key);
854         }
855     }
856     HILOGD("delKeys.size:%{public}zu", delKeys.size());
857     if (delKeys.empty()) { return; }
858     if (DeleteBatchByKeys(delKeys) != DP_SUCCESS) {
859         HILOGE("DeleteBatchByKeys fail, localUdid=%{public}s", ProfileUtils::GetAnonyString(localUdid).c_str());
860         return;
861     }
862 }
863 
864 // Clean ohbase data when the peer is non-ohbase
FixRemoteDataWhenPeerIsNonOH(const std::string & remoteUdid)865 void DeviceProfileManager::FixRemoteDataWhenPeerIsNonOH(const std::string& remoteUdid)
866 {
867     HILOGD("remoteUdid:%{public}s", ProfileUtils::GetAnonyString(remoteUdid).c_str());
868     std::map<std::string, std::string> remoteDataByKeyPrefix;
869     if (GetProfilesByKeyPrefix(remoteUdid, remoteDataByKeyPrefix) != DP_SUCCESS) {
870         HILOGE("GetProfilesByKeyPrefix fail, remoteUdid=%{public}s", ProfileUtils::GetAnonyString(remoteUdid).c_str());
871         return;
872     }
873     std::vector<std::string> delKeys;
874     for (const auto& [key, _] : remoteDataByKeyPrefix) {
875         std::vector<std::string> res;
876         if (ProfileUtils::SplitString(key, SEPARATOR, res) != DP_SUCCESS || res.size() < NUM_3) {
877             HILOGW("SplitString fail, key: %{public}s", ProfileUtils::GetDbKeyAnonyString(key).c_str());
878             continue;
879         }
880         if (ProfileUtils::EndsWith(res[NUM_2], OH_PROFILE_SUFFIX)) {
881             HILOGI("delKey: %{public}s", ProfileUtils::GetDbKeyAnonyString(key).c_str());
882             delKeys.emplace_back(key);
883             continue;
884         }
885         if ((res[0] == SVR_PREFIX || res[0] == CHAR_PREFIX) &&
886             NON_OHBASE_NEED_CLEAR_SVR_NAMES.find(res[NUM_2]) != NON_OHBASE_NEED_CLEAR_SVR_NAMES.end()) {
887             HILOGI("delKey: %{public}s", ProfileUtils::GetDbKeyAnonyString(key).c_str());
888             delKeys.emplace_back(key);
889             continue;
890         }
891     }
892     HILOGD("delKeys.size:%{public}zu", delKeys.size());
893     if (delKeys.empty()) { return; }
894     if (DeleteBatchByKeys(delKeys) != DP_SUCCESS) {
895         HILOGE("DeleteBatchByKeys fail, remoteUdid=%{public}s", ProfileUtils::GetAnonyString(remoteUdid).c_str());
896         return;
897     }
898 }
899 
900 // Clean non-ohbase data when the peer is ohbase
FixRemoteDataWhenPeerIsOHBase(const std::string & remoteUdid,const std::map<std::string,std::string> & localDataByOwner)901 void DeviceProfileManager::FixRemoteDataWhenPeerIsOHBase(const std::string& remoteUdid,
902     const std::map<std::string, std::string>& localDataByOwner)
903 {
904     HILOGD("remoteUdid:%{public}s", ProfileUtils::GetAnonyString(remoteUdid).c_str());
905     std::vector<std::string> delKeys;
906     // local has remote data, and the data is written by local
907     for (const auto& [key, _] : localDataByOwner) {
908         if (key.find(remoteUdid) != std::string::npos) {
909             HILOGI("delKey: %{public}s", ProfileUtils::GetDbKeyAnonyString(key).c_str());
910             delKeys.emplace_back(key);
911         }
912     }
913     HILOGD("delKeys.size:%{public}zu", delKeys.size());
914     if (delKeys.empty()) { return; }
915     if (deviceProfileStore_->DeleteBatch(delKeys) != DP_SUCCESS) {
916         HILOGE("DeleteBatch failed, remoteUdid=%{public}s", ProfileUtils::GetAnonyString(remoteUdid).c_str());
917         return;
918     }
919 }
920 } // namespace DeviceProfile
921 } // namespace OHOS
922