1 /*
2  * Copyright (c) 2021-2024 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 "inner_common_event_manager.h"
17 
18 #include "ces_inner_error_code.h"
19 #include "common_event_constant.h"
20 #include "common_event_record.h"
21 #include "common_event_sticky_manager.h"
22 #include "common_event_subscriber_manager.h"
23 #include "common_event_support.h"
24 #include "common_event_support_mapper.h"
25 #include "event_log_wrapper.h"
26 #include "event_report.h"
27 #include "hitrace_meter_adapter.h"
28 #include "ipc_skeleton.h"
29 #include "nlohmann/json.hpp"
30 #include "os_account_manager_helper.h"
31 #include "parameters.h"
32 #include "system_time.h"
33 #include "want.h"
34 #include <fstream>
35 #include "securec.h"
36 #ifdef CONFIG_POLICY_ENABLE
37 #include "config_policy_utils.h"
38 #endif
39 
40 
41 namespace OHOS {
42 namespace EventFwk {
43 namespace {
44 const std::string NOTIFICATION_CES_CHECK_SA_PERMISSION = "notification.ces.check.sa.permission";
45 }  // namespace
46 
47 static const int32_t PUBLISH_SYS_EVENT_INTERVAL = 10;  // 10s
48 #ifdef CONFIG_POLICY_ENABLE
49     constexpr static const char* CONFIG_FILE = "etc/notification/common_event_config.json";
50 #else
51     constexpr static const char* CONFIG_FILE = "system/etc/notification/common_event_config.json";
52 #endif
53 
InnerCommonEventManager()54 InnerCommonEventManager::InnerCommonEventManager() : controlPtr_(std::make_shared<CommonEventControlManager>()),
55     staticSubscriberManager_(std::make_shared<StaticSubscriberManager>())
56 {
57     supportCheckSaPermission_ = OHOS::system::GetParameter(NOTIFICATION_CES_CHECK_SA_PERMISSION, "false");
58     if (!GetJsonByFilePath(CONFIG_FILE, eventConfigJson_)) {
59         EVENT_LOGE("Failed to get config file.");
60     }
61 
62     getCcmPublishControl();
63 }
64 
65 constexpr char HIDUMPER_HELP_MSG[] =
66     "Usage:dump <command> [options]\n"
67     "Description:\n"
68     "  -h, --help                   list available commands\n"
69     "  -a, --all                    dump the info of all events\n"
70     "  -e, --event <name>           dump the info of a specified event\n";
71 
72 const std::unordered_map<std::string, char> HIDUMPER_CMD_MAP = {
73     { "--help", 'h'},
74     { "--all", 'a'},
75     { "--event", 'e'},
76     { "-h", 'h' },
77     { "-a", 'a' },
78     { "-e", 'e' },
79 };
80 
81 const std::map<std::string, std::string> EVENT_COUNT_DISALLOW = {
82     { CommonEventSupport::COMMON_EVENT_TIME_TICK, "usual.event.TIME_TICK" },
83 };
84 
85 constexpr size_t HIDUMP_OPTION_MAX_SIZE = 2;
86 
GetJsonFromFile(const char *path, nlohmann::json &root)87 bool InnerCommonEventManager::GetJsonFromFile(const char *path, nlohmann::json &root)
88 {
89     std::ifstream file(path);
90     if (!file.good()) {
91         EVENT_LOGE("Failed to open file %{public}s.", path);
92         return false;
93     }
94     root = nlohmann::json::parse(file, nullptr, false);
95     file.close();
96     if (root.is_discarded() || !root.is_structured()) {
97         EVENT_LOGE("Failed to parse json from file %{public}s.", path);
98         return false;
99     }
100     if (root.is_null() || root.empty() || !root.is_object()) {
101         EVENT_LOGE("GetJsonFromFile fail as invalid root.");
102         return false;
103     }
104     return true;
105 }
106 
GetJsonByFilePath(const char *filePath, std::vector<nlohmann::json> &roots)107 bool InnerCommonEventManager::GetJsonByFilePath(const char *filePath, std::vector<nlohmann::json> &roots)
108 {
109     EVENT_LOGD("Get json value by file path.");
110     if (filePath == nullptr) {
111         EVENT_LOGE("GetJsonByFilePath fail as filePath is null.");
112         return false;
113     }
114     bool ret = false;
115     nlohmann::json localRoot;
116 #ifdef CONFIG_POLICY_ENABLE
117     CfgFiles *cfgFiles = GetCfgFiles(filePath);
118     if (cfgFiles == nullptr) {
119         EVENT_LOGE("Not found filePath:%{public}s.", filePath);
120         return false;
121     }
122 
123     for (int32_t i = 0; i <= MAX_CFG_POLICY_DIRS_CNT - 1; i++) {
124         if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0' && GetJsonFromFile(cfgFiles->paths[i], localRoot)) {
125             EVENT_LOGE("Config file path:%{public}s.", cfgFiles->paths[i]);
126             roots.push_back(localRoot);
127             ret = true;
128         }
129     }
130     FreeCfgFiles(cfgFiles);
131 #else
132     EVENT_LOGD("Use default config file path:%{public}s.", filePath);
133     ret = GetJsonFromFile(filePath, localRoot);
134     if (ret) {
135         roots.push_back(localRoot);
136     }
137 #endif
138     return ret;
139 }
140 
GetConfigJson(const std::string &keyCheck, nlohmann::json &configJson) const141 bool InnerCommonEventManager::GetConfigJson(const std::string &keyCheck, nlohmann::json &configJson) const
142 {
143     if (eventConfigJson_.size() <= 0) {
144         EVENT_LOGE("Failed to get config json cause empty configJsons.");
145         return false;
146     }
147     bool ret = false;
148     std::for_each(eventConfigJson_.rbegin(), eventConfigJson_.rend(),
149         [&keyCheck, &configJson, &ret](const nlohmann::json &json) {
150         if (keyCheck.find("/") == std::string::npos && json.contains(keyCheck)) {
151             configJson = json;
152             ret = true;
153         }
154 
155         if (keyCheck.find("/") != std::string::npos) {
156             nlohmann::json::json_pointer keyCheckPoint(keyCheck);
157             if (json.contains(keyCheckPoint)) {
158                 configJson = json;
159                 ret = true;
160             }
161         }
162     });
163     if (!ret) {
164         EVENT_LOGE("Cannot find keyCheck: %{public}s in configJsons.", keyCheck.c_str());
165     }
166     return ret;
167 }
168 
getCcmPublishControl()169 void InnerCommonEventManager::getCcmPublishControl()
170 {
171     nlohmann::json root;
172     std::string JsonPoint = "/";
173     JsonPoint.append("publishControl");
174     if (!GetConfigJson(JsonPoint, root)) {
175         EVENT_LOGE("Failed to get JsonPoint CCM config file.");
176         return;
177     }
178     if (!root.contains("publishControl")) {
179         EVENT_LOGE("not found jsonKey publishControl");
180         return;
181     }
182     // 访问数据
183     const nlohmann::json& publish_control = root["publishControl"];
184     if (publish_control.is_null() || publish_control.empty()) {
185         EVENT_LOGE("GetCcm publishControl failed as invalid publishControl json.");
186         return;
187     }
188     for (const auto& item : publish_control) {
189         std::string event_name = item["eventName"];
190         const nlohmann::json& uid_list = item["uidList"];
191         std::vector<int> uids;
192         for (const auto& uid : uid_list) {
193             uids.push_back(uid);
194         }
195         publishControlMap_[event_name] = uids;
196     }
197 }
198 
IsPublishAllowed(const std::string &event, int32_t uid)199 bool InnerCommonEventManager::IsPublishAllowed(const std::string &event, int32_t uid)
200 {
201     if (publishControlMap_.empty()) {
202         EVENT_LOGD("PublishControlMap event no need control");
203         return true;
204     }
205     auto it = publishControlMap_.find(event);
206     if (it != publishControlMap_.end()) {
207         EVENT_LOGD("PublishControlMap event = %{public}s,uid = %{public}d", event.c_str(), it->second[0]);
208         return std::find(it->second.begin(), it->second.end(), uid) != it->second.end();
209     }
210     return true;
211 }
212 
PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo, const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime, const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken, const int32_t &userId, const std::string &bundleName, const sptr<IRemoteObject> &service)213 bool InnerCommonEventManager::PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo,
214     const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime, const pid_t &pid, const uid_t &uid,
215     const Security::AccessToken::AccessTokenID &callerToken, const int32_t &userId, const std::string &bundleName,
216     const sptr<IRemoteObject> &service)
217 {
218     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
219     if (data.GetWant().GetAction().empty()) {
220         EVENT_LOGE("the commonEventdata action is null");
221         return false;
222     }
223 
224     if ((!publishInfo.IsOrdered()) && (commonEventListener != nullptr)) {
225         EVENT_LOGE("When publishing unordered events, the subscriber object is not required.");
226         return false;
227     }
228 
229     std::string action = data.GetWant().GetAction();
230     bool isAllowed = IsPublishAllowed(action, uid);
231     if (!isAllowed) {
232         EVENT_LOGE("Publish event = %{public}s not allowed uid = %{public}d.", action.c_str(), uid);
233         return false;
234     }
235     bool isSystemEvent = DelayedSingleton<CommonEventSupport>::GetInstance()->IsSystemEvent(action);
236     int32_t user = userId;
237     EventComeFrom comeFrom;
238     if (!CheckUserId(pid, uid, callerToken, comeFrom, user)) {
239         SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
240         return false;
241     }
242 
243     if (isSystemEvent) {
244         EVENT_LOGD("System common event");
245         if (!comeFrom.isSystemApp && !comeFrom.isSubsystem) {
246             EVENT_LOGE(
247                 "No permission to send a system common event from %{public}s(pid = %{public}d, uid = %{public}d)"
248                 ", userId = %{public}d", bundleName.c_str(), pid, uid, userId);
249             SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
250             return false;
251         }
252     }
253 
254     EVENT_LOGI("%{public}s(pid = %{public}d, uid = %{public}d), publish event = %{public}s to userId = %{public}d",
255         bundleName.c_str(), pid, uid, data.GetWant().GetAction().c_str(), userId);
256 
257     if (staticSubscriberManager_ != nullptr) {
258         staticSubscriberManager_->PublishCommonEvent(data, publishInfo, callerToken, user, service, bundleName);
259     }
260 
261     CommonEventRecord eventRecord;
262     eventRecord.commonEventData = std::make_shared<CommonEventData>(data);
263     eventRecord.publishInfo = std::make_shared<CommonEventPublishInfo>(publishInfo);
264     eventRecord.recordTime = recordTime;
265     eventRecord.eventRecordInfo.pid = pid;
266     eventRecord.eventRecordInfo.uid = uid;
267     eventRecord.eventRecordInfo.callerToken = callerToken;
268     eventRecord.userId = user;
269     eventRecord.eventRecordInfo.bundleName = bundleName;
270     eventRecord.eventRecordInfo.isSubsystem = comeFrom.isSubsystem;
271     eventRecord.eventRecordInfo.isSystemApp = (comeFrom.isSystemApp || comeFrom.isCemShell);
272     eventRecord.eventRecordInfo.isProxy = comeFrom.isProxy;
273     eventRecord.isSystemEvent = isSystemEvent;
274 
275     if (publishInfo.IsSticky()) {
276         if (!ProcessStickyEvent(eventRecord)) {
277             SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
278             return false;
279         }
280     }
281 
282     if (!controlPtr_) {
283         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
284         SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
285         return false;
286     }
287     controlPtr_->PublishCommonEvent(eventRecord, commonEventListener);
288 
289     std::string mappedSupport = "";
290     if (DelayedSingleton<CommonEventSupportMapper>::GetInstance()->GetMappedSupport(
291         eventRecord.commonEventData->GetWant().GetAction(), mappedSupport)) {
292         Want want = eventRecord.commonEventData->GetWant();
293         want.SetAction(mappedSupport);
294         CommonEventRecord mappedEventRecord = eventRecord;
295         mappedEventRecord.commonEventData->SetWant(want);
296         controlPtr_->PublishCommonEvent(mappedEventRecord, commonEventListener);
297     }
298 
299     if (time(nullptr) - sysEventTime >= PUBLISH_SYS_EVENT_INTERVAL &&
300         EVENT_COUNT_DISALLOW.find(data.GetWant().GetAction().c_str()) == EVENT_COUNT_DISALLOW.end()) {
301         SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), true);
302         sysEventTime = time(nullptr);
303     }
304 
305     return true;
306 }
307 
SubscribeCommonEvent(const CommonEventSubscribeInfo &subscribeInfo, const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime, const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken, const std::string &bundleName, const int32_t instanceKey, const int64_t startTime)308 bool InnerCommonEventManager::SubscribeCommonEvent(const CommonEventSubscribeInfo &subscribeInfo,
309     const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime,
310     const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken,
311     const std::string &bundleName, const int32_t instanceKey, const int64_t startTime)
312 {
313     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
314     int64_t taskStartTime = SystemTime::GetNowSysTime();
315     EVENT_LOGD("enter %{public}s(pid = %{public}d, uid = %{public}d, userId = %{public}d)",
316         bundleName.c_str(), pid, uid, subscribeInfo.GetUserId());
317 
318     if (subscribeInfo.GetMatchingSkills().CountEvent() == 0) {
319         EVENT_LOGE("the subscriber has no event");
320         return false;
321     }
322     if (commonEventListener == nullptr) {
323         EVENT_LOGE("InnerCommonEventManager::SubscribeCommonEvent:commonEventListener == nullptr");
324         return false;
325     }
326 
327     CommonEventSubscribeInfo subscribeInfo_(subscribeInfo);
328     int32_t userId = subscribeInfo_.GetUserId();
329     EventComeFrom comeFrom;
330     if (!CheckUserId(pid, uid, callerToken, comeFrom, userId)) {
331         return false;
332     }
333     subscribeInfo_.SetUserId(userId);
334 
335     std::shared_ptr<CommonEventSubscribeInfo> sp = std::make_shared<CommonEventSubscribeInfo>(subscribeInfo_);
336 
337     // create EventRecordInfo here
338     EventRecordInfo eventRecordInfo;
339     eventRecordInfo.pid = pid;
340     eventRecordInfo.uid = uid;
341     eventRecordInfo.callerToken = callerToken;
342     eventRecordInfo.bundleName = bundleName;
343     eventRecordInfo.isSubsystem = comeFrom.isSubsystem;
344     eventRecordInfo.isSystemApp = comeFrom.isSystemApp;
345     eventRecordInfo.isProxy = comeFrom.isProxy;
346 
347     // generate subscriber id : pid_uid_subCount_time
348     int64_t now = SystemTime::GetNowSysTime();
349     std::string subId = std::to_string(pid) + "_" + std::to_string(uid) + "_" +
350         std::to_string(instanceKey) + "_" + std::to_string(subCount.load()) + "_" + std::to_string(now);
351     subCount.fetch_add(1);
352     eventRecordInfo.subId = subId;
353     EVENT_LOGI("SubscribeCommonEvent %{public}s(pid = %{public}d, uid = %{public}d, "
354         "userId = %{public}d, instanceKey = %{public}d, subId = %{public}s, "
355         "ffrtCost = %{public}s, taskCost = %{public}s",
356         bundleName.c_str(), pid, uid, subscribeInfo.GetUserId(), instanceKey, subId.c_str(),
357         std::to_string(taskStartTime - startTime).c_str(), std::to_string(now - taskStartTime).c_str());
358 
359     auto record = DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->InsertSubscriber(
360         sp, commonEventListener, recordTime, eventRecordInfo);
361 
362     PublishStickyEvent(sp, record);
363 
364     SendSubscribeHiSysEvent(userId, bundleName, pid, uid, subscribeInfo.GetMatchingSkills().GetEvents());
365     return true;
366 };
367 
UnsubscribeCommonEvent(const sptr<IRemoteObject> &commonEventListener)368 bool InnerCommonEventManager::UnsubscribeCommonEvent(const sptr<IRemoteObject> &commonEventListener)
369 {
370     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
371     EVENT_LOGD("enter");
372 
373     if (commonEventListener == nullptr) {
374         EVENT_LOGE("commonEventListener == nullptr");
375         return false;
376     }
377 
378     if (!controlPtr_) {
379         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
380         return false;
381     }
382 
383     std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(commonEventListener);
384     if (sp) {
385         EVENT_LOGD("Unsubscribe the subscriber who is waiting to receive finish feedback");
386         int32_t code = sp->commonEventData->GetCode();
387         std::string data = sp->commonEventData->GetData();
388         controlPtr_->FinishReceiverAction(sp, code, data, sp->resultAbort);
389     }
390 
391     SendUnSubscribeHiSysEvent(commonEventListener);
392     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->RemoveSubscriber(commonEventListener);
393 
394     return true;
395 }
396 
GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)397 bool InnerCommonEventManager::GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)
398 {
399     EVENT_LOGD("enter");
400 
401     return DelayedSingleton<CommonEventStickyManager>::GetInstance()->GetStickyCommonEvent(event, eventData);
402 }
403 
DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId, std::vector<std::string> &state)404 void InnerCommonEventManager::DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId,
405     std::vector<std::string> &state)
406 {
407     EVENT_LOGD("enter");
408 
409     switch (dumpType) {
410         case DumpEventType::SUBSCRIBER: {
411             DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
412             break;
413         }
414         case DumpEventType::STICKY: {
415             DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
416             break;
417         }
418         case DumpEventType::PENDING: {
419             if (controlPtr_) {
420                 controlPtr_->DumpState(event, userId, state);
421             }
422             break;
423         }
424         case DumpEventType::HISTORY: {
425             if (controlPtr_) {
426                 controlPtr_->DumpHistoryState(event, userId, state);
427             }
428             break;
429         }
430         default: {
431             DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
432             DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
433             if (controlPtr_) {
434                 controlPtr_->DumpState(event, userId, state);
435                 controlPtr_->DumpHistoryState(event, userId, state);
436             }
437             break;
438         }
439     }
440 
441     if (!controlPtr_) {
442         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
443     }
444 }
445 
FinishReceiver( const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &receiverData, const bool &abortEvent)446 void InnerCommonEventManager::FinishReceiver(
447     const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &receiverData, const bool &abortEvent)
448 {
449     EVENT_LOGD("enter");
450 
451     if (!controlPtr_) {
452         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
453         return;
454     }
455 
456     std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(proxy);
457     if (sp) {
458         controlPtr_->FinishReceiverAction(sp, code, receiverData, abortEvent);
459     }
460 
461     return;
462 }
463 
Freeze(const uid_t &uid)464 void InnerCommonEventManager::Freeze(const uid_t &uid)
465 {
466     EVENT_LOGD("enter");
467     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
468         uid, true, SystemTime::GetNowSysTime());
469 }
470 
Unfreeze(const uid_t &uid)471 void InnerCommonEventManager::Unfreeze(const uid_t &uid)
472 {
473     EVENT_LOGD("enter");
474     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(uid, false);
475     if (!controlPtr_) {
476         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
477         return;
478     }
479     controlPtr_->PublishFreezeCommonEvent(uid);
480 }
481 
SetFreezeStatus(std::set<int> pidList, bool isFreeze)482 bool InnerCommonEventManager::SetFreezeStatus(std::set<int> pidList, bool isFreeze)
483 {
484     EVENT_LOGD("enter");
485     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
486         pidList, isFreeze, SystemTime::GetNowSysTime());
487     if (!isFreeze) {
488         if (!controlPtr_) {
489             EVENT_LOGE("CommonEventControlManager ptr is nullptr");
490             return false;
491         }
492         return controlPtr_->PublishFreezeCommonEvent(pidList);
493     }
494     return true;
495 }
496 
UnfreezeAll()497 void InnerCommonEventManager::UnfreezeAll()
498 {
499     EVENT_LOGD("enter");
500     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateAllFreezeInfos(false);
501     if (!controlPtr_) {
502         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
503         return;
504     }
505     controlPtr_->PublishAllFreezeCommonEvents();
506 }
507 
ProcessStickyEvent(const CommonEventRecord &record)508 bool InnerCommonEventManager::ProcessStickyEvent(const CommonEventRecord &record)
509 {
510     EVENT_LOGD("enter");
511     const std::string permission = "ohos.permission.COMMONEVENT_STICKY";
512     bool result = AccessTokenHelper::VerifyAccessToken(record.eventRecordInfo.callerToken, permission);
513     // Only subsystems and system apps with permissions can publish sticky common events
514     if ((result && record.eventRecordInfo.isSystemApp) ||
515         (!record.eventRecordInfo.isProxy && record.eventRecordInfo.isSubsystem)) {
516         DelayedSingleton<CommonEventStickyManager>::GetInstance()->UpdateStickyEvent(record);
517         return true;
518     } else {
519         EVENT_LOGE("No permission to send a sticky common event from %{public}s (pid = %{public}d, uid = %{public}d)",
520             record.eventRecordInfo.bundleName.c_str(), record.eventRecordInfo.pid, record.eventRecordInfo.uid);
521         return false;
522     }
523 }
524 
SetSystemUserId(const uid_t &uid, EventComeFrom &comeFrom, int32_t &userId)525 void InnerCommonEventManager::SetSystemUserId(const uid_t &uid, EventComeFrom &comeFrom, int32_t &userId)
526 {
527     if (userId == CURRENT_USER) {
528         DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
529     } else if (userId == UNDEFINED_USER) {
530         if (comeFrom.isSubsystem) {
531             userId = ALL_USER;
532         } else {
533             DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
534             if (userId >= SUBSCRIBE_USER_SYSTEM_BEGIN && userId <= SUBSCRIBE_USER_SYSTEM_END) {
535                 userId = ALL_USER;
536             }
537         }
538     }
539 }
540 
CheckUserId(const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken, EventComeFrom &comeFrom, int32_t &userId)541 bool InnerCommonEventManager::CheckUserId(const pid_t &pid, const uid_t &uid,
542     const Security::AccessToken::AccessTokenID &callerToken, EventComeFrom &comeFrom, int32_t &userId)
543 {
544     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
545     EVENT_LOGD("enter");
546 
547     if (userId < UNDEFINED_USER) {
548         EVENT_LOGE("Invalid User ID %{public}d", userId);
549         return false;
550     }
551 
552     comeFrom.isSubsystem = AccessTokenHelper::VerifyNativeToken(callerToken);
553 
554     if (!comeFrom.isSubsystem || supportCheckSaPermission_.compare("true") == 0) {
555         if (AccessTokenHelper::VerifyShellToken(callerToken)) {
556             const std::string permission = "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT";
557             comeFrom.isCemShell = AccessTokenHelper::VerifyAccessToken(callerToken, permission);
558         } else {
559             comeFrom.isSystemApp = DelayedSingleton<BundleManagerHelper>::GetInstance()->CheckIsSystemAppByUid(uid);
560         }
561     }
562     comeFrom.isProxy = pid == UNDEFINED_PID;
563     if ((comeFrom.isSystemApp || comeFrom.isSubsystem || comeFrom.isCemShell) && !comeFrom.isProxy) {
564         SetSystemUserId(uid, comeFrom, userId);
565     } else {
566         if (userId == UNDEFINED_USER) {
567             DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
568         } else {
569             EVENT_LOGE("No permission to subscribe or send a common event to another user from uid = %{public}d", uid);
570             return false;
571         }
572     }
573 
574     return true;
575 }
576 
PublishStickyEvent( const std::shared_ptr<CommonEventSubscribeInfo> &sp, const std::shared_ptr<EventSubscriberRecord> &subscriberRecord)577 bool InnerCommonEventManager::PublishStickyEvent(
578     const std::shared_ptr<CommonEventSubscribeInfo> &sp, const std::shared_ptr<EventSubscriberRecord> &subscriberRecord)
579 {
580     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
581     EVENT_LOGD("enter");
582 
583     if (!sp) {
584         EVENT_LOGE("sp is null");
585         return false;
586     }
587 
588     if (!subscriberRecord) {
589         EVENT_LOGE("subscriberRecord is null");
590         return false;
591     }
592 
593     std::vector<std::shared_ptr<CommonEventRecord>> commonEventRecords;
594     if (DelayedSingleton<CommonEventStickyManager>::GetInstance()->FindStickyEvents(sp, commonEventRecords)) {
595         return false;
596     }
597 
598     for (auto commonEventRecord : commonEventRecords) {
599         if (!commonEventRecord) {
600             EVENT_LOGW("commonEventRecord is nullptr and get next");
601             continue;
602         }
603         EVENT_LOGD("publish sticky event : %{public}s",
604             commonEventRecord->commonEventData->GetWant().GetAction().c_str());
605 
606         if (!commonEventRecord->publishInfo->GetBundleName().empty() &&
607             commonEventRecord->publishInfo->GetBundleName() != subscriberRecord->eventRecordInfo.bundleName) {
608             EVENT_LOGW("commonEventRecord assigned to bundleName[%{public}s]",
609                 commonEventRecord->publishInfo->GetBundleName().c_str());
610             continue;
611         }
612 
613         commonEventRecord->publishInfo->SetOrdered(false);
614         if (!controlPtr_) {
615             EVENT_LOGE("CommonEventControlManager ptr is nullptr");
616             return false;
617         }
618         controlPtr_->PublishStickyCommonEvent(*commonEventRecord, subscriberRecord);
619     }
620 
621     return true;
622 }
623 
HiDump(const std::vector<std::u16string> &args, std::string &result)624 void InnerCommonEventManager::HiDump(const std::vector<std::u16string> &args, std::string &result)
625 {
626     if (args.size() == 0 || args.size() > HIDUMP_OPTION_MAX_SIZE) {
627         result = "error: unknown option.";
628         return;
629     }
630     std::string cmd = Str16ToStr8(args[0]);
631     if (HIDUMPER_CMD_MAP.find(cmd) == HIDUMPER_CMD_MAP.end()) {
632         result = "error: unknown option.";
633         return;
634     }
635     std::string event;
636     if (args.size() == HIDUMP_OPTION_MAX_SIZE) {
637         event = Str16ToStr8(args[1]);
638     }
639     char cmdValue = HIDUMPER_CMD_MAP.find(cmd)->second;
640     switch (cmdValue) {
641         case 'h' :
642             result = HIDUMPER_HELP_MSG;
643             return;
644         case 'a' :
645             event = "";
646             break;
647         case 'e' :
648             if (event.empty()) {
649                 result = "error: request a event value.";
650                 return;
651             }
652             break;
653         default:
654             break;
655     }
656     std::vector<std::string> records;
657     DumpState(DumpEventType::ALL, event, ALL_USER, records);
658     for (const auto &record : records) {
659         result.append(record).append("\n");
660     }
661 }
662 
SendSubscribeHiSysEvent(int32_t userId, const std::string &subscriberName, int32_t pid, int32_t uid, const std::vector<std::string> &events)663 void InnerCommonEventManager::SendSubscribeHiSysEvent(int32_t userId, const std::string &subscriberName, int32_t pid,
664     int32_t uid, const std::vector<std::string> &events)
665 {
666     EventInfo eventInfo;
667     eventInfo.userId = userId;
668     eventInfo.subscriberName = subscriberName;
669     eventInfo.pid = pid;
670     eventInfo.uid = uid;
671     eventInfo.eventName = std::accumulate(events.begin(), events.end(), std::string(""),
672         [events](std::string eventName, const std::string &str) {
673             return (str == events.front()) ? (eventName + str) : (eventName + "," + str);
674         });
675     EventReport::SendHiSysEvent(SUBSCRIBE, eventInfo);
676 }
677 
SendUnSubscribeHiSysEvent(const sptr<IRemoteObject> &commonEventListener)678 void InnerCommonEventManager::SendUnSubscribeHiSysEvent(const sptr<IRemoteObject> &commonEventListener)
679 {
680     auto subscriberRecord = DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->GetSubscriberRecord(
681         commonEventListener);
682     if (subscriberRecord == nullptr) {
683         return;
684     }
685 
686     EventInfo eventInfo;
687     if (subscriberRecord->eventSubscribeInfo != nullptr) {
688         eventInfo.userId = subscriberRecord->eventSubscribeInfo->GetUserId();
689         std::vector<std::string> events = subscriberRecord->eventSubscribeInfo->GetMatchingSkills().GetEvents();
690         eventInfo.eventName = std::accumulate(events.begin(), events.end(), std::string(""),
691             [events](std::string eventName, const std::string &str) {
692                 return (str == events.front()) ? (eventName + str) : (eventName + "," + str);
693             });
694     }
695     eventInfo.subscriberName = subscriberRecord->eventRecordInfo.bundleName;
696     eventInfo.pid = subscriberRecord->eventRecordInfo.pid;
697     eventInfo.uid = static_cast<int32_t>(subscriberRecord->eventRecordInfo.uid);
698     EventReport::SendHiSysEvent(UNSUBSCRIBE, eventInfo);
699 }
700 
SendPublishHiSysEvent(int32_t userId, const std::string &publisherName, int32_t pid, int32_t uid, const std::string &event, bool succeed)701 void InnerCommonEventManager::SendPublishHiSysEvent(int32_t userId, const std::string &publisherName, int32_t pid,
702     int32_t uid, const std::string &event, bool succeed)
703 {
704     EventInfo eventInfo;
705     eventInfo.userId = userId;
706     eventInfo.publisherName = publisherName;
707     eventInfo.pid = pid;
708     eventInfo.uid = uid;
709     eventInfo.eventName = event;
710 
711     if (succeed) {
712         EventReport::SendHiSysEvent(PUBLISH, eventInfo);
713     } else {
714         EventReport::SendHiSysEvent(PUBLISH_ERROR, eventInfo);
715     }
716 }
717 
RemoveStickyCommonEvent(const std::string &event, uint32_t callerUid)718 int32_t InnerCommonEventManager::RemoveStickyCommonEvent(const std::string &event, uint32_t callerUid)
719 {
720     return DelayedSingleton<CommonEventStickyManager>::GetInstance()->RemoveStickyCommonEvent(event, callerUid);
721 }
722 
SetStaticSubscriberState(bool enable)723 int32_t InnerCommonEventManager::SetStaticSubscriberState(bool enable)
724 {
725     if (staticSubscriberManager_ != nullptr) {
726         return staticSubscriberManager_->SetStaticSubscriberState(enable);
727     }
728     return Notification::ERR_NOTIFICATION_CESM_ERROR;
729 }
730 
SetStaticSubscriberState(const std::vector<std::string> &events, bool enable)731 int32_t InnerCommonEventManager::SetStaticSubscriberState(const std::vector<std::string> &events, bool enable)
732 {
733     if (staticSubscriberManager_ != nullptr) {
734         return staticSubscriberManager_->SetStaticSubscriberState(events, enable);
735     }
736     return Notification::ERR_NOTIFICATION_CESM_ERROR;
737 }
738 }  // namespace EventFwk
739 }  // namespace OHOS
740