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