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 "subscribe_profile_manager.h"
17 
18 #include "distributed_device_profile_errors.h"
19 #include "dp_radar_helper.h"
20 #include "profile_utils.h"
21 #include "profile_cache.h"
22 
23 namespace OHOS {
24 namespace DistributedDeviceProfile {
25 IMPLEMENT_SINGLE_INSTANCE(SubscribeProfileManager);
26 namespace {
27     const std::string TAG = "SubscribeProfileManager";
28 }
29 
Init()30 int32_t SubscribeProfileManager::Init()
31 {
32     HILOGI("call!");
33     {
34         std::lock_guard<std::mutex> lockGuard(funcsMutex_);
35         funcsMap_[ProfileType::DEVICE_PROFILE * ChangeType::ADD] =
36             &SubscribeProfileManager::NotifyDeviceProfileAdd;
37         funcsMap_[ProfileType::DEVICE_PROFILE * ChangeType::UPDATE] =
38             &SubscribeProfileManager::NotifyDeviceProfileUpdate;
39         funcsMap_[ProfileType::DEVICE_PROFILE * ChangeType::DELETE] =
40             &SubscribeProfileManager::NotifyDeviceProfileDelete;
41         funcsMap_[ProfileType::SERVICE_PROFILE * ChangeType::ADD] =
42             &SubscribeProfileManager::NotifyServiceProfileAdd;
43         funcsMap_[ProfileType::SERVICE_PROFILE * ChangeType::UPDATE] =
44             &SubscribeProfileManager::NotifyServiceProfileUpdate;
45         funcsMap_[ProfileType::SERVICE_PROFILE * ChangeType::DELETE] =
46             &SubscribeProfileManager::NotifyServiceProfileDelete;
47         funcsMap_[ProfileType::CHAR_PROFILE * ChangeType::ADD] =
48             &SubscribeProfileManager::NotifyCharProfileAdd;
49         funcsMap_[ProfileType::CHAR_PROFILE * ChangeType::UPDATE] =
50             &SubscribeProfileManager::NotifyCharProfileUpdate;
51         funcsMap_[ProfileType::CHAR_PROFILE * ChangeType::DELETE] =
52             &SubscribeProfileManager::NotifyCharProfileDelete;
53     }
54     return DP_SUCCESS;
55 }
56 
UnInit()57 int32_t SubscribeProfileManager::UnInit()
58 {
59     HILOGI("call!");
60     {
61         std::lock_guard<std::mutex> lockGuard(subscribeMutex_);
62         subscribeInfoMap_.clear();
63     }
64     {
65         std::lock_guard<std::mutex> lockGuard(funcsMutex_);
66         funcsMap_.clear();
67     }
68     return DP_SUCCESS;
69 }
70 
NotifyProfileChange(ProfileType profileType,ChangeType changeType,const std::string & dbKey,const std::string & dbValue)71 int32_t SubscribeProfileManager::NotifyProfileChange(ProfileType profileType, ChangeType changeType,
72     const std::string& dbKey, const std::string& dbValue)
73 {
74     int32_t code = static_cast<int32_t>(profileType) * static_cast<int32_t>(changeType);
75     DpRadarHelper::GetInstance().ReportNotifyProfileChange(code);
76     switch (code) {
77         case ProfileType::DEVICE_PROFILE * ChangeType::ADD:
78             return SubscribeProfileManager::NotifyDeviceProfileAdd(dbKey, dbValue);
79         case ProfileType::DEVICE_PROFILE * ChangeType::UPDATE:
80             return SubscribeProfileManager::NotifyDeviceProfileUpdate(dbKey, dbValue);
81         case ProfileType::DEVICE_PROFILE * ChangeType::DELETE:
82             return SubscribeProfileManager::NotifyDeviceProfileDelete(dbKey, dbValue);
83         case ProfileType::SERVICE_PROFILE * ChangeType::ADD:
84             return SubscribeProfileManager::NotifyServiceProfileAdd(dbKey, dbValue);
85         case ProfileType::SERVICE_PROFILE * ChangeType::UPDATE:
86             return SubscribeProfileManager::NotifyServiceProfileUpdate(dbKey, dbValue);
87         case ProfileType::SERVICE_PROFILE * ChangeType::DELETE:
88             return SubscribeProfileManager::NotifyServiceProfileDelete(dbKey, dbValue);
89         case ProfileType::CHAR_PROFILE * ChangeType::ADD:
90             return SubscribeProfileManager::NotifyCharProfileAdd(dbKey, dbValue);
91         case ProfileType::CHAR_PROFILE * ChangeType::UPDATE:
92             return SubscribeProfileManager::NotifyCharProfileUpdate(dbKey, dbValue);
93         case ProfileType::CHAR_PROFILE * ChangeType::DELETE:
94             return SubscribeProfileManager::NotifyCharProfileDelete(dbKey, dbValue);
95         default:
96             HILOGE("Params is invalid!, code = %{public}u", code);
97             return DP_INVALID_PARAMS;
98     }
99 }
100 
NotifyTrustDeviceProfileAdd(const TrustDeviceProfile & trustDeviceProfile)101 int32_t SubscribeProfileManager::NotifyTrustDeviceProfileAdd(const TrustDeviceProfile& trustDeviceProfile)
102 {
103     auto subscriberInfos = GetSubscribeInfos(SUBSCRIBE_TRUST_DEVICE_PROFILE);
104     if (subscriberInfos.empty()) {
105         return DP_SUCCESS;
106     }
107     HILOGI("%{public}s!", trustDeviceProfile.dump().c_str());
108     for (const auto& subscriberInfo : subscriberInfos) {
109         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
110         if (listenerProxy == nullptr) {
111             HILOGE("Cast to IProfileChangeListener failed!");
112             continue;
113         }
114         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::TRUST_DEVICE_PROFILE_ADD) != 0) {
115             listenerProxy->OnTrustDeviceProfileAdd(trustDeviceProfile);
116         }
117     }
118     return DP_SUCCESS;
119 }
120 
NotifyTrustDeviceProfileUpdate(const TrustDeviceProfile & oldDeviceProfile,const TrustDeviceProfile & newDeviceProfile)121 int32_t SubscribeProfileManager::NotifyTrustDeviceProfileUpdate(const TrustDeviceProfile& oldDeviceProfile,
122     const TrustDeviceProfile& newDeviceProfile)
123 {
124     auto subscriberInfos = GetSubscribeInfos(SUBSCRIBE_TRUST_DEVICE_PROFILE);
125     if (subscriberInfos.empty()) {
126         return DP_SUCCESS;
127     }
128     HILOGI("%{public}s!", newDeviceProfile.dump().c_str());
129     for (const auto& subscriberInfo : subscriberInfos) {
130         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
131         if (listenerProxy == nullptr) {
132             HILOGE("Cast to IProfileChangeListener failed!");
133             continue;
134         }
135         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::TRUST_DEVICE_PROFILE_UPDATE) != 0) {
136             listenerProxy->OnTrustDeviceProfileUpdate(oldDeviceProfile, newDeviceProfile);
137         }
138     }
139     return DP_SUCCESS;
140 }
141 
NotifyTrustDeviceProfileDelete(const TrustDeviceProfile & trustDeviceProfile)142 int32_t SubscribeProfileManager::NotifyTrustDeviceProfileDelete(const TrustDeviceProfile& trustDeviceProfile)
143 {
144     auto subscriberInfos = GetSubscribeInfos(SUBSCRIBE_TRUST_DEVICE_PROFILE);
145     if (subscriberInfos.empty()) {
146         return DP_SUCCESS;
147     }
148     HILOGI("%{public}s!", trustDeviceProfile.dump().c_str());
149     for (const auto& subscriberInfo : subscriberInfos) {
150         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
151         if (listenerProxy == nullptr) {
152             HILOGE("Cast to IProfileChangeListener failed!");
153             continue;
154         }
155         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::TRUST_DEVICE_PROFILE_DELETE) != 0) {
156             listenerProxy->OnTrustDeviceProfileDelete(trustDeviceProfile);
157         }
158     }
159     return DP_SUCCESS;
160 }
161 
SubscribeDeviceProfile(const SubscribeInfo & subscribeInfo)162 int32_t SubscribeProfileManager::SubscribeDeviceProfile(const SubscribeInfo& subscribeInfo)
163 {
164     HILOGI("saId: %{public}d!, subscribeKey: %{public}s", subscribeInfo.GetSaId(),
165         ProfileUtils::GetDbKeyAnonyString(subscribeInfo.GetSubscribeKey()).c_str());
166     {
167         std::lock_guard<std::mutex> lock(subscribeMutex_);
168         if (subscribeInfoMap_.size() > MAX_LISTENER_SIZE) {
169             HILOGE("SubscribeInfoMap size is invalid!size: %{public}zu!", subscribeInfoMap_.size());
170             return DP_EXCEED_MAX_SIZE_FAIL;
171         }
172         if (subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].size() > MAX_LISTENER_SIZE) {
173             HILOGE("SubscribeInfoMap size is invalid!size: %{public}zu!",
174                 subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].size());
175             return DP_EXCEED_MAX_SIZE_FAIL;
176         }
177         if (subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].find(subscribeInfo) !=
178             subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].end()) {
179             HILOGI("this sa subscribeInfo is exist, saId : %{public}d", subscribeInfo.GetSaId());
180             subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].erase(subscribeInfo);
181         }
182         subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].emplace(subscribeInfo);
183     }
184     return DP_SUCCESS;
185 }
186 
SubscribeDeviceProfile(std::map<std::string,SubscribeInfo> subscribeInfos)187 int32_t SubscribeProfileManager::SubscribeDeviceProfile(std::map<std::string, SubscribeInfo> subscribeInfos)
188 {
189     HILOGD("call!");
190     for (auto item : subscribeInfos) {
191         SubscribeDeviceProfile(item.second);
192     }
193     return DP_SUCCESS;
194 }
195 
UnSubscribeDeviceProfile(const SubscribeInfo & subscribeInfo)196 int32_t SubscribeProfileManager::UnSubscribeDeviceProfile(const SubscribeInfo& subscribeInfo)
197 {
198     HILOGI("saId: %{public}d!, subscribeKey: %{public}s", subscribeInfo.GetSaId(),
199         ProfileUtils::GetDbKeyAnonyString(subscribeInfo.GetSubscribeKey()).c_str());
200     {
201         std::lock_guard<std::mutex> lock(subscribeMutex_);
202         subscribeInfoMap_[subscribeInfo.GetSubscribeKey()].erase(subscribeInfo);
203     }
204     return DP_SUCCESS;
205 }
206 
NotifyDeviceProfileAdd(const std::string & dbKey,const std::string & dbValue)207 int32_t SubscribeProfileManager::NotifyDeviceProfileAdd(const std::string& dbKey, const std::string& dbValue)
208 {
209     std::map<std::string, std::string> values;
210     values[dbKey] = dbValue;
211     DeviceProfile deviceProfile;
212     deviceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
213     ProfileUtils::EntriesToDeviceProfile(values, deviceProfile);
214     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
215     if (subscriberInfos.empty()) {
216         return DP_SUCCESS;
217     }
218     HILOGI("%{public}s!", deviceProfile.AnnoymizeDump().c_str());
219     for (const auto& subscriberInfo : subscriberInfos) {
220         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
221         if (listenerProxy == nullptr) {
222             HILOGE("Cast to IProfileChangeListener failed!");
223             continue;
224         }
225         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::DEVICE_PROFILE_ADD) != 0) {
226             listenerProxy->OnDeviceProfileAdd(deviceProfile);
227         }
228     }
229     return DP_SUCCESS;
230 }
231 
NotifyDeviceProfileUpdate(const std::string & dbKey,const std::string & dbValue)232 int32_t SubscribeProfileManager::NotifyDeviceProfileUpdate(const std::string& dbKey, const std::string& dbValue)
233 {
234     std::map<std::string, std::string> values;
235     values[dbKey] = dbValue;
236     DeviceProfile newDeviceProfile;
237     newDeviceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
238     ProfileUtils::EntriesToDeviceProfile(values, newDeviceProfile);
239     DeviceProfile oldDeviceProfile;
240     ProfileCache::GetInstance().GetDeviceProfile(ProfileUtils::GetDeviceIdByDBKey(dbKey), oldDeviceProfile);
241     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
242     if (subscriberInfos.empty()) {
243         return DP_SUCCESS;
244     }
245     HILOGI("%{public}s!", newDeviceProfile.AnnoymizeDump().c_str());
246     for (const auto& subscriberInfo : subscriberInfos) {
247         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
248         if (listenerProxy == nullptr) {
249             HILOGE("Cast to IProfileChangeListener failed!");
250             continue;
251         }
252         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::DEVICE_PROFILE_UPDATE) != 0) {
253             listenerProxy->OnDeviceProfileUpdate(oldDeviceProfile, newDeviceProfile);
254         }
255     }
256     return DP_SUCCESS;
257 }
258 
NotifyDeviceProfileDelete(const std::string & dbKey,const std::string & dbValue)259 int32_t SubscribeProfileManager::NotifyDeviceProfileDelete(const std::string& dbKey, const std::string& dbValue)
260 {
261     std::map<std::string, std::string> values;
262     values[dbKey] = dbValue;
263     DeviceProfile deviceProfile;
264     deviceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
265     ProfileUtils::EntriesToDeviceProfile(values, deviceProfile);
266     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
267     if (subscriberInfos.empty()) {
268         return DP_SUCCESS;
269     }
270     HILOGI("%{public}s!", deviceProfile.AnnoymizeDump().c_str());
271     for (const auto& subscriberInfo : subscriberInfos) {
272         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
273         if (listenerProxy == nullptr) {
274             HILOGE("Cast to IProfileChangeListener failed!");
275             continue;
276         }
277         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::DEVICE_PROFILE_DELETE) != 0) {
278             listenerProxy->OnDeviceProfileDelete(deviceProfile);
279         }
280     }
281     return DP_SUCCESS;
282 }
283 
NotifyServiceProfileAdd(const std::string & dbKey,const std::string & dbValue)284 int32_t SubscribeProfileManager::NotifyServiceProfileAdd(const std::string& dbKey, const std::string& dbValue)
285 {
286     std::map<std::string, std::string> values;
287     values[dbKey] = dbValue;
288     ServiceProfile serviceProfile;
289     serviceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
290     serviceProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
291     ProfileUtils::EntriesToServiceProfile(values, serviceProfile);
292     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
293     if (subscriberInfos.empty()) {
294         return DP_SUCCESS;
295     }
296     HILOGI("%{public}s!", serviceProfile.dump().c_str());
297     for (const auto& subscriberInfo : subscriberInfos) {
298         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
299         if (listenerProxy == nullptr) {
300             HILOGE("Cast to IProfileChangeListener failed!");
301             continue;
302         }
303         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::SERVICE_PROFILE_ADD) != 0) {
304             listenerProxy->OnServiceProfileAdd(serviceProfile);
305         }
306     }
307     return DP_SUCCESS;
308 }
309 
NotifyServiceProfileUpdate(const std::string & dbKey,const std::string & dbValue)310 int32_t SubscribeProfileManager::NotifyServiceProfileUpdate(const std::string& dbKey, const std::string& dbValue)
311 {
312     std::map<std::string, std::string> values;
313     values[dbKey] = dbValue;
314     ServiceProfile newServiceProfile;
315     newServiceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
316     newServiceProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
317     ProfileUtils::EntriesToServiceProfile(values, newServiceProfile);
318     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
319     if (subscriberInfos.empty()) {
320         return DP_SUCCESS;
321     }
322     HILOGI("%{public}s!", newServiceProfile.dump().c_str());
323     ServiceProfile oldServiceProfile;
324     ProfileCache::GetInstance().GetServiceProfile(ProfileUtils::GetDeviceIdByDBKey(dbKey),
325         ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey), oldServiceProfile);
326     for (const auto& subscriberInfo : subscriberInfos) {
327         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
328         if (listenerProxy == nullptr) {
329             HILOGE("Cast to IProfileChangeListener failed!");
330             continue;
331         }
332         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::SERVICE_PROFILE_UPDATE) != 0) {
333             listenerProxy->OnServiceProfileUpdate(oldServiceProfile, newServiceProfile);
334         }
335     }
336     return DP_SUCCESS;
337 }
338 
NotifyServiceProfileDelete(const std::string & dbKey,const std::string & dbValue)339 int32_t SubscribeProfileManager::NotifyServiceProfileDelete(const std::string& dbKey, const std::string& dbValue)
340 {
341     std::map<std::string, std::string> values;
342     values[dbKey] = dbValue;
343     ServiceProfile serviceProfile;
344     serviceProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
345     serviceProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
346     ProfileUtils::EntriesToServiceProfile(values, serviceProfile);
347     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
348     if (subscriberInfos.empty()) {
349         return DP_SUCCESS;
350     }
351     HILOGI("%{public}s!", serviceProfile.dump().c_str());
352     for (const auto& subscriberInfo : subscriberInfos) {
353         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
354         if (listenerProxy == nullptr) {
355             HILOGE("Cast to IProfileChangeListener failed!");
356             continue;
357         }
358         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::SERVICE_PROFILE_DELETE) != 0) {
359             listenerProxy->OnServiceProfileDelete(serviceProfile);
360         }
361     }
362     return DP_SUCCESS;
363 }
364 
NotifyCharProfileAdd(const std::string & dbKey,const std::string & dbValue)365 int32_t SubscribeProfileManager::NotifyCharProfileAdd(const std::string& dbKey, const std::string& dbValue)
366 {
367     std::map<std::string, std::string> values;
368     values[dbKey] = dbValue;
369     CharacteristicProfile charProfile;
370     charProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
371     charProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
372     charProfile.SetCharacteristicKey(ProfileUtils::GetCharKeyByDBKey(dbKey));
373     ProfileUtils::EntriesToCharProfile(values, charProfile);
374     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
375     if (subscriberInfos.empty()) {
376         return DP_SUCCESS;
377     }
378     HILOGI("%{public}s!", charProfile.dump().c_str());
379     for (const auto& subscriberInfo : subscriberInfos) {
380         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
381         if (listenerProxy == nullptr) {
382             HILOGE("Cast to IProfileChangeListener failed!");
383             continue;
384         }
385         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::CHAR_PROFILE_ADD) != 0) {
386             listenerProxy->OnCharacteristicProfileAdd(charProfile);
387         }
388     }
389     return DP_SUCCESS;
390 }
391 
NotifyCharProfileUpdate(const std::string & dbKey,const std::string & dbValue)392 int32_t SubscribeProfileManager::NotifyCharProfileUpdate(const std::string& dbKey, const std::string& dbValue)
393 {
394     std::map<std::string, std::string> values;
395     values[dbKey] = dbValue;
396     CharacteristicProfile newCharProfile;
397     newCharProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
398     newCharProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
399     newCharProfile.SetCharacteristicKey(ProfileUtils::GetCharKeyByDBKey(dbKey));
400     ProfileUtils::EntriesToCharProfile(values, newCharProfile);
401     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
402     if (subscriberInfos.empty()) {
403         return DP_SUCCESS;
404     }
405     HILOGI("%{public}s!", newCharProfile.dump().c_str());
406     CharacteristicProfile oldCharProfile;
407     ProfileCache::GetInstance().GetCharacteristicProfile(ProfileUtils::GetDeviceIdByDBKey(dbKey),
408         ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey), ProfileUtils::GetCharKeyByDBKey(dbKey), oldCharProfile);
409     for (const auto& subscriberInfo : subscriberInfos) {
410         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
411         if (listenerProxy == nullptr) {
412             HILOGE("Cast to IProfileChangeListener failed!");
413             continue;
414         }
415         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::CHAR_PROFILE_UPDATE) != 0) {
416             listenerProxy->OnCharacteristicProfileUpdate(oldCharProfile, newCharProfile);
417         }
418     }
419     return DP_SUCCESS;
420 }
421 
NotifyCharProfileDelete(const std::string & dbKey,const std::string & dbValue)422 int32_t SubscribeProfileManager::NotifyCharProfileDelete(const std::string& dbKey, const std::string& dbValue)
423 {
424     std::map<std::string, std::string> values;
425     values[dbKey] = dbValue;
426     CharacteristicProfile charProfile;
427     charProfile.SetDeviceId(ProfileUtils::GetDeviceIdByDBKey(dbKey));
428     charProfile.SetServiceName(ProfileUtils::GetNonOhSuffixServiceNameByDBKey(dbKey));
429     charProfile.SetCharacteristicKey(ProfileUtils::GetCharKeyByDBKey(dbKey));
430     ProfileUtils::EntriesToCharProfile(values, charProfile);
431     auto subscriberInfos = GetSubscribeInfos(DBKeyToSubcribeKey(dbKey));
432     if (subscriberInfos.empty()) {
433         return DP_SUCCESS;
434     }
435     HILOGI("%{public}s!", charProfile.dump().c_str());
436     for (const auto& subscriberInfo : subscriberInfos) {
437         sptr<IProfileChangeListener> listenerProxy = iface_cast<IProfileChangeListener>(subscriberInfo.GetListener());
438         if (listenerProxy == nullptr) {
439             HILOGE("Cast to IProfileChangeListener failed!");
440             continue;
441         }
442         if (subscriberInfo.GetProfileChangeTypes().count(ProfileChangeType::CHAR_PROFILE_DELETE) != 0) {
443             listenerProxy->OnCharacteristicProfileDelete(charProfile);
444         }
445     }
446     return DP_SUCCESS;
447 }
GetSubscribeInfos(const std::string & dbKey)448 std::unordered_set<SubscribeInfo, SubscribeHash, SubscribeCompare> SubscribeProfileManager::GetSubscribeInfos(
449     const std::string& dbKey)
450 {
451     {
452         std::lock_guard<std::mutex> lock(subscribeMutex_);
453         if (subscribeInfoMap_.find(dbKey) == subscribeInfoMap_.end()) {
454             HILOGD("This dbKey is not subscribed, dbKey: %{public}s", ProfileUtils::GetDbKeyAnonyString(dbKey).c_str());
455             return {};
456         }
457         return subscribeInfoMap_[dbKey];
458     }
459 }
460 
DBKeyToSubcribeKey(const std::string & dbkey)461 std::string SubscribeProfileManager::DBKeyToSubcribeKey(const std::string& dbkey)
462 {
463     std::string subscribeKey = dbkey;
464     std::vector<std::string> res;
465     if (ProfileUtils::SplitString(subscribeKey, SEPARATOR, res) != DP_SUCCESS) {
466         return subscribeKey;
467     }
468     if (res.size() > NUM_2) {
469         res[NUM_2] = ProfileUtils::CheckAndRemoveOhSuffix(res[NUM_2]);
470         subscribeKey = ProfileUtils::JoinString(res, SEPARATOR);
471     }
472     return subscribeKey;
473 }
474 } // namespace DistributedDeviceProfile
475 } // namespace OHOS
476