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