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