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