• 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.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 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     for (auto it = (recordsItem->second).begin(); it != (recordsItem->second).end(); it++) {
356         if ((*it)->eventSubscribeInfo == nullptr) {
357             continue;
358         }
359 
360         if (!(*it)->eventSubscribeInfo->GetMatchingSkills().Match(eventRecord.commonEventData->GetWant())) {
361             continue;
362         }
363 
364         if (!eventRecord.publishInfo->GetBundleName().empty() &&
365             eventRecord.publishInfo->GetBundleName() != (*it)->eventRecordInfo.bundleName) {
366             continue;
367         }
368 
369         if (CheckSubscriberByUserId((*it)->eventSubscribeInfo->GetUserId(), isSystemApp, eventRecord.userId)) {
370             records.emplace_back(*it);
371         }
372     }
373 }
374 
GetSubscriberRecordsByEvent(const std::string & event,const int32_t & userId,std::vector<SubscriberRecordPtr> & records)375 void CommonEventSubscriberManager::GetSubscriberRecordsByEvent(
376     const std::string &event, const int32_t &userId, std::vector<SubscriberRecordPtr> &records)
377 {
378     if (event.empty() && userId == ALL_USER) {
379         records = subscribers_;
380     } else if (event.empty()) {
381         for (auto recordPtr : subscribers_) {
382             if (recordPtr->eventSubscribeInfo->GetUserId() == userId) {
383                 records.emplace_back(recordPtr);
384             }
385         }
386     } else if (userId == ALL_USER) {
387         auto infoItem = eventSubscribers_.find(event);
388         if (infoItem != eventSubscribers_.end()) {
389             for (auto recordPtr : infoItem->second) {
390                 records.emplace_back(recordPtr);
391             }
392         }
393     } else {
394         auto infoItem = eventSubscribers_.find(event);
395         if (infoItem != eventSubscribers_.end()) {
396             for (auto recordPtr : infoItem->second) {
397                 if (CheckSubscriberByUserId(recordPtr->eventSubscribeInfo->GetUserId(), true, userId)) {
398                     records.emplace_back(recordPtr);
399                 }
400             }
401         }
402     }
403 }
404 
UpdateFreezeInfo(const uid_t & uid,const bool & freezeState,const int64_t & freezeTime)405 void CommonEventSubscriberManager::UpdateFreezeInfo(
406     const uid_t &uid, const bool &freezeState, const int64_t &freezeTime)
407 {
408     EVENT_LOGD("enter");
409 
410     std::lock_guard<std::mutex> lock(mutex_);
411     for (auto recordPtr : subscribers_) {
412         if (recordPtr->eventRecordInfo.uid == uid) {
413             if (freezeState) {
414                 recordPtr->freezeTime = freezeTime;
415             } else {
416                 recordPtr->freezeTime = 0;
417             }
418             recordPtr->isFreeze = freezeState;
419             EVENT_LOGD("recordPtr->uid: %{public}d", recordPtr->eventRecordInfo.uid);
420             EVENT_LOGD("recordPtr->isFreeze: %{public}d", recordPtr->isFreeze);
421         }
422     }
423 }
424 
UpdateAllFreezeInfos(const bool & freezeState,const int64_t & freezeTime)425 void CommonEventSubscriberManager::UpdateAllFreezeInfos(const bool &freezeState, const int64_t &freezeTime)
426 {
427     EVENT_LOGD("enter");
428 
429     std::lock_guard<std::mutex> lock(mutex_);
430     for (auto recordPtr : subscribers_) {
431         if (freezeState) {
432             recordPtr->freezeTime = freezeTime;
433         } else {
434             recordPtr->freezeTime = 0;
435         }
436         recordPtr->isFreeze = freezeState;
437     }
438     EVENT_LOGD("all subscribers update freeze state to %{public}d", freezeState);
439 }
440 
InsertFrozenEvents(const SubscriberRecordPtr & subscriberRecord,const CommonEventRecord & eventRecord)441 void CommonEventSubscriberManager::InsertFrozenEvents(
442     const SubscriberRecordPtr &subscriberRecord, const CommonEventRecord &eventRecord)
443 {
444     EVENT_LOGD("enter");
445 
446     if (subscriberRecord == nullptr) {
447         EVENT_LOGE("subscriberRecord is null");
448         return;
449     }
450 
451     auto record = std::make_shared<CommonEventRecord>(eventRecord);
452     std::lock_guard<std::mutex> lock(mutex_);
453     auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
454     if (frozenRecordsItem != frozenEvents_.end()) {
455         auto eventRecordsItem = frozenRecordsItem->second.find(subscriberRecord);
456         if (eventRecordsItem != frozenRecordsItem->second.end()) {
457             eventRecordsItem->second.emplace_back(record);
458             time_t backRecordTime = mktime(&eventRecordsItem->second.back()->recordTime);
459             time_t frontRecordTime = mktime(&eventRecordsItem->second.front()->recordTime);
460             time_t timeDiff = backRecordTime - frontRecordTime;
461             if (timeDiff > FREEZE_EVENT_TIMEOUT) {
462                 eventRecordsItem->second.erase(eventRecordsItem->second.begin());
463             }
464         } else {
465             std::vector<EventRecordPtr> EventRecords;
466             EventRecords.emplace_back(record);
467             frozenRecordsItem->second[subscriberRecord] = EventRecords;
468         }
469     } else {
470         std::map<SubscriberRecordPtr, std::vector<EventRecordPtr>> frozenRecords;
471         std::vector<EventRecordPtr> EventRecords;
472         EventRecords.emplace_back(record);
473         frozenRecords[subscriberRecord] = EventRecords;
474         frozenEvents_[subscriberRecord->eventRecordInfo.uid] = frozenRecords;
475     }
476 }
477 
GetFrozenEvents(const uid_t & uid)478 std::map<SubscriberRecordPtr, std::vector<EventRecordPtr>> CommonEventSubscriberManager::GetFrozenEvents(
479     const uid_t &uid)
480 {
481     EVENT_LOGD("enter");
482 
483     std::map<SubscriberRecordPtr, std::vector<EventRecordPtr>> frozenEvents;
484     std::lock_guard<std::mutex> lock(mutex_);
485     auto infoItem = frozenEvents_.find(uid);
486     if (infoItem != frozenEvents_.end()) {
487         frozenEvents = infoItem->second;
488     }
489 
490     RemoveFrozenEvents(uid);
491 
492     return frozenEvents;
493 }
494 
GetAllFrozenEvents()495 std::map<uid_t, FrozenRecords> CommonEventSubscriberManager::GetAllFrozenEvents()
496 {
497     EVENT_LOGD("enter");
498     std::lock_guard<std::mutex> lock(mutex_);
499     return std::move(frozenEvents_);
500 }
501 
RemoveFrozenEvents(const uid_t & uid)502 void CommonEventSubscriberManager::RemoveFrozenEvents(const uid_t &uid)
503 {
504     EVENT_LOGD("enter");
505     auto infoItem = frozenEvents_.find(uid);
506     if (infoItem != frozenEvents_.end()) {
507         frozenEvents_.erase(uid);
508     }
509 }
510 
RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr & subscriberRecord)511 void CommonEventSubscriberManager::RemoveFrozenEventsBySubscriber(const SubscriberRecordPtr &subscriberRecord)
512 {
513     EVENT_LOGD("enter");
514 
515     auto frozenRecordsItem = frozenEvents_.find(subscriberRecord->eventRecordInfo.uid);
516     if (frozenRecordsItem != frozenEvents_.end()) {
517         auto eventRecordsItems = frozenRecordsItem->second.find(subscriberRecord);
518         if (eventRecordsItems != frozenRecordsItem->second.end()) {
519             frozenRecordsItem->second.erase(subscriberRecord);
520         }
521     }
522 }
523 
SendSubscriberExceedMaximumHiSysEvent(int32_t userId,const std::string & eventName,uint32_t subscriberNum)524 void CommonEventSubscriberManager::SendSubscriberExceedMaximumHiSysEvent(int32_t userId, const std::string &eventName,
525     uint32_t subscriberNum)
526 {
527     EventInfo eventInfo;
528     eventInfo.userId = userId;
529     eventInfo.eventName = eventName;
530     eventInfo.subscriberNum = subscriberNum;
531     EventReport::SendHiSysEvent(SUBSCRIBER_EXCEED_MAXIMUM, eventInfo);
532 }
533 }  // namespace EventFwk
534 }  // namespace OHOS