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 "common_event_subscriber_manager.h"
17
18 #include "event_log_wrapper.h"
19 #include "event_report.h"
20 #include "hitrace_meter_adapter.h"
21 #include "subscriber_death_recipient.h"
22
23 namespace OHOS {
24 namespace EventFwk {
25 constexpr int32_t LENGTH = 80;
26 static constexpr int32_t SUBSCRIBE_EVENT_MAX_NUM = 512;
27
CommonEventSubscriberManager()28 CommonEventSubscriberManager::CommonEventSubscriberManager()
29 : death_(sptr<IRemoteObject::DeathRecipient>(new (std::nothrow) SubscriberDeathRecipient()))
30 {
31 }
32
~CommonEventSubscriberManager()33 CommonEventSubscriberManager::~CommonEventSubscriberManager()
34 {
35 EVENT_LOGI("~CommonEventSubscriberManager");
36 }
37
InsertSubscriber(const SubscribeInfoPtr & eventSubscribeInfo,const sptr<IRemoteObject> & commonEventListener,const struct tm & recordTime,const EventRecordInfo & eventRecordInfo)38 std::shared_ptr<EventSubscriberRecord> CommonEventSubscriberManager::InsertSubscriber(
39 const SubscribeInfoPtr &eventSubscribeInfo, const sptr<IRemoteObject> &commonEventListener,
40 const struct tm &recordTime, const EventRecordInfo &eventRecordInfo)
41 {
42 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
43 EVENT_LOGD("enter");
44
45 if (eventSubscribeInfo == nullptr) {
46 EVENT_LOGE("eventSubscribeInfo is null");
47 return nullptr;
48 }
49
50 if (commonEventListener == nullptr) {
51 EVENT_LOGE("commonEventListener is null");
52 return nullptr;
53 }
54
55 std::vector<std::string> events = eventSubscribeInfo->GetMatchingSkills().GetEvents();
56 if (events.size() == 0 || events.size() > SUBSCRIBE_EVENT_MAX_NUM) {
57 EVENT_LOGE("subscribed events size is error");
58 return nullptr;
59 }
60
61 auto record = std::make_shared<EventSubscriberRecord>();
62 if (record == nullptr) {
63 EVENT_LOGE("Failed to create EventSubscriberRecord");
64 return nullptr;
65 }
66
67 record->eventSubscribeInfo = eventSubscribeInfo;
68 record->commonEventListener = commonEventListener;
69 record->recordTime = recordTime;
70 record->eventRecordInfo = eventRecordInfo;
71
72 if (death_ != nullptr) {
73 commonEventListener->AddDeathRecipient(death_);
74 }
75
76 if (!InsertSubscriberRecordLocked(events, record)) {
77 return nullptr;
78 }
79
80 return record;
81 }
82
RemoveSubscriber(const sptr<IRemoteObject> & commonEventListener)83 int CommonEventSubscriberManager::RemoveSubscriber(const sptr<IRemoteObject> &commonEventListener)
84 {
85 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
86 EVENT_LOGD("enter");
87
88 if (commonEventListener == nullptr) {
89 EVENT_LOGE("commonEventListener is null");
90 return ERR_INVALID_VALUE;
91 }
92
93 int res = RemoveSubscriberRecordLocked(commonEventListener);
94
95 if (death_ != nullptr) {
96 commonEventListener->RemoveDeathRecipient(death_);
97 }
98 return res;
99 }
100
GetSubscriberRecords(const CommonEventRecord & eventRecord)101 std::vector<std::shared_ptr<EventSubscriberRecord>> CommonEventSubscriberManager::GetSubscriberRecords(
102 const CommonEventRecord &eventRecord)
103 {
104 EVENT_LOGD("enter");
105
106 auto records = std::vector<SubscriberRecordPtr>();
107
108 GetSubscriberRecordsByWantLocked(eventRecord, records);
109
110 return records;
111 }
112
GetSubscriberRecord(const sptr<IRemoteObject> & commonEventListener)113 std::shared_ptr<EventSubscriberRecord> CommonEventSubscriberManager::GetSubscriberRecord(
114 const sptr<IRemoteObject> &commonEventListener)
115 {
116 std::lock_guard<std::mutex> lock(mutex_);
117
118 for (auto it = subscribers_.begin(); it != subscribers_.end(); ++it) {
119 if (commonEventListener == (*it)->commonEventListener) {
120 return *it;
121 }
122 }
123
124 return nullptr;
125 }
126
DumpDetailed(const std::string & title,const SubscriberRecordPtr & record,const std::string format,std::string & dumpInfo)127 void CommonEventSubscriberManager::DumpDetailed(
128 const std::string &title, const SubscriberRecordPtr &record, const std::string format, std::string &dumpInfo)
129 {
130 if (record == nullptr || record->eventSubscribeInfo == nullptr) {
131 EVENT_LOGE("record or eventSubscribeInfo is null");
132 return;
133 }
134 char systime[LENGTH];
135 strftime(systime, sizeof(char) * LENGTH, "%Y%m%d %I:%M %p", &record->recordTime);
136
137 std::string recordTime = format + "Time: " + std::string(systime) + "\n";
138 std::string pid = format + "PID: " + std::to_string(record->eventRecordInfo.pid) + "\n";
139 std::string uid = format + "UID: " + std::to_string(record->eventRecordInfo.uid) + "\n";
140 std::string bundleName = format + "BundleName: " + record->eventRecordInfo.bundleName + "\n";
141 std::string priority = format + "Priority: " + std::to_string(record->eventSubscribeInfo->GetPriority()) + "\n";
142 std::string userId;
143 switch (record->eventSubscribeInfo->GetUserId()) {
144 case UNDEFINED_USER:
145 userId = "UNDEFINED_USER";
146 break;
147 case ALL_USER:
148 userId = "ALL_USER";
149 break;
150 default:
151 userId = std::to_string(record->eventSubscribeInfo->GetUserId());
152 break;
153 }
154 userId = format + "USERID: " + userId + "\n";
155 std::string permission = format + "Permission: " + record->eventSubscribeInfo->GetPermission() + "\n";
156 std::string deviceId = format + "DevicedID: " + record->eventSubscribeInfo->GetDeviceId() + "\n";
157
158 std::string events = format + "\tEvent: ";
159 std::string separator;
160 size_t countSize = record->eventSubscribeInfo->GetMatchingSkills().CountEvent();
161 for (size_t eventNum = 0; eventNum < countSize; ++eventNum) {
162 if (eventNum == 0) {
163 separator = "";
164 } else {
165 separator = ", ";
166 }
167 events = events + separator + record->eventSubscribeInfo->GetMatchingSkills().GetEvent(eventNum);
168 }
169 events = events + "\n";
170
171 std::string entities = format + "\tEntity: ";
172 size_t entitySize = record->eventSubscribeInfo->GetMatchingSkills().CountEntities();
173 for (size_t entityNum = 0; entityNum < entitySize; ++entityNum) {
174 if (entityNum == 0) {
175 separator = "";
176 } else {
177 separator = ", ";
178 }
179 entities = entities + separator + record->eventSubscribeInfo->GetMatchingSkills().GetEntity(entityNum);
180 }
181 entities = entities + "\n";
182
183 std::string scheme = format + "\tScheme: ";
184 size_t schemeSize = record->eventSubscribeInfo->GetMatchingSkills().CountSchemes();
185 for (size_t schemeNum = 0; schemeNum < schemeSize; ++schemeNum) {
186 if (schemeNum == 0) {
187 separator = "";
188 } else {
189 separator = ", ";
190 }
191 scheme = scheme + separator + record->eventSubscribeInfo->GetMatchingSkills().GetScheme(schemeNum);
192 }
193 scheme = scheme + "\n";
194
195 std::string matchingSkills = format + "MatchingSkills:\n" + events + entities + scheme;
196
197 std::string isFreeze = record->isFreeze ? "true" : "false";
198 isFreeze = format + "IsFreeze: " + isFreeze + "\n";
199
200 std::string freezeTime;
201 if (record->freezeTime == 0) {
202 freezeTime = format + "FreezeTime: -\n";
203 } else {
204 freezeTime = format + "FreezeTime: " + std::to_string(record->freezeTime) + "\n";
205 }
206
207 dumpInfo = title + recordTime + pid + uid + bundleName + priority + userId + permission + deviceId +
208 matchingSkills + isFreeze + freezeTime;
209 }
210
DumpState(const std::string & event,const int32_t & userId,std::vector<std::string> & state)211 void CommonEventSubscriberManager::DumpState(const std::string &event, const int32_t &userId,
212 std::vector<std::string> &state)
213 {
214 EVENT_LOGD("enter");
215
216 std::vector<SubscriberRecordPtr> records;
217
218 std::lock_guard<std::mutex> lock(mutex_);
219 GetSubscriberRecordsByEvent(event, userId, records);
220
221 if (records.size() == 0) {
222 state.emplace_back("Subscribers:\tNo information");
223 return;
224 }
225
226 size_t num = 0;
227 for (auto record : records) {
228 num++;
229 std::string title = std::to_string(num);
230 if (num == 1) {
231 title = "Subscribers:\tTotal " + std::to_string(records.size()) + " subscribers\nNO " + title + "\n";
232 } else {
233 title = "NO " + title + "\n";
234 }
235 std::string dumpInfo;
236 DumpDetailed(title, record, "\t", dumpInfo);
237 state.emplace_back(dumpInfo);
238 }
239 }
240
InsertSubscriberRecordLocked(const std::vector<std::string> & events,const SubscriberRecordPtr & record)241 bool CommonEventSubscriberManager::InsertSubscriberRecordLocked(
242 const std::vector<std::string> &events, const SubscriberRecordPtr &record)
243 {
244 EVENT_LOGD("enter");
245
246 if (events.size() == 0) {
247 EVENT_LOGE("No subscribed events");
248 return false;
249 }
250
251 if (record == nullptr) {
252 EVENT_LOGE("record is null");
253 return false;
254 }
255
256 std::lock_guard<std::mutex> lock(mutex_);
257
258 for (auto event : events) {
259 auto infoItem = eventSubscribers_.find(event);
260 if (infoItem != eventSubscribers_.end()) {
261 infoItem->second.insert(record);
262
263 if (infoItem->second.size() > MAX_SUBSCRIBER_NUM_PER_EVENT && record->eventSubscribeInfo != nullptr) {
264 SendSubscriberExceedMaximumHiSysEvent(record->eventSubscribeInfo->GetUserId(), event,
265 infoItem->second.size());
266 }
267 } else {
268 std::multiset<SubscriberRecordPtr> EventSubscribersPtr;
269 EventSubscribersPtr.insert(record);
270 eventSubscribers_[event] = EventSubscribersPtr;
271 }
272 }
273
274 subscribers_.emplace_back(record);
275
276 return true;
277 }
278
RemoveSubscriberRecordLocked(const sptr<IRemoteObject> & commonEventListener)279 int CommonEventSubscriberManager::RemoveSubscriberRecordLocked(const sptr<IRemoteObject> &commonEventListener)
280 {
281 if (commonEventListener == nullptr) {
282 EVENT_LOGE("commonEventListener is null");
283 return ERR_INVALID_VALUE;
284 }
285
286 std::lock_guard<std::mutex> lock(mutex_);
287 std::vector<std::string> events;
288
289 for (auto it = subscribers_.begin(); it != subscribers_.end(); ++it) {
290 if (commonEventListener == (*it)->commonEventListener) {
291 RemoveFrozenEventsBySubscriber((*it));
292 (*it)->commonEventListener = nullptr;
293 events = (*it)->eventSubscribeInfo->GetMatchingSkills().GetEvents();
294 subscribers_.erase(it);
295 break;
296 }
297 }
298
299 for (auto event : events) {
300 for (auto it = eventSubscribers_[event].begin(); it != eventSubscribers_[event].end(); ++it) {
301 if ((commonEventListener == (*it)->commonEventListener) || ((*it)->commonEventListener == nullptr)) {
302 (*it)->commonEventListener = nullptr;
303 eventSubscribers_[event].erase(it);
304 break;
305 }
306 }
307 if (eventSubscribers_[event].size() == 0) {
308 eventSubscribers_.erase(event);
309 }
310 }
311
312 return ERR_OK;
313 }
314
CheckSubscriberByUserId(const int32_t & subscriberUserId,const bool & isSystemApp,const int32_t & userId)315 bool CommonEventSubscriberManager::CheckSubscriberByUserId(const int32_t &subscriberUserId, const bool &isSystemApp,
316 const int32_t &userId)
317 {
318 if (subscriberUserId == ALL_USER) {
319 return true;
320 }
321
322 if (isSystemApp && (userId == UNDEFINED_USER || userId == ALL_USER)) {
323 return true;
324 }
325
326 if (!isSystemApp && subscriberUserId == userId) {
327 return true;
328 }
329
330 if (isSystemApp && (subscriberUserId == userId ||
331 (subscriberUserId >= SUBSCRIBE_USER_SYSTEM_BEGIN && subscriberUserId <= SUBSCRIBE_USER_SYSTEM_END))) {
332 return true;
333 }
334
335 return false;
336 }
337
GetSubscriberRecordsByWantLocked(const CommonEventRecord & eventRecord,std::vector<SubscriberRecordPtr> & records)338 void CommonEventSubscriberManager::GetSubscriberRecordsByWantLocked(const CommonEventRecord &eventRecord,
339 std::vector<SubscriberRecordPtr> &records)
340 {
341 std::lock_guard<std::mutex> lock(mutex_);
342
343 if (eventSubscribers_.size() <= 0) {
344 return;
345 }
346
347 auto recordsItem = eventSubscribers_.find(eventRecord.commonEventData->GetWant().GetAction());
348 if (recordsItem == eventSubscribers_.end()) {
349 return;
350 }
351
352 bool isSystemApp = (eventRecord.eventRecordInfo.isSystemApp || eventRecord.eventRecordInfo.isSubsystem) &&
353 !eventRecord.eventRecordInfo.isProxy;
354
355 auto bundleName = eventRecord.eventRecordInfo.bundleName;
356 auto uid = eventRecord.eventRecordInfo.uid;
357
358 for (auto it = (recordsItem->second).begin(); it != (recordsItem->second).end(); it++) {
359 if ((*it)->eventSubscribeInfo == nullptr) {
360 continue;
361 }
362
363 if (!(*it)->eventSubscribeInfo->GetMatchingSkills().Match(eventRecord.commonEventData->GetWant())) {
364 continue;
365 }
366
367 if (!eventRecord.publishInfo->GetBundleName().empty() &&
368 eventRecord.publishInfo->GetBundleName() != (*it)->eventRecordInfo.bundleName) {
369 continue;
370 }
371
372 auto publisherBundleName = (*it)->eventSubscribeInfo->GetPublisherBundleName();
373 if (!publisherBundleName.empty() && publisherBundleName != bundleName) {
374 continue;
375 }
376
377 auto publisherUid = (*it)->eventSubscribeInfo->GetPublisherUid();
378 if (publisherUid > 0 && uid > 0 && static_cast<uid_t>(publisherUid) != uid) {
379 continue;
380 }
381
382 if (CheckSubscriberByUserId((*it)->eventSubscribeInfo->GetUserId(), isSystemApp, eventRecord.userId)) {
383 records.emplace_back(*it);
384 }
385 }
386 }
387
GetSubscriberRecordsByEvent(const std::string & event,const int32_t & userId,std::vector<SubscriberRecordPtr> & records)388 void CommonEventSubscriberManager::GetSubscriberRecordsByEvent(
389 const std::string &event, const int32_t &userId, std::vector<SubscriberRecordPtr> &records)
390 {
391 if (event.empty() && userId == ALL_USER) {
392 records = subscribers_;
393 } else if (event.empty()) {
394 for (auto recordPtr : subscribers_) {
395 if (recordPtr->eventSubscribeInfo->GetUserId() == userId) {
396 records.emplace_back(recordPtr);
397 }
398 }
399 } else if (userId == ALL_USER) {
400 auto infoItem = eventSubscribers_.find(event);
401 if (infoItem != eventSubscribers_.end()) {
402 for (auto recordPtr : infoItem->second) {
403 records.emplace_back(recordPtr);
404 }
405 }
406 } else {
407 auto infoItem = eventSubscribers_.find(event);
408 if (infoItem != eventSubscribers_.end()) {
409 for (auto recordPtr : infoItem->second) {
410 if (CheckSubscriberByUserId(recordPtr->eventSubscribeInfo->GetUserId(), true, userId)) {
411 records.emplace_back(recordPtr);
412 }
413 }
414 }
415 }
416 }
417
UpdateFreezeInfo(const uid_t & uid,const bool & freezeState,const int64_t & freezeTime)418 void CommonEventSubscriberManager::UpdateFreezeInfo(
419 const uid_t &uid, const bool &freezeState, const int64_t &freezeTime)
420 {
421 EVENT_LOGD("enter");
422
423 std::lock_guard<std::mutex> lock(mutex_);
424 for (auto recordPtr : subscribers_) {
425 if (recordPtr->eventRecordInfo.uid == uid) {
426 if (freezeState) {
427 recordPtr->freezeTime = freezeTime;
428 } else {
429 recordPtr->freezeTime = 0;
430 }
431 recordPtr->isFreeze = freezeState;
432 EVENT_LOGD("recordPtr->uid: %{public}d", recordPtr->eventRecordInfo.uid);
433 EVENT_LOGD("recordPtr->isFreeze: %{public}d", recordPtr->isFreeze);
434 }
435 }
436 }
437
UpdateAllFreezeInfos(const bool & freezeState,const int64_t & freezeTime)438 void CommonEventSubscriberManager::UpdateAllFreezeInfos(const bool &freezeState, const int64_t &freezeTime)
439 {
440 EVENT_LOGD("enter");
441
442 std::lock_guard<std::mutex> lock(mutex_);
443 for (auto recordPtr : subscribers_) {
444 if (freezeState) {
445 recordPtr->freezeTime = freezeTime;
446 } else {
447 recordPtr->freezeTime = 0;
448 }
449 recordPtr->isFreeze = freezeState;
450 }
451 EVENT_LOGD("all subscribers update freeze state to %{public}d", freezeState);
452 }
453
InsertFrozenEvents(const SubscriberRecordPtr & subscriberRecord,const CommonEventRecord & eventRecord)454 void CommonEventSubscriberManager::InsertFrozenEvents(
455 const SubscriberRecordPtr &subscriberRecord, const CommonEventRecord &eventRecord)
456 {
457 EVENT_LOGD("enter");
458
459 if (subscriberRecord == nullptr) {
460 EVENT_LOGE("subscriberRecord is null");
461 return;
462 }
463
464 auto record = std::make_shared<CommonEventRecord>(eventRecord);
465 std::lock_guard<std::mutex> lock(mutex_);
466 auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
467 if (frozenRecordsItem != frozenEvents_.end()) {
468 auto eventRecordsItem = frozenRecordsItem->second.find(*subscriberRecord);
469 if (eventRecordsItem != frozenRecordsItem->second.end()) {
470 eventRecordsItem->second.emplace_back(record);
471 time_t backRecordTime = mktime(&eventRecordsItem->second.back()->recordTime);
472 time_t frontRecordTime = mktime(&eventRecordsItem->second.front()->recordTime);
473 time_t timeDiff = backRecordTime - frontRecordTime;
474 if (timeDiff > FREEZE_EVENT_TIMEOUT) {
475 eventRecordsItem->second.erase(eventRecordsItem->second.begin());
476 }
477 } else {
478 std::vector<EventRecordPtr> EventRecords;
479 EventRecords.emplace_back(record);
480 frozenRecordsItem->second[*subscriberRecord] = EventRecords;
481 }
482 } else {
483 std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> frozenRecords;
484 std::vector<EventRecordPtr> EventRecords;
485 EventRecords.emplace_back(record);
486 frozenRecords[*subscriberRecord] = EventRecords;
487 frozenEvents_[subscriberRecord->eventRecordInfo.uid] = frozenRecords;
488 }
489 }
490
GetFrozenEvents(const uid_t & uid)491 std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> CommonEventSubscriberManager::GetFrozenEvents(
492 const uid_t &uid)
493 {
494 EVENT_LOGD("enter");
495
496 std::map<EventSubscriberRecord, std::vector<EventRecordPtr>> frozenEvents;
497 std::lock_guard<std::mutex> lock(mutex_);
498 auto infoItem = frozenEvents_.find(uid);
499 if (infoItem != frozenEvents_.end()) {
500 frozenEvents = infoItem->second;
501 }
502
503 RemoveFrozenEvents(uid);
504
505 return frozenEvents;
506 }
507
GetAllFrozenEvents()508 std::map<uid_t, FrozenRecords> CommonEventSubscriberManager::GetAllFrozenEvents()
509 {
510 EVENT_LOGD("enter");
511 std::lock_guard<std::mutex> lock(mutex_);
512 return std::move(frozenEvents_);
513 }
514
RemoveFrozenEvents(const uid_t & uid)515 void CommonEventSubscriberManager::RemoveFrozenEvents(const uid_t &uid)
516 {
517 EVENT_LOGD("enter");
518 auto infoItem = frozenEvents_.find(uid);
519 if (infoItem != frozenEvents_.end()) {
520 frozenEvents_.erase(uid);
521 }
522 }
523
RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr & subscriberRecord)524 void CommonEventSubscriberManager::RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr &subscriberRecord)
525 {
526 EVENT_LOGD("enter");
527
528 auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
529 if (frozenRecordsItem != frozenEvents_.end()) {
530 auto eventRecordsItems = frozenRecordsItem->second.find(*subscriberRecord);
531 if (eventRecordsItems != frozenRecordsItem->second.end()) {
532 frozenRecordsItem->second.erase(*subscriberRecord);
533 }
534 }
535 }
536
SendSubscriberExceedMaximumHiSysEvent(int32_t userId,const std::string & eventName,uint32_t subscriberNum)537 void CommonEventSubscriberManager::SendSubscriberExceedMaximumHiSysEvent(int32_t userId, const std::string &eventName,
538 uint32_t subscriberNum)
539 {
540 EventInfo eventInfo;
541 eventInfo.userId = userId;
542 eventInfo.eventName = eventName;
543 eventInfo.subscriberNum = subscriberNum;
544 EventReport::SendHiSysEvent(SUBSCRIBER_EXCEED_MAXIMUM, eventInfo);
545 }
546 } // namespace EventFwk
547 } // namespace OHOS