1 /*
2  * Copyright (c) 2023-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 "profile_cache.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 
21 #include "datetime_ex.h"
22 #include "device_manager.h"
23 
24 #include "content_sensor_manager_utils.h"
25 #include "distributed_device_profile_errors.h"
26 #include "device_profile_manager.h"
27 #include "profile_utils.h"
28 #include "static_profile_manager.h"
29 #include "switch_profile_manager.h"
30 #include "sync_subscriber_death_recipient.h"
31 
32 namespace OHOS {
33 namespace DistributedDeviceProfile {
34 IMPLEMENT_SINGLE_INSTANCE(ProfileCache);
35 
36 namespace {
37     const std::string TAG = "ProfileCache";
38 }
39 
Init()40 int32_t ProfileCache::Init()
41 {
42     HILOGI("call!");
43     ContentSensorManagerUtils::GetInstance().ObtainDeviceDataSyncMode();
44     RefreshProfileCache();
45     SwitchProfileManager::GetInstance().RefreshLocalSwitchProfile();
46     syncListenerDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new SyncSubscriberDeathRecipient);
47     std::vector<DistributedHardware::DmDeviceInfo> allOnlineDeviceInfo;
48     int32_t res =
49         DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(DP_PKG_NAME, "", allOnlineDeviceInfo);
50     if (res != DP_SUCCESS || allOnlineDeviceInfo.empty()) {
51         HILOGW("GetTrustedDeviceList failed, res: %{public}d", res);
52         return DP_SUCCESS;
53     }
54 
55     std::string udid = EMPTY_STRING;
56     std::lock_guard<std::mutex> lock(onlineDeviceLock_);
57     for (const auto& dmDeviceInfo : allOnlineDeviceInfo) {
58         if (!ProfileUtils::GetUdidByNetworkId(dmDeviceInfo.networkId, udid)) {
59             HILOGE("get udid by networkId failed, networkId:%{public}s",
60                 ProfileUtils::GetAnonyString(dmDeviceInfo.networkId).c_str());
61             continue;
62         }
63         onlineDevMap_[udid] = dmDeviceInfo.networkId;
64         HILOGI("Init add %{public}s", ProfileUtils::GetAnonyString(udid).c_str());
65     }
66     return DP_SUCCESS;
67 }
68 
UnInit()69 int32_t ProfileCache::UnInit()
70 {
71     HILOGI("UnInit");
72     {
73         std::lock_guard<std::mutex> lock(onlineDeviceLock_);
74         onlineDevMap_.clear();
75     }
76     {
77         std::lock_guard<std::mutex> lock(deviceProfileMutex_);
78         deviceProfileMap_.clear();
79     }
80     {
81         std::lock_guard<std::mutex> lock(serviceProfileMutex_);
82         serviceProfileMap_.clear();
83     }
84     {
85         std::lock_guard<std::mutex> lock(charProfileMutex_);
86         charProfileMap_.clear();
87     }
88     {
89         std::lock_guard<std::mutex> lock(staticCharProfileMutex_);
90         staticCharProfileMap_.clear();
91     }
92     {
93         std::lock_guard<std::mutex> lock(syncListenerMutex_);
94         syncListenerMap_.clear();
95     }
96     return DP_SUCCESS;
97 }
98 
AddDeviceProfile(const DeviceProfile & deviceProfile)99 int32_t ProfileCache::AddDeviceProfile(const DeviceProfile& deviceProfile)
100 {
101     if (!ProfileUtils::IsKeyValid(deviceProfile.GetDeviceId())) {
102         HILOGE("Params is invalid!");
103         return DP_INVALID_PARAMS;
104     }
105     std::string deviceProfileKey = ProfileUtils::GenerateDeviceProfileKey(deviceProfile.GetDeviceId());
106     {
107         std::lock_guard<std::mutex> lock(deviceProfileMutex_);
108         if (deviceProfileMap_.size() > MAX_DEVICE_SIZE) {
109             HILOGE("DeviceProfileMap size is invalid!size: %{public}zu!", deviceProfileMap_.size());
110             return DP_EXCEED_MAX_SIZE_FAIL;
111         }
112         deviceProfileMap_[deviceProfileKey] = deviceProfile;
113     }
114     return DP_SUCCESS;
115 }
116 
AddServiceProfile(const ServiceProfile & serviceProfile)117 int32_t ProfileCache::AddServiceProfile(const ServiceProfile& serviceProfile)
118 {
119     if (!ProfileUtils::IsKeyValid(serviceProfile.GetDeviceId()) ||
120         !ProfileUtils::IsKeyValid(serviceProfile.GetServiceName())) {
121         HILOGE("Params is invalid!");
122         return DP_INVALID_PARAMS;
123     }
124     std::string serviceProfileKey = ProfileUtils::GenerateServiceProfileKey(serviceProfile.GetDeviceId(),
125         serviceProfile.GetServiceName());
126     {
127         std::lock_guard<std::mutex> lock(serviceProfileMutex_);
128         if (serviceProfileMap_.size() > MAX_SERVICE_SIZE) {
129             HILOGE("ServiceProfileMap size is invalid!size: %{public}zu!", serviceProfileMap_.size());
130             return DP_EXCEED_MAX_SIZE_FAIL;
131         }
132         serviceProfileMap_[serviceProfileKey] = serviceProfile;
133     }
134     return DP_SUCCESS;
135 }
136 
AddCharProfile(const CharacteristicProfile & charProfile)137 int32_t ProfileCache::AddCharProfile(const CharacteristicProfile& charProfile)
138 {
139     if (!ProfileUtils::IsKeyValid(charProfile.GetDeviceId()) ||
140         !ProfileUtils::IsKeyValid(charProfile.GetServiceName()) ||
141         !ProfileUtils::IsKeyValid(charProfile.GetCharacteristicKey())) {
142         HILOGE("Params is invalid!");
143         return DP_INVALID_PARAMS;
144     }
145     std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(charProfile.GetDeviceId(),
146         charProfile.GetServiceName(), charProfile.GetCharacteristicKey());
147     {
148         std::lock_guard<std::mutex> lock(charProfileMutex_);
149         if (charProfileMap_.size() > MAX_CHAR_SIZE) {
150             HILOGE("CharProfileMap size is invalid!size: %{public}zu!", charProfileMap_.size());
151             return DP_EXCEED_MAX_SIZE_FAIL;
152         }
153         charProfileMap_[charProfileKey] = charProfile;
154     }
155     return DP_SUCCESS;
156 }
157 
AddStaticCharProfile(const CharacteristicProfile & charProfile)158 int32_t ProfileCache::AddStaticCharProfile(const CharacteristicProfile& charProfile)
159 {
160     if (!ProfileUtils::IsKeyValid(charProfile.GetDeviceId()) ||
161         !ProfileUtils::IsKeyValid(charProfile.GetServiceName()) ||
162         !ProfileUtils::IsKeyValid(charProfile.GetCharacteristicKey())) {
163         HILOGE("Params is invalid!");
164         return DP_INVALID_PARAMS;
165     }
166     std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(charProfile.GetDeviceId(),
167         charProfile.GetServiceName(), charProfile.GetCharacteristicKey());
168     {
169         std::lock_guard<std::mutex> lock(staticCharProfileMutex_);
170         if (staticCharProfileMap_.size() > MAX_CHAR_SIZE) {
171             HILOGE("CharProfileMap size is invalid!size: %{public}zu!", staticCharProfileMap_.size());
172             return DP_EXCEED_MAX_SIZE_FAIL;
173         }
174         staticCharProfileMap_[charProfileKey] = charProfile;
175     }
176     return DP_SUCCESS;
177 }
178 
AddStaticCharProfileBatch(const std::unordered_map<std::string,CharacteristicProfile> & charProfiles)179 int32_t ProfileCache::AddStaticCharProfileBatch(
180     const std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
181 {
182     for (const auto& item : charProfiles) {
183         HILOGD("%{public}s!", item.second.dump().c_str());
184         ProfileCache::AddStaticCharProfile(item.second);
185     }
186     return DP_SUCCESS;
187 }
188 
GetDeviceProfile(const std::string & deviceId,DeviceProfile & deviceProfile)189 int32_t ProfileCache::GetDeviceProfile(const std::string& deviceId, DeviceProfile& deviceProfile)
190 {
191     if (!ProfileUtils::IsKeyValid(deviceId)) {
192         HILOGE("Params is invalid!");
193         return DP_INVALID_PARAMS;
194     }
195     {
196         std::lock_guard<std::mutex> lock(deviceProfileMutex_);
197         std::string deviceProfileKey = ProfileUtils::GenerateDeviceProfileKey(deviceId);
198         if (deviceProfileMap_.find(deviceProfileKey) == deviceProfileMap_.end()) {
199             HILOGI("ProfileKey is not found in deviceProfileMap!");
200             return DP_NOT_FOUND_FAIL;
201         }
202         deviceProfile = deviceProfileMap_[deviceProfileKey];
203     }
204     return DP_SUCCESS;
205 }
206 
GetServiceProfile(const std::string & deviceId,const std::string & serviceName,ServiceProfile & serviceProfile)207 int32_t ProfileCache::GetServiceProfile(const std::string& deviceId, const std::string& serviceName,
208     ServiceProfile& serviceProfile)
209 {
210     if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName)) {
211         HILOGE("Params is invalid!");
212         return DP_INVALID_PARAMS;
213     }
214     {
215         std::lock_guard<std::mutex> lock(serviceProfileMutex_);
216         std::string serviceProfileKey = ProfileUtils::GenerateServiceProfileKey(deviceId, serviceName);
217         if (serviceProfileMap_.find(serviceProfileKey) == serviceProfileMap_.end()) {
218             HILOGI("ProfileKey is not found in serviceProfileMap!");
219             return DP_NOT_FOUND_FAIL;
220         }
221         serviceProfile = serviceProfileMap_[serviceProfileKey];
222     }
223     return DP_SUCCESS;
224 }
225 
GetCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & charKey,CharacteristicProfile & charProfile)226 int32_t ProfileCache::GetCharacteristicProfile(const std::string& deviceId, const std::string& serviceName,
227     const std::string& charKey, CharacteristicProfile& charProfile)
228 {
229     if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName) ||
230         !ProfileUtils::IsKeyValid(charKey)) {
231         HILOGE("Params is invalid!");
232         return DP_INVALID_PARAMS;
233     }
234     {
235         std::lock_guard<std::mutex> lock(charProfileMutex_);
236         std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(deviceId, serviceName, charKey);
237         if (charProfileMap_.find(charProfileKey) == charProfileMap_.end()) {
238             HILOGD("ProfileKey is not found in charProfileMap!");
239             return DP_NOT_FOUND_FAIL;
240         }
241         charProfile = charProfileMap_[charProfileKey];
242     }
243     return DP_SUCCESS;
244 }
245 
GetStaticCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & charKey,CharacteristicProfile & charProfile)246 int32_t ProfileCache::GetStaticCharacteristicProfile(const std::string& deviceId, const std::string& serviceName,
247     const std::string& charKey, CharacteristicProfile& charProfile)
248 {
249     if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName) ||
250         !ProfileUtils::IsKeyValid(charKey)) {
251         HILOGE("Params is invalid!");
252         return DP_INVALID_PARAMS;
253     }
254     {
255         std::lock_guard<std::mutex> lock(staticCharProfileMutex_);
256         std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(deviceId, serviceName, charKey);
257         if (staticCharProfileMap_.find(charProfileKey) == staticCharProfileMap_.end()) {
258             HILOGI("ProfileKey is not found in charProfileMap!");
259             return DP_NOT_FOUND_FAIL;
260         }
261         charProfile = staticCharProfileMap_[charProfileKey];
262     }
263     return DP_SUCCESS;
264 }
265 
DeleteDeviceProfile(const std::string & deviceId)266 int32_t ProfileCache::DeleteDeviceProfile(const std::string& deviceId)
267 {
268     if (!ProfileUtils::IsKeyValid(deviceId)) {
269         HILOGE("Params is invalid!");
270         return DP_INVALID_PARAMS;
271     }
272     std::string deviceProfileKey = ProfileUtils::GenerateDeviceProfileKey(deviceId);
273     {
274         std::lock_guard<std::mutex> lock(deviceProfileMutex_);
275         deviceProfileMap_.erase(deviceProfileKey);
276     }
277     return DP_SUCCESS;
278 }
279 
DeleteServiceProfile(const std::string & deviceId,const std::string & serviceName)280 int32_t ProfileCache::DeleteServiceProfile(const std::string& deviceId, const std::string& serviceName)
281 {
282     if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName)) {
283         HILOGE("Params is invalid!");
284         return DP_INVALID_PARAMS;
285     }
286     std::string serviceProfileKey = ProfileUtils::GenerateServiceProfileKey(deviceId, serviceName);
287     {
288         std::lock_guard<std::mutex> lock(serviceProfileMutex_);
289         serviceProfileMap_.erase(serviceProfileKey);
290     }
291     return DP_SUCCESS;
292 }
293 
DeleteCharProfile(const std::string & deviceId,const std::string & serviceName,const std::string & charKey)294 int32_t ProfileCache::DeleteCharProfile(const std::string& deviceId, const std::string& serviceName,
295     const std::string& charKey)
296 {
297     if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName) ||
298         !ProfileUtils::IsKeyValid(charKey)) {
299         HILOGE("Params is invalid!");
300         return DP_INVALID_PARAMS;
301     }
302     std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(deviceId, serviceName, charKey);
303     {
304         std::lock_guard<std::mutex> lock(charProfileMutex_);
305         charProfileMap_.erase(charProfileKey);
306     }
307     return DP_SUCCESS;
308 }
309 
IsDeviceProfileExist(const DeviceProfile & deviceProfile)310 bool ProfileCache::IsDeviceProfileExist(const DeviceProfile& deviceProfile)
311 {
312     if (!ProfileUtils::IsKeyValid(deviceProfile.GetDeviceId())) {
313         HILOGE("Params is invalid!");
314         return false;
315     }
316     std::string deviceProfileKey = ProfileUtils::GenerateDeviceProfileKey(deviceProfile.GetDeviceId());
317     {
318         std::lock_guard<std::mutex> lock(deviceProfileMutex_);
319         if (deviceProfileMap_.find(deviceProfileKey) == deviceProfileMap_.end()) {
320             HILOGE("ProfileKey is not found in deviceProfileMap!");
321             return false;
322         }
323         DeviceProfile deviceProfileCache = deviceProfileMap_[deviceProfileKey];
324         if (deviceProfile != deviceProfileCache) {
325             HILOGE("The device profile is not same in cache!");
326             return false;
327         }
328     }
329     return true;
330 }
331 
IsServiceProfileExist(const ServiceProfile & serviceProfile)332 bool ProfileCache::IsServiceProfileExist(const ServiceProfile& serviceProfile)
333 {
334     if (!ProfileUtils::IsKeyValid(serviceProfile.GetDeviceId()) ||
335         !ProfileUtils::IsKeyValid(serviceProfile.GetServiceName())) {
336         HILOGE("Params is invalid!");
337         return false;
338     }
339     std::string serviceProfileKey = ProfileUtils::GenerateServiceProfileKey(serviceProfile.GetDeviceId(),
340         serviceProfile.GetServiceName());
341     {
342         std::lock_guard<std::mutex> lock(serviceProfileMutex_);
343         if (serviceProfileMap_.find(serviceProfileKey) == serviceProfileMap_.end()) {
344             HILOGE("ProfileKey is not found in serviceProfileMap!");
345             return false;
346         }
347         ServiceProfile serviceProfileCache = serviceProfileMap_[serviceProfileKey];
348         if (serviceProfile != serviceProfileCache) {
349             HILOGE("The service profile is not same in cache!");
350             return false;
351         }
352     }
353     return true;
354 }
355 
IsCharProfileExist(const CharacteristicProfile & charProfile)356 bool ProfileCache::IsCharProfileExist(const CharacteristicProfile& charProfile)
357 {
358     if (!ProfileUtils::IsKeyValid(charProfile.GetDeviceId()) ||
359         !ProfileUtils::IsKeyValid(charProfile.GetServiceName()) ||
360         !ProfileUtils::IsKeyValid(charProfile.GetCharacteristicKey())) {
361         HILOGE("Params is invalid!");
362         return false;
363     }
364     std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(charProfile.GetDeviceId(),
365         charProfile.GetServiceName(), charProfile.GetCharacteristicKey());
366     {
367         std::lock_guard<std::mutex> lock(charProfileMutex_);
368         if (charProfileMap_.find(charProfileKey) == charProfileMap_.end()) {
369             HILOGI("ProfileKey is not found in charProfileMap!");
370             return false;
371         }
372         CharacteristicProfile charProfileCache = charProfileMap_[charProfileKey];
373         if (charProfile != charProfileCache) {
374             HILOGI("The char profile is not same in cache!");
375             return false;
376         }
377     }
378     return true;
379 }
380 
RefreshProfileCache()381 int32_t ProfileCache::RefreshProfileCache()
382 {
383     int64_t beginTime = GetTickCount();
384     std::vector<CharacteristicProfile> charProfiles;
385     StaticProfileManager::GetInstance().GetAllCharacteristicProfile(charProfiles);
386     RefreshCharProfileCache(charProfiles);
387     int64_t endTime = GetTickCount();
388     HILOGI("spend %{public}" PRId64 " ms", endTime - beginTime);
389     return DP_SUCCESS;
390 }
391 
RefreshCharProfileCache(const std::vector<CharacteristicProfile> & characteristicProfiles)392 int32_t ProfileCache::RefreshCharProfileCache(const std::vector<CharacteristicProfile>& characteristicProfiles)
393 {
394     if (characteristicProfiles.empty() || characteristicProfiles.size() > MAX_DB_RECORD_SIZE) {
395         HILOGE("Params is invalid!");
396         return DP_INVALID_PARAMS;
397     }
398     {
399         std::lock_guard<std::mutex> lock(charProfileMutex_);
400         charProfileMap_.clear();
401         for (const auto& charProfile : characteristicProfiles) {
402             std::string profileKey = ProfileUtils::GenerateCharProfileKey(charProfile.GetDeviceId(),
403                 charProfile.GetServiceName(), charProfile.GetCharacteristicKey());
404             charProfileMap_[profileKey] = charProfile;
405         }
406     }
407     return DP_SUCCESS;
408 }
409 
RefreshStaticProfileCache(const std::unordered_map<std::string,CharacteristicProfile> & staticProfiles)410 int32_t ProfileCache::RefreshStaticProfileCache(const std::unordered_map<std::string, CharacteristicProfile>&
411     staticProfiles)
412 {
413     if (staticProfiles.empty() || staticProfiles.size() > MAX_DB_RECORD_SIZE) {
414         HILOGE("Params is invalid!");
415         return DP_INVALID_PARAMS;
416     }
417     {
418         std::lock_guard<std::mutex> lock(charProfileMutex_);
419         charProfileMap_.clear();
420         for (const auto& staticProfileItem : staticProfiles) {
421             HILOGD("profile: %{public}s!", staticProfileItem.second.dump().c_str());
422             charProfileMap_[staticProfileItem.first] = staticProfileItem.second;
423         }
424     }
425     return DP_SUCCESS;
426 }
427 
AddSyncListener(const std::string & caller,sptr<IRemoteObject> syncListener)428 int32_t ProfileCache::AddSyncListener(const std::string& caller, sptr<IRemoteObject> syncListener)
429 {
430     if (caller.empty() || caller.size() > MAX_STRING_LEN || syncListener == nullptr) {
431         HILOGE("params is invalid!");
432         return DP_INVALID_PARAMS;
433     }
434     {
435         std::lock_guard<std::mutex> lock(syncListenerMutex_);
436         if (syncListenerMap_.size() > MAX_LISTENER_SIZE) {
437             HILOGE("syncListenerMap is exceed max listenerSize!");
438             return DP_EXCEED_MAX_SIZE_FAIL;
439         }
440         HILOGI("caller %{public}s!", caller.c_str());
441         syncListener->AddDeathRecipient(syncListenerDeathRecipient_);
442         syncListenerMap_[caller] = syncListener;
443     }
444     return DP_SUCCESS;
445 }
446 
GetSyncListeners(std::map<std::string,sptr<IRemoteObject>> & syncListeners)447 int32_t ProfileCache::GetSyncListeners(std::map<std::string, sptr<IRemoteObject>>& syncListeners)
448 {
449     HILOGD("call!");
450     {
451         std::lock_guard<std::mutex> lock(syncListenerMutex_);
452         for (const auto& item : syncListenerMap_) {
453             syncListeners[item.first] = item.second;
454         }
455     }
456     return DP_SUCCESS;
457 }
458 
RemoveSyncListeners(std::map<std::string,sptr<IRemoteObject>> syncListeners)459 int32_t ProfileCache::RemoveSyncListeners(std::map<std::string, sptr<IRemoteObject>> syncListeners)
460 {
461     HILOGD("call!");
462     {
463         std::lock_guard<std::mutex> lock(syncListenerMutex_);
464         auto iter = syncListenerMap_.begin();
465         while (iter!= syncListenerMap_.end()) {
466             if (syncListeners.count(iter->first) != 0) {
467                 if (iter->second != nullptr) {
468                     iter->second->RemoveDeathRecipient(syncListenerDeathRecipient_);
469                 }
470                 HILOGI("caller %{public}s!", iter->first.c_str());
471                 iter = syncListenerMap_.erase(iter);
472             } else {
473                 iter++;
474             }
475         }
476     }
477     return DP_SUCCESS;
478 }
479 
RemoveSyncListener(const std::string & caller)480 int32_t ProfileCache::RemoveSyncListener(const std::string& caller)
481 {
482     HILOGD("call!");
483     if (caller.empty() || caller.size() > MAX_STRING_LEN) {
484         HILOGE("descriptor is invalid!");
485         return DP_INVALID_PARAMS;
486     }
487     {
488         std::lock_guard<std::mutex> lock(syncListenerMutex_);
489         if (syncListenerMap_.count(caller) == 0) {
490             HILOGE("Can not find this listener!");
491             return DP_NOT_FOUND_FAIL;
492         }
493         HILOGI("caller %{public}s!", caller.c_str());
494         if (syncListenerMap_[caller] == nullptr) {
495             HILOGE("this caller syncListener is nullptr, caller : %{public}s", caller.c_str());
496             return DP_NULLPTR;
497         }
498         syncListenerMap_[caller]->RemoveDeathRecipient(syncListenerDeathRecipient_);
499         syncListenerMap_.erase(caller);
500     }
501     return DP_SUCCESS;
502 }
503 
RemoveSyncListener(sptr<IRemoteObject> syncListener)504 int32_t ProfileCache::RemoveSyncListener(sptr<IRemoteObject> syncListener)
505 {
506     HILOGD("call!");
507     if (syncListener == nullptr) {
508         HILOGE("syncListener is nullptr!");
509         return DP_INVALID_PARAMS;
510     }
511     {
512         std::lock_guard<std::mutex> lock(syncListenerMutex_);
513         auto iter = std::find_if(syncListenerMap_.begin(), syncListenerMap_.end(), [=](
514             const std::pair<std::string, sptr<IRemoteObject>>& item)->bool {
515             return item.second == syncListener;
516         });
517         if (iter == syncListenerMap_.end()) {
518             HILOGE("syncListener is not exist!");
519             return DP_NOT_FOUND_FAIL;
520         }
521         HILOGI("remote procName = %{public}s", iter->first.c_str());
522         if (iter->second != nullptr) {
523             iter->second->RemoveDeathRecipient(syncListenerDeathRecipient_);
524         }
525         syncListenerMap_.erase(iter);
526     }
527     return DP_SUCCESS;
528 }
529 
GetSwitch()530 uint32_t ProfileCache::GetSwitch()
531 {
532     HILOGD("call!");
533     std::lock_guard<std::mutex> lock(switchMutex_);
534     return curLocalSwitch_;
535 }
536 
SetSwitchByProfileBatch(const std::vector<CharacteristicProfile> & charProfiles,const std::unordered_map<std::string,SwitchFlag> & switchServiceMap,uint32_t & outSwitch)537 int32_t ProfileCache::SetSwitchByProfileBatch(const std::vector<CharacteristicProfile>& charProfiles,
538     const std::unordered_map<std::string, SwitchFlag>& switchServiceMap, uint32_t& outSwitch)
539 {
540     HILOGD("call!");
541     if (charProfiles.empty()) {
542         HILOGE("charProfiles is empty");
543         return DP_INVALID_PARAMS;
544     }
545     std::lock_guard<std::mutex> lock(switchMutex_);
546     outSwitch = curLocalSwitch_;
547     for (auto item : charProfiles) {
548         if (!IsSwitchValid(item, switchServiceMap, SWITCH_OPERATE_PUT)) {
549             HILOGE("SetSwitchByProfileBatch params invalid");
550             return DP_INVALID_PARAMS;
551         }
552         auto service = switchServiceMap.find(item.GetServiceName());
553         uint32_t mask = NUM_1U << (static_cast<uint32_t>(service->second));
554         uint32_t value = static_cast<uint32_t>(std::stoi(item.GetCharacteristicValue()));
555         if (value != 0) {
556             outSwitch |= mask;
557             HILOGI("service: %{public}s, switch on, currentSwitch: %{public}d",
558                 ProfileUtils::GetAnonyString(item.GetServiceName()).c_str(), outSwitch);
559         } else {
560             outSwitch &= ~mask;
561             HILOGI("service: %{public}s, switch off, currentSwitch: %{public}d",
562                 ProfileUtils::GetAnonyString(item.GetServiceName()).c_str(), outSwitch);
563         }
564     }
565     return DP_SUCCESS;
566 }
567 
SetSwitchByProfile(const CharacteristicProfile & charProfile,const std::unordered_map<std::string,SwitchFlag> & switchServiceMap,uint32_t & outSwitch)568 int32_t ProfileCache::SetSwitchByProfile(const CharacteristicProfile& charProfile,
569     const std::unordered_map<std::string, SwitchFlag>& switchServiceMap, uint32_t& outSwitch)
570 {
571     HILOGD("call!");
572     if (!IsSwitchValid(charProfile, switchServiceMap, SWITCH_OPERATE_PUT)) {
573         HILOGE("SetSwitch params invalid");
574         return DP_INVALID_PARAMS;
575     }
576     auto service = switchServiceMap.find(charProfile.GetServiceName());
577     uint32_t mask = NUM_1U << (static_cast<uint32_t>(service->second));
578     uint32_t value = static_cast<uint32_t>(std::stoi(charProfile.GetCharacteristicValue()));
579     if (value != 0) {
580         outSwitch |= mask;
581         HILOGI("SetSwitch service: %{public}s, switch on, currentSwitch: %{public}d",
582             ProfileUtils::GetAnonyString(charProfile.GetServiceName()).c_str(), outSwitch);
583     } else {
584         outSwitch &= ~mask;
585         HILOGI("SetSwitch service: %{public}s, switch off, currentSwitch: %{public}d",
586             ProfileUtils::GetAnonyString(charProfile.GetServiceName()).c_str(), outSwitch);
587     }
588     return DP_SUCCESS;
589 }
590 
IsSwitchValid(const CharacteristicProfile & charProfile,const std::unordered_map<std::string,SwitchFlag> & switchServiceMap,const std::string & operate)591 bool ProfileCache::IsSwitchValid(const CharacteristicProfile& charProfile,
592     const std::unordered_map<std::string, SwitchFlag>& switchServiceMap, const std::string& operate)
593 {
594     HILOGD("call!");
595     if (charProfile.GetCharacteristicKey() != SWITCH_STATUS || switchServiceMap.empty()) {
596         HILOGE("params invalid");
597         return false;
598     }
599     //Verify and intercept the input switch key and value.
600     if (operate == SWITCH_OPERATE_PUT) {
601         if (charProfile.GetCharacteristicValue().empty() ||
602             (charProfile.GetCharacteristicValue() != SWITCH_OFF &&
603                 charProfile.GetCharacteristicValue() != SWITCH_ON)) {
604             HILOGE("params invalid");
605             return false;
606         }
607     }
608     if (switchServiceMap.find(charProfile.GetServiceName()) == switchServiceMap.end()) {
609         HILOGE("can not find switchServiceName : %{public}s", charProfile.GetServiceName().c_str());
610         return false;
611     }
612     return true;
613 }
614 
SetSwitchProfile(CharacteristicProfile & charProfile,uint32_t switchValue)615 int32_t ProfileCache::SetSwitchProfile(CharacteristicProfile& charProfile, uint32_t switchValue)
616 {
617     HILOGD("call!");
618     if (!IsSwitchValid(charProfile, SWITCH_SERVICE_MAP, SWITCH_OPERATE_GET)) {
619         HILOGE("SetSwitchProfile params invalid");
620         return DP_INVALID_PARAMS;
621     }
622     auto service = SWITCH_SERVICE_MAP.find(charProfile.GetServiceName());
623     uint32_t mask = NUM_1U << static_cast<int32_t>(service->second);
624     charProfile.SetCharacteristicValue(std::to_string((((switchValue & mask) >>
625         (static_cast<int32_t>(service->second))))));
626     if (charProfile.GetDeviceId() == GetLocalUdid()) {
627         std::lock_guard<std::mutex> lock(switchMutex_);
628         curLocalSwitch_ = switchValue;
629     }
630     return DP_SUCCESS;
631 }
632 
SetCurSwitch(uint32_t newSwitch)633 void ProfileCache::SetCurSwitch(uint32_t newSwitch)
634 {
635     std::lock_guard<std::mutex> lock(switchMutex_);
636     curLocalSwitch_ = newSwitch;
637     return;
638 }
639 
OnNodeOnline(const std::string & peerNetworkId)640 void ProfileCache::OnNodeOnline(const std::string& peerNetworkId)
641 {
642     HILOGD("call! peerNetworkId=%{public}s", ProfileUtils::GetAnonyString(peerNetworkId).c_str());
643     std::string udid = EMPTY_STRING;
644     if (!ProfileUtils::GetUdidByNetworkId(peerNetworkId, udid)) {
645         HILOGE("get udid by networkId failed");
646         return;
647     }
648     {
649         std::lock_guard<std::mutex> lock(onlineDeviceLock_);
650         onlineDevMap_[udid] = peerNetworkId;
651         HILOGI("add %{public}s", ProfileUtils::GetAnonyString(udid).c_str());
652     }
653 }
654 
OnNodeOffline(const std::string & peerNetworkId)655 void ProfileCache::OnNodeOffline(const std::string& peerNetworkId)
656 {
657     HILOGD("call! peerNetworkId=%{public}s", ProfileUtils::GetAnonyString(peerNetworkId).c_str());
658     std::string udid = EMPTY_STRING;
659     if (!ProfileUtils::GetUdidByNetworkId(peerNetworkId, udid)) {
660         HILOGE("get udid by networkId failed");
661         return;
662     }
663     {
664         std::lock_guard<std::mutex> lock(onlineDeviceLock_);
665         onlineDevMap_.erase(udid);
666         HILOGI("release %{public}s", ProfileUtils::GetAnonyString(udid).c_str());
667     }
668 }
669 
IsLocalOrOnlineDevice(const std::string & deviceId)670 bool ProfileCache::IsLocalOrOnlineDevice(const std::string& deviceId)
671 {
672     if (deviceId == GetLocalUdid()) {
673         HILOGI("%{public}s is localDevice", ProfileUtils::GetAnonyString(deviceId).c_str());
674         return true;
675     }
676     std::lock_guard<std::mutex> lock(onlineDeviceLock_);
677     if (onlineDevMap_.find(deviceId) != onlineDevMap_.end()) {
678         HILOGI("%{public}s is online", ProfileUtils::GetAnonyString(deviceId).c_str());
679         return true;
680     }
681     HILOGE("%{public}s is offline or is not a local device.", ProfileUtils::GetAnonyString(deviceId).c_str());
682     return false;
683 }
684 
GetNetWorkIdByUdid(const std::string & udid,std::string & networkId)685 int32_t ProfileCache::GetNetWorkIdByUdid(const std::string& udid, std::string& networkId)
686 {
687     HILOGD("call!");
688     if (udid.empty()) {
689         HILOGE("UDID is empty");
690         return DP_INVALID_PARAMS;
691     }
692 
693     if (udid == GetLocalUdid()) {
694         networkId = GetLocalNetworkId();
695         HILOGI("success, networkId is localNetworkid: %{public}s",
696             ProfileUtils::GetAnonyString(networkId).c_str());
697         return DP_SUCCESS;
698     }
699     std::lock_guard<std::mutex> lock(onlineDeviceLock_);
700     if (onlineDevMap_.find(udid) == onlineDevMap_.end()) {
701         HILOGE("GetNetWorkIdByUdid failed");
702         return DP_GET_NETWORKID_BY_UDID_FAIL;
703     }
704     networkId = onlineDevMap_[udid];
705     HILOGI("success, networkId: %{public}s", ProfileUtils::GetAnonyString(networkId).c_str());
706     return DP_SUCCESS;
707 }
708 
GetUdidByNetWorkId(const std::string & networkId,std::string & udid)709 int32_t ProfileCache::GetUdidByNetWorkId(const std::string& networkId, std::string& udid)
710 {
711     if (networkId.empty()) {
712         HILOGE("networkId is empty");
713         return DP_INVALID_PARAMS;
714     }
715     if (GetLocalNetworkId() == networkId) {
716         udid = GetLocalUdid();
717         HILOGD("networkId is local");
718         return DP_SUCCESS;
719     }
720     std::lock_guard<std::mutex> lock(onlineDeviceLock_);
721     for (auto& item : onlineDevMap_) {
722         if (item.second == networkId) {
723             udid = item.first;
724             HILOGI("find udid: %{public}s", ProfileUtils::GetAnonyString(udid).c_str());
725             return DP_SUCCESS;
726         }
727     }
728     if (!ProfileUtils::GetUdidByNetworkId(networkId, udid)) {
729         HILOGE("GetUdidByNetworkId failed");
730         return DP_GET_UDID_BY_NETWORKID_FAIL;
731     }
732     onlineDevMap_[udid] = networkId;
733     return DP_SUCCESS;
734 }
735 
GetServiceNameByPos(int32_t pos,const std::unordered_map<std::string,SwitchFlag> & switchServiceMap,std::string & serviceName)736 int32_t ProfileCache::GetServiceNameByPos(int32_t pos,
737     const std::unordered_map<std::string, SwitchFlag>& switchServiceMap, std::string& serviceName)
738 {
739     if (pos <= (int32_t)SwitchFlag::SWITCH_FLAG_MIN || pos >= (int32_t)SwitchFlag::SWITCH_FLAG_MAX ||
740         switchServiceMap.empty()) {
741         HILOGE("params are invalid");
742         return DP_INVALID_PARAMS;
743     }
744     for (const auto& item : switchServiceMap) {
745         if (item.second == (SwitchFlag)pos) {
746             serviceName = item.first;
747             HILOGI("find serviceName: %{public}s", serviceName.c_str());
748             return DP_SUCCESS;
749         }
750     }
751     HILOGE("GetServiceNameByPos failed");
752     return DP_GET_SERVICENAME_BY_POS_FAIL;
753 }
754 
GetSwitchProfilesByServiceName(const std::string & charProfileKey,CharacteristicProfile & switchProfile)755 int32_t ProfileCache::GetSwitchProfilesByServiceName(const std::string& charProfileKey,
756     CharacteristicProfile& switchProfile)
757 {
758     if (charProfileKey.empty()) {
759         HILOGE("params are invalid");
760         return DP_INVALID_PARAMS;
761     }
762 
763     std::lock_guard<std::mutex> lock(charProfileMutex_);
764     if (charProfileMap_.find(charProfileKey) == charProfileMap_.end()) {
765         HILOGW("ProfileKey is not found in charProfileMap!");
766     }
767 
768     switchProfile = charProfileMap_[charProfileKey];
769     return DP_SUCCESS;
770 }
771 
IsCharProfileKeyExist(const std::string & charKey)772 bool ProfileCache::IsCharProfileKeyExist(const std::string& charKey)
773 {
774     if (charKey.empty()) {
775         HILOGE("Params is invalid!");
776         return false;
777     }
778     {
779         std::lock_guard<std::mutex> lock(charProfileMutex_);
780         if (charProfileMap_.find(charKey) == charProfileMap_.end()) {
781             HILOGI("charKey is not found in charProfileMap!");
782             return false;
783         }
784     }
785     return true;
786 }
787 
GetLocalUdid()788 std::string ProfileCache::GetLocalUdid()
789 {
790     return ContentSensorManagerUtils::GetInstance().ObtainLocalUdid();
791 }
792 
GetLocalNetworkId()793 std::string ProfileCache::GetLocalNetworkId()
794 {
795     DistributedHardware::DmDeviceInfo localDevInfo;
796     int32_t res = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(DP_PKG_NAME, localDevInfo);
797     if (res != DP_SUCCESS) {
798         HILOGE("GetLocalDeviceInfo fail, res: %{public}d.", res);
799         return EMPTY_STRING;
800     }
801     localNetworkId_ = localDevInfo.networkId;
802     return localNetworkId_;
803 }
804 
GetLocalUuid()805 std::string ProfileCache::GetLocalUuid()
806 {
807     std::string localUuid = EMPTY_STRING;
808     std::lock_guard<std::mutex> lock(localUuidMtx_);
809     if (!localUuid_.empty()) {
810         return localUuid_;
811     }
812     auto networkId = GetLocalNetworkId();
813     if (networkId.empty()) {
814         HILOGE("networkId is empty");
815         return EMPTY_STRING;
816     }
817     if (!ProfileUtils::GetUuidByNetworkId(networkId, localUuid) || localUuid.empty()) {
818         HILOGE("GetUuidByNetworkId fail");
819         return EMPTY_STRING;
820     }
821     localUuid_ = localUuid;
822     return localUuid;
823 }
824 } // namespace DeviceProfile
825 } // namespace OHOS
826