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