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