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