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