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