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