• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <csignal>
17 #include <utility>
18 #include <vector>
19 #include <set>
20 
21 #include "ability_manager_client.h"
22 #include "common_event_subscriber_manager.h"
23 #include "event_log_wrapper.h"
24 #include "event_report.h"
25 #include "hisysevent.h"
26 #include "hitrace_meter_adapter.h"
27 #include "subscriber_death_recipient.h"
28 
29 namespace OHOS {
30 namespace EventFwk {
31 constexpr int32_t LENGTH = 80;
32 constexpr int32_t SIGNAL_KILL = 9;
33 static constexpr int32_t SUBSCRIBE_EVENT_MAX_NUM = 512;
34 static constexpr char CES_REGISTER_EXCEED_LIMIT[] = "Kill Reason: CES Register exceed limit";
35 
CommonEventSubscriberManager()36 CommonEventSubscriberManager::CommonEventSubscriberManager()
37     : death_(sptr<IRemoteObject::DeathRecipient>(new (std::nothrow) SubscriberDeathRecipient()))
38 {
39 }
40 
~CommonEventSubscriberManager()41 CommonEventSubscriberManager::~CommonEventSubscriberManager()
42 {
43     EVENT_LOGI("~CommonEventSubscriberManager");
44 }
45 
InsertSubscriber(const SubscribeInfoPtr & eventSubscribeInfo,const sptr<IRemoteObject> & commonEventListener,const struct tm & recordTime,const EventRecordInfo & eventRecordInfo)46 std::shared_ptr<EventSubscriberRecord> CommonEventSubscriberManager::InsertSubscriber(
47     const SubscribeInfoPtr &eventSubscribeInfo, const sptr<IRemoteObject> &commonEventListener,
48     const struct tm &recordTime, const EventRecordInfo &eventRecordInfo)
49 {
50     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
51     EVENT_LOGD("enter");
52 
53     if (eventSubscribeInfo == nullptr) {
54         EVENT_LOGE("eventSubscribeInfo is null");
55         return nullptr;
56     }
57 
58     if (commonEventListener == nullptr) {
59         EVENT_LOGE("commonEventListener is null");
60         return nullptr;
61     }
62 
63     std::vector<std::string> events = eventSubscribeInfo->GetMatchingSkills().GetEvents();
64     if (events.size() == 0 || events.size() > SUBSCRIBE_EVENT_MAX_NUM) {
65         EVENT_LOGE("subscribed events size is error");
66         return nullptr;
67     }
68 
69     auto record = std::make_shared<EventSubscriberRecord>();
70     if (record == nullptr) {
71         EVENT_LOGE("Failed to create EventSubscriberRecord");
72         return nullptr;
73     }
74 
75     record->eventSubscribeInfo = eventSubscribeInfo;
76     record->commonEventListener = commonEventListener;
77     record->recordTime = recordTime;
78     record->eventRecordInfo = eventRecordInfo;
79 
80     if (death_ != nullptr) {
81         commonEventListener->AddDeathRecipient(death_);
82     }
83 
84     if (!InsertSubscriberRecordLocked(events, record)) {
85         return nullptr;
86     }
87 
88     return record;
89 }
90 
RemoveSubscriber(const sptr<IRemoteObject> & commonEventListener)91 int CommonEventSubscriberManager::RemoveSubscriber(const sptr<IRemoteObject> &commonEventListener)
92 {
93     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
94     EVENT_LOGD("enter");
95 
96     if (commonEventListener == nullptr) {
97         EVENT_LOGE("commonEventListener is null");
98         return ERR_INVALID_VALUE;
99     }
100 
101     int res = RemoveSubscriberRecordLocked(commonEventListener);
102 
103     if (death_ != nullptr) {
104         commonEventListener->RemoveDeathRecipient(death_);
105     }
106     return res;
107 }
108 
GetSubscriberRecords(const CommonEventRecord & eventRecord)109 std::vector<std::shared_ptr<EventSubscriberRecord>> CommonEventSubscriberManager::GetSubscriberRecords(
110     const CommonEventRecord &eventRecord)
111 {
112     EVENT_LOGD("enter");
113 
114     auto records = std::vector<SubscriberRecordPtr>();
115 
116     GetSubscriberRecordsByWantLocked(eventRecord, records);
117 
118     return records;
119 }
120 
GetSubscriberRecord(const sptr<IRemoteObject> & commonEventListener)121 std::shared_ptr<EventSubscriberRecord> CommonEventSubscriberManager::GetSubscriberRecord(
122     const sptr<IRemoteObject> &commonEventListener)
123 {
124     std::lock_guard<std::mutex> lock(mutex_);
125 
126     for (auto it = subscribers_.begin(); it != subscribers_.end(); ++it) {
127         if (commonEventListener == (*it)->commonEventListener) {
128             return *it;
129         }
130     }
131 
132     return nullptr;
133 }
134 
DumpDetailed(const std::string & title,const SubscriberRecordPtr & record,const std::string format,std::string & dumpInfo)135 void CommonEventSubscriberManager::DumpDetailed(
136     const std::string &title, const SubscriberRecordPtr &record, const std::string format, std::string &dumpInfo)
137 {
138     if (record == nullptr || record->eventSubscribeInfo == nullptr) {
139         EVENT_LOGE("record or eventSubscribeInfo is null");
140         return;
141     }
142     char systime[LENGTH];
143     strftime(systime, sizeof(char) * LENGTH, "%Y%m%d %I:%M %p", &record->recordTime);
144 
145     std::string recordTime = format + "Time: " + std::string(systime) + "\n";
146     std::string pid = format + "PID: " + std::to_string(record->eventRecordInfo.pid) + "\n";
147     std::string uid = format + "UID: " + std::to_string(record->eventRecordInfo.uid) + "\n";
148     std::string bundleName = format + "BundleName: " + record->eventRecordInfo.bundleName + "\n";
149     std::string priority = format + "Priority: " + std::to_string(record->eventSubscribeInfo->GetPriority()) + "\n";
150     std::string userId;
151     switch (record->eventSubscribeInfo->GetUserId()) {
152         case UNDEFINED_USER:
153             userId = "UNDEFINED_USER";
154             break;
155         case ALL_USER:
156             userId = "ALL_USER";
157             break;
158         default:
159             userId = std::to_string(record->eventSubscribeInfo->GetUserId());
160             break;
161     }
162     userId = format + "USERID: " + userId + "\n";
163     std::string permission = format + "Permission: " + record->eventSubscribeInfo->GetPermission() + "\n";
164     std::string deviceId = format + "DevicedID: " + record->eventSubscribeInfo->GetDeviceId() + "\n";
165 
166     std::string events = format + "\tEvent: ";
167     std::string separator;
168     size_t countSize = record->eventSubscribeInfo->GetMatchingSkills().CountEvent();
169     for (size_t eventNum = 0; eventNum < countSize; ++eventNum) {
170         if (eventNum == 0) {
171             separator = "";
172         } else {
173             separator = ", ";
174         }
175         events = events + separator + record->eventSubscribeInfo->GetMatchingSkills().GetEvent(eventNum);
176     }
177     events = events + "\n";
178 
179     std::string entities = format + "\tEntity: ";
180     size_t entitySize = record->eventSubscribeInfo->GetMatchingSkills().CountEntities();
181     for (size_t entityNum = 0; entityNum < entitySize; ++entityNum) {
182         if (entityNum == 0) {
183             separator = "";
184         } else {
185             separator = ", ";
186         }
187         entities = entities + separator + record->eventSubscribeInfo->GetMatchingSkills().GetEntity(entityNum);
188     }
189     entities = entities + "\n";
190 
191     std::string scheme = format + "\tScheme: ";
192     size_t schemeSize = record->eventSubscribeInfo->GetMatchingSkills().CountSchemes();
193     for (size_t schemeNum = 0; schemeNum < schemeSize; ++schemeNum) {
194         if (schemeNum == 0) {
195             separator = "";
196         } else {
197             separator = ", ";
198         }
199         scheme = scheme + separator + record->eventSubscribeInfo->GetMatchingSkills().GetScheme(schemeNum);
200     }
201     scheme = scheme + "\n";
202 
203     std::string matchingSkills = format + "MatchingSkills:\n" + events + entities + scheme;
204 
205     std::string isFreeze = record->isFreeze ? "true" : "false";
206     isFreeze = format + "IsFreeze: " + isFreeze + "\n";
207 
208     std::string freezeTime;
209     if (record->freezeTime == 0) {
210         freezeTime = format + "FreezeTime:  -\n";
211     } else {
212         freezeTime = format + "FreezeTime: " + std::to_string(record->freezeTime) + "\n";
213     }
214 
215     dumpInfo = title + recordTime + pid + uid + bundleName + priority + userId + permission + deviceId +
216                matchingSkills + isFreeze + freezeTime;
217 }
218 
DumpState(const std::string & event,const int32_t & userId,std::vector<std::string> & state)219 void CommonEventSubscriberManager::DumpState(const std::string &event, const int32_t &userId,
220     std::vector<std::string> &state)
221 {
222     EVENT_LOGD("enter");
223 
224     std::vector<SubscriberRecordPtr> records;
225 
226     std::lock_guard<std::mutex> lock(mutex_);
227     GetSubscriberRecordsByEvent(event, userId, records);
228 
229     if (records.size() == 0) {
230         state.emplace_back("Subscribers:\tNo information");
231         return;
232     }
233 
234     size_t num = 0;
235     for (auto record : records) {
236         num++;
237         std::string title = std::to_string(num);
238         if (num == 1) {
239             title = "Subscribers:\tTotal " + std::to_string(records.size()) + " subscribers\nNO " + title + "\n";
240         } else {
241             title = "NO " + title + "\n";
242         }
243         std::string dumpInfo;
244         DumpDetailed(title, record, "\t", dumpInfo);
245         state.emplace_back(dumpInfo);
246     }
247 }
248 
InsertSubscriberRecordLocked(const std::vector<std::string> & events,const SubscriberRecordPtr & record)249 bool CommonEventSubscriberManager::InsertSubscriberRecordLocked(
250     const std::vector<std::string> &events, const SubscriberRecordPtr &record)
251 {
252     EVENT_LOGD("enter");
253 
254     if (events.size() == 0) {
255         EVENT_LOGE("No subscribed events");
256         return false;
257     }
258 
259     if (record == nullptr) {
260         EVENT_LOGE("record is null");
261         return false;
262     }
263 
264     std::lock_guard<std::mutex> lock(mutex_);
265 
266     pid_t pid = record->eventRecordInfo.pid;
267 
268     if (CheckSubscriberCountReachedMaxinum()) {
269         std::vector<std::pair<pid_t, uint32_t>> vtSubscriberCounts = GetTopSubscriberCounts(1);
270         pid_t killedPid = (*vtSubscriberCounts.begin()).first;
271         if (pid == killedPid) {
272             return false;
273         }
274 
275         AAFwk::ExitReason reason = { AAFwk::REASON_RESOURCE_CONTROL, "Kill Reason: CES Register exceed limit"};
276         AAFwk::AbilityManagerClient::GetInstance()->RecordProcessExitReason(killedPid, reason);
277 
278         if (kill(killedPid, SIGNAL_KILL) < 0) {
279             EVENT_LOGE("kill pid=%{public}d which has the most subscribers failed", killedPid);
280         } else {
281             EVENT_LOGI("kill pid=%{public}d which has the most subscribers successfully", killedPid);
282         }
283 
284         int result = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::FRAMEWORK, "PROCESS_KILL",
285             HiviewDFX::HiSysEvent::EventType::FAULT, "PID", killedPid, "PROCESS_NAME",
286             record->eventRecordInfo.bundleName, "MSG", CES_REGISTER_EXCEED_LIMIT);
287         EVENT_LOGE("hisysevent write result=%{public}d, send event [FRAMEWORK,PROCESS_KILL], pid=%{public}d,"
288             " bundleName=%{public}s, msg=%{public}s", result, killedPid, record->eventRecordInfo.bundleName.c_str(),
289             CES_REGISTER_EXCEED_LIMIT);
290     }
291 
292     for (auto event : events) {
293         auto infoItem = eventSubscribers_.find(event);
294         if (infoItem != eventSubscribers_.end()) {
295             infoItem->second.insert(record);
296 
297             if (infoItem->second.size() > MAX_SUBSCRIBER_NUM_PER_EVENT && record->eventSubscribeInfo != nullptr) {
298                 SendSubscriberExceedMaximumHiSysEvent(record->eventSubscribeInfo->GetUserId(), event,
299                     infoItem->second.size());
300             }
301         } else {
302             std::multiset<SubscriberRecordPtr> EventSubscribersPtr;
303             EventSubscribersPtr.insert(record);
304             eventSubscribers_[event] = EventSubscribersPtr;
305         }
306     }
307 
308     subscribers_.emplace_back(record);
309     subscriberCounts_[pid]++;
310 
311     return true;
312 }
313 
RemoveSubscriberRecordLocked(const sptr<IRemoteObject> & commonEventListener)314 int CommonEventSubscriberManager::RemoveSubscriberRecordLocked(const sptr<IRemoteObject> &commonEventListener)
315 {
316     if (commonEventListener == nullptr) {
317         EVENT_LOGE("commonEventListener is null");
318         return ERR_INVALID_VALUE;
319     }
320 
321     std::lock_guard<std::mutex> lock(mutex_);
322     std::vector<std::string> events;
323 
324     for (auto it = subscribers_.begin(); it != subscribers_.end(); ++it) {
325         if (commonEventListener == (*it)->commonEventListener) {
326             RemoveFrozenEventsBySubscriber((*it));
327             (*it)->commonEventListener = nullptr;
328             events = (*it)->eventSubscribeInfo->GetMatchingSkills().GetEvents();
329             EVENT_LOGI("Unsubscribe subscriberID: %{public}s", (*it)->eventRecordInfo.subId.c_str());
330             subscribers_.erase(it);
331             pid_t pid = (*it)->eventRecordInfo.pid;
332             subscriberCounts_[pid] > 1 ? subscriberCounts_[pid]-- : subscriberCounts_.erase(pid);
333             break;
334         }
335     }
336 
337     for (auto event : events) {
338         for (auto it = eventSubscribers_[event].begin(); it != eventSubscribers_[event].end(); ++it) {
339             if ((commonEventListener == (*it)->commonEventListener) || ((*it)->commonEventListener == nullptr)) {
340                 (*it)->commonEventListener = nullptr;
341                 eventSubscribers_[event].erase(it);
342                 break;
343             }
344         }
345         if (eventSubscribers_[event].size() == 0) {
346             eventSubscribers_.erase(event);
347         }
348     }
349 
350     return ERR_OK;
351 }
352 
CheckSubscriberByUserId(const int32_t & subscriberUserId,const bool & isSystemApp,const int32_t & userId)353 bool CommonEventSubscriberManager::CheckSubscriberByUserId(const int32_t &subscriberUserId, const bool &isSystemApp,
354     const int32_t &userId)
355 {
356     if (subscriberUserId == ALL_USER) {
357         return true;
358     }
359 
360     if (isSystemApp && (userId == UNDEFINED_USER || userId == ALL_USER)) {
361         return true;
362     }
363 
364     if (!isSystemApp && subscriberUserId == userId) {
365         return true;
366     }
367 
368     if (isSystemApp && (subscriberUserId == userId ||
369         (subscriberUserId >= SUBSCRIBE_USER_SYSTEM_BEGIN && subscriberUserId <= SUBSCRIBE_USER_SYSTEM_END))) {
370         return true;
371     }
372 
373     return false;
374 }
375 
GetSubscriberRecordsByWantLocked(const CommonEventRecord & eventRecord,std::vector<SubscriberRecordPtr> & records)376 void CommonEventSubscriberManager::GetSubscriberRecordsByWantLocked(const CommonEventRecord &eventRecord,
377     std::vector<SubscriberRecordPtr> &records)
378 {
379     std::lock_guard<std::mutex> lock(mutex_);
380 
381     if (eventSubscribers_.size() <= 0) {
382         return;
383     }
384 
385     auto recordsItem = eventSubscribers_.find(eventRecord.commonEventData->GetWant().GetAction());
386     if (recordsItem == eventSubscribers_.end()) {
387         return;
388     }
389 
390     bool isSystemApp = (eventRecord.eventRecordInfo.isSystemApp || eventRecord.eventRecordInfo.isSubsystem) &&
391         !eventRecord.eventRecordInfo.isProxy;
392 
393     auto bundleName = eventRecord.eventRecordInfo.bundleName;
394     auto uid = eventRecord.eventRecordInfo.uid;
395 
396     for (auto it = (recordsItem->second).begin(); it != (recordsItem->second).end(); it++) {
397         if ((*it)->eventSubscribeInfo == nullptr) {
398             continue;
399         }
400 
401         if (!(*it)->eventSubscribeInfo->GetMatchingSkills().Match(eventRecord.commonEventData->GetWant())) {
402             continue;
403         }
404 
405         if (!eventRecord.publishInfo->GetBundleName().empty() &&
406             eventRecord.publishInfo->GetBundleName() != (*it)->eventRecordInfo.bundleName) {
407             continue;
408         }
409 
410         auto publisherBundleName = (*it)->eventSubscribeInfo->GetPublisherBundleName();
411         if (!publisherBundleName.empty() && publisherBundleName != bundleName) {
412             continue;
413         }
414 
415         auto publisherUid = (*it)->eventSubscribeInfo->GetPublisherUid();
416         if (publisherUid > 0 && uid > 0 && static_cast<uid_t>(publisherUid) != uid) {
417             continue;
418         }
419 
420         if (CheckSubscriberByUserId((*it)->eventSubscribeInfo->GetUserId(), isSystemApp, eventRecord.userId)) {
421             records.emplace_back(*it);
422         }
423     }
424 }
425 
GetSubscriberRecordsByEvent(const std::string & event,const int32_t & userId,std::vector<SubscriberRecordPtr> & records)426 void CommonEventSubscriberManager::GetSubscriberRecordsByEvent(
427     const std::string &event, const int32_t &userId, std::vector<SubscriberRecordPtr> &records)
428 {
429     if (event.empty() && userId == ALL_USER) {
430         records = subscribers_;
431     } else if (event.empty()) {
432         for (auto recordPtr : subscribers_) {
433             if (recordPtr->eventSubscribeInfo->GetUserId() == userId) {
434                 records.emplace_back(recordPtr);
435             }
436         }
437     } else if (userId == ALL_USER) {
438         auto infoItem = eventSubscribers_.find(event);
439         if (infoItem != eventSubscribers_.end()) {
440             for (auto recordPtr : infoItem->second) {
441                 records.emplace_back(recordPtr);
442             }
443         }
444     } else {
445         auto infoItem = eventSubscribers_.find(event);
446         if (infoItem != eventSubscribers_.end()) {
447             for (auto recordPtr : infoItem->second) {
448                 if (CheckSubscriberByUserId(recordPtr->eventSubscribeInfo->GetUserId(), true, userId)) {
449                     records.emplace_back(recordPtr);
450                 }
451             }
452         }
453     }
454 }
455 
UpdateFreezeInfo(const uid_t & uid,const bool & freezeState,const int64_t & freezeTime)456 void CommonEventSubscriberManager::UpdateFreezeInfo(
457     const uid_t &uid, const bool &freezeState, const int64_t &freezeTime)
458 {
459     EVENT_LOGD("enter");
460 
461     std::lock_guard<std::mutex> lock(mutex_);
462     for (auto recordPtr : subscribers_) {
463         if (recordPtr->eventRecordInfo.uid == uid) {
464             if (freezeState) {
465                 recordPtr->freezeTime = freezeTime;
466             } else {
467                 recordPtr->freezeTime = 0;
468             }
469             recordPtr->isFreeze = freezeState;
470             EVENT_LOGD("recordPtr->uid: %{public}d", recordPtr->eventRecordInfo.uid);
471             EVENT_LOGD("recordPtr->isFreeze: %{public}d", recordPtr->isFreeze);
472         }
473     }
474 }
475 
UpdateAllFreezeInfos(const bool & freezeState,const int64_t & freezeTime)476 void CommonEventSubscriberManager::UpdateAllFreezeInfos(const bool &freezeState, const int64_t &freezeTime)
477 {
478     EVENT_LOGD("enter");
479 
480     std::lock_guard<std::mutex> lock(mutex_);
481     for (auto recordPtr : subscribers_) {
482         if (freezeState) {
483             recordPtr->freezeTime = freezeTime;
484         } else {
485             recordPtr->freezeTime = 0;
486         }
487         recordPtr->isFreeze = freezeState;
488     }
489     EVENT_LOGD("all subscribers update freeze state to %{public}d", freezeState);
490 }
491 
InsertFrozenEvents(const SubscriberRecordPtr & subscriberRecord,const CommonEventRecord & eventRecord)492 void CommonEventSubscriberManager::InsertFrozenEvents(
493     const SubscriberRecordPtr &subscriberRecord, const CommonEventRecord &eventRecord)
494 {
495     EVENT_LOGD("enter");
496 
497     if (subscriberRecord == nullptr) {
498         EVENT_LOGE("subscriberRecord is null");
499         return;
500     }
501 
502     auto record = std::make_shared<CommonEventRecord>(eventRecord);
503     std::lock_guard<std::mutex> lock(mutex_);
504     auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
505     if (frozenRecordsItem != frozenEvents_.end()) {
506         auto eventRecordsItem = frozenRecordsItem->second.find(*subscriberRecord);
507         if (eventRecordsItem != frozenRecordsItem->second.end()) {
508             eventRecordsItem->second.emplace_back(record);
509             time_t backRecordTime = mktime(&eventRecordsItem->second.back()->recordTime);
510             time_t frontRecordTime = mktime(&eventRecordsItem->second.front()->recordTime);
511             time_t timeDiff = backRecordTime - frontRecordTime;
512             if (timeDiff > FREEZE_EVENT_TIMEOUT) {
513                 eventRecordsItem->second.erase(eventRecordsItem->second.begin());
514             }
515         } else {
516             std::vector<EventRecordPtr> EventRecords;
517             EventRecords.emplace_back(record);
518             frozenRecordsItem->second[*subscriberRecord] = EventRecords;
519         }
520     } else {
521         std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> frozenRecords;
522         std::vector<EventRecordPtr> EventRecords;
523         EventRecords.emplace_back(record);
524         frozenRecords[*subscriberRecord] = EventRecords;
525         frozenEvents_[subscriberRecord->eventRecordInfo.uid] = frozenRecords;
526     }
527 }
528 
GetFrozenEvents(const uid_t & uid)529 std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> CommonEventSubscriberManager::GetFrozenEvents(
530     const uid_t &uid)
531 {
532     EVENT_LOGD("enter");
533 
534     std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> frozenEvents;
535     std::lock_guard<std::mutex> lock(mutex_);
536     auto infoItem = frozenEvents_.find(uid);
537     if (infoItem != frozenEvents_.end()) {
538         frozenEvents = infoItem->second;
539     }
540 
541     RemoveFrozenEvents(uid);
542 
543     return frozenEvents;
544 }
545 
GetAllFrozenEvents()546 std::map<uid_t, FrozenRecords> CommonEventSubscriberManager::GetAllFrozenEvents()
547 {
548     EVENT_LOGD("enter");
549     std::lock_guard<std::mutex> lock(mutex_);
550     return std::move(frozenEvents_);
551 }
552 
RemoveFrozenEvents(const uid_t & uid)553 void CommonEventSubscriberManager::RemoveFrozenEvents(const uid_t &uid)
554 {
555     EVENT_LOGD("enter");
556     auto infoItem = frozenEvents_.find(uid);
557     if (infoItem != frozenEvents_.end()) {
558         frozenEvents_.erase(uid);
559     }
560 }
561 
RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr & subscriberRecord)562 void CommonEventSubscriberManager::RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr &subscriberRecord)
563 {
564     EVENT_LOGD("enter");
565 
566     auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
567     if (frozenRecordsItem != frozenEvents_.end()) {
568         auto eventRecordsItems = frozenRecordsItem->second.find(*subscriberRecord);
569         if (eventRecordsItems != frozenRecordsItem->second.end()) {
570             frozenRecordsItem->second.erase(*subscriberRecord);
571         }
572     }
573 }
574 
SendSubscriberExceedMaximumHiSysEvent(int32_t userId,const std::string & eventName,uint32_t subscriberNum)575 void CommonEventSubscriberManager::SendSubscriberExceedMaximumHiSysEvent(int32_t userId, const std::string &eventName,
576     uint32_t subscriberNum)
577 {
578     EventInfo eventInfo;
579     eventInfo.userId = userId;
580     eventInfo.eventName = eventName;
581     eventInfo.subscriberNum = subscriberNum;
582     EventReport::SendHiSysEvent(SUBSCRIBER_EXCEED_MAXIMUM, eventInfo);
583 }
584 
CheckSubscriberCountReachedMaxinum()585 bool CommonEventSubscriberManager::CheckSubscriberCountReachedMaxinum()
586 {
587     uint32_t subscriberCount = subscribers_.size();
588     uint32_t maxSubscriberNum = GetUintParameter("hiviewdfx.ces.subscriber_limit",
589         DEFAULT_MAX_SUBSCRIBER_NUM_ALL_APP);
590     if (subscriberCount == (uint32_t)(maxSubscriberNum * WARNING_REPORT_PERCENTAGE)) {
591         EVENT_LOGW("subscribers reaches the alarm threshold");
592         PrintSubscriberCounts(GetTopSubscriberCounts());
593         return false;
594     }
595     if (subscriberCount == maxSubscriberNum) {
596         EVENT_LOGE("subscribers reaches the maxinum");
597         PrintSubscriberCounts(GetTopSubscriberCounts());
598         return true;
599     }
600     return false;
601 }
602 
GetTopSubscriberCounts(size_t topNum)603 std::vector<std::pair<pid_t, uint32_t>> CommonEventSubscriberManager::GetTopSubscriberCounts(size_t topNum)
604 {
605     topNum = subscriberCounts_.size() < topNum ? subscriberCounts_.size() : topNum;
606 
607     std::vector<std::pair<pid_t, uint32_t>> vtSubscriberCounts;
608     std::set<pid_t> pidSet;
609     for (size_t i = 0; i < topNum; i++) {
610         std::pair<pid_t, uint32_t> curPair;
611         for (auto it = subscriberCounts_.begin(); it != subscriberCounts_.end(); it++) {
612             pid_t pid = it->first;
613             uint32_t count = it->second;
614             if (pidSet.find(pid) != pidSet.end()) {
615                 continue;
616             }
617             if (curPair.second < count) {
618                 curPair = std::make_pair(pid, count);
619             }
620         }
621         pidSet.insert(curPair.first);
622         vtSubscriberCounts.push_back(curPair);
623     }
624 
625     return vtSubscriberCounts;
626 }
627 
PrintSubscriberCounts(std::vector<std::pair<pid_t,uint32_t>> vtSubscriberCounts)628 void CommonEventSubscriberManager::PrintSubscriberCounts(std::vector<std::pair<pid_t, uint32_t>> vtSubscriberCounts)
629 {
630     EVENT_LOGI("Start to print top App by subscribers in descending order");
631     int index = 1;
632     for (auto vtIt = vtSubscriberCounts.begin(); vtIt != vtSubscriberCounts.end(); vtIt++) {
633         EVENT_LOGI("top%{public}d pid=%{public}d subscribers=%{public}d", index, vtIt->first, vtIt->second);
634         index++;
635     }
636 }
637 }  // namespace EventFwk
638 }  // namespace OHOS