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