• 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 "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