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