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