• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_trace_wrapper.h"
27 #include "event_report.h"
28 #include "hitrace_meter_adapter.h"
29 #include "ipc_skeleton.h"
30 #include "nlohmann/json.hpp"
31 #include "os_account_manager_helper.h"
32 #include "parameters.h"
33 #include "system_time.h"
34 #include "want.h"
35 #include <fstream>
36 #include "securec.h"
37 #ifdef CONFIG_POLICY_ENABLE
38 #include "config_policy_utils.h"
39 #endif
40 
41 
42 namespace OHOS {
43 namespace EventFwk {
44 namespace {
45 const std::string NOTIFICATION_CES_CHECK_SA_PERMISSION = "notification.ces.check.sa.permission";
46 }  // namespace
47 
48 static const int32_t PUBLISH_SYS_EVENT_INTERVAL = 10;  // 10s
49 #ifdef CONFIG_POLICY_ENABLE
50     constexpr static const char* CONFIG_FILE = "etc/notification/common_event_config.json";
51 #else
52     constexpr static const char* CONFIG_FILE = "system/etc/notification/common_event_config.json";
53 #endif
54 
InnerCommonEventManager()55 InnerCommonEventManager::InnerCommonEventManager() : controlPtr_(std::make_shared<CommonEventControlManager>()),
56     staticSubscriberManager_(std::make_shared<StaticSubscriberManager>())
57 {
58     supportCheckSaPermission_ = OHOS::system::GetParameter(NOTIFICATION_CES_CHECK_SA_PERMISSION, "false");
59     if (!GetJsonByFilePath(CONFIG_FILE, eventConfigJson_)) {
60         EVENT_LOGE("Failed to get config file.");
61     }
62 
63     getCcmPublishControl();
64 }
65 
66 constexpr char HIDUMPER_HELP_MSG[] =
67     "Usage:dump <command> [options]\n"
68     "Description:\n"
69     "  -h, --help                   list available commands\n"
70     "  -a, --all                    dump the info of all events\n"
71     "  -e, --event <name>           dump the info of a specified event\n";
72 
73 const std::unordered_map<std::string, char> HIDUMPER_CMD_MAP = {
74     { "--help", 'h'},
75     { "--all", 'a'},
76     { "--event", 'e'},
77     { "-h", 'h' },
78     { "-a", 'a' },
79     { "-e", 'e' },
80 };
81 
82 const std::map<std::string, std::string> EVENT_COUNT_DISALLOW = {
83     { CommonEventSupport::COMMON_EVENT_TIME_TICK, "usual.event.TIME_TICK" },
84 };
85 
86 constexpr size_t HIDUMP_OPTION_MAX_SIZE = 2;
87 
GetJsonFromFile(const char * path,nlohmann::json & root)88 bool InnerCommonEventManager::GetJsonFromFile(const char *path, nlohmann::json &root)
89 {
90     std::ifstream file(path);
91     if (!file.good()) {
92         EVENT_LOGE("Failed to open file %{public}s.", path);
93         return false;
94     }
95     root = nlohmann::json::parse(file, nullptr, false);
96     file.close();
97     if (root.is_discarded() || !root.is_structured()) {
98         EVENT_LOGE("Failed to parse json from file %{public}s.", path);
99         return false;
100     }
101     if (root.is_null() || root.empty() || !root.is_object()) {
102         EVENT_LOGE("GetJsonFromFile fail as invalid root.");
103         return false;
104     }
105     return true;
106 }
107 
GetJsonByFilePath(const char * filePath,std::vector<nlohmann::json> & roots)108 bool InnerCommonEventManager::GetJsonByFilePath(const char *filePath, std::vector<nlohmann::json> &roots)
109 {
110     EVENT_LOGD("Get json value by file path.");
111     if (filePath == nullptr) {
112         EVENT_LOGE("GetJsonByFilePath fail as filePath is null.");
113         return false;
114     }
115     bool ret = false;
116     nlohmann::json localRoot;
117 #ifdef CONFIG_POLICY_ENABLE
118     CfgFiles *cfgFiles = GetCfgFiles(filePath);
119     if (cfgFiles == nullptr) {
120         EVENT_LOGE("Not found file");
121         return false;
122     }
123 
124     for (int32_t i = 0; i <= MAX_CFG_POLICY_DIRS_CNT - 1; i++) {
125         if (cfgFiles->paths[i] && *(cfgFiles->paths[i]) != '\0' && GetJsonFromFile(cfgFiles->paths[i], localRoot)) {
126             roots.push_back(localRoot);
127             ret = true;
128         }
129     }
130     FreeCfgFiles(cfgFiles);
131 #else
132     EVENT_LOGD("Use default config file");
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     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
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("pid=%{public}d publish %{public}s to %{public}d", pid, data.GetWant().GetAction().c_str(), user);
255 
256     if (staticSubscriberManager_ != nullptr) {
257         staticSubscriberManager_->PublishCommonEvent(data, publishInfo, callerToken, user, service, bundleName);
258     }
259 
260     CommonEventRecord eventRecord;
261     eventRecord.commonEventData = std::make_shared<CommonEventData>(data);
262     eventRecord.publishInfo = std::make_shared<CommonEventPublishInfo>(publishInfo);
263     eventRecord.recordTime = recordTime;
264     eventRecord.eventRecordInfo.pid = pid;
265     eventRecord.eventRecordInfo.uid = uid;
266     eventRecord.eventRecordInfo.callerToken = callerToken;
267     eventRecord.userId = user;
268     eventRecord.eventRecordInfo.bundleName = bundleName;
269     eventRecord.eventRecordInfo.isSubsystem = comeFrom.isSubsystem;
270     eventRecord.eventRecordInfo.isSystemApp = (comeFrom.isSystemApp || comeFrom.isCemShell);
271     eventRecord.eventRecordInfo.isProxy = comeFrom.isProxy;
272     eventRecord.isSystemEvent = isSystemEvent;
273 
274     if (publishInfo.IsSticky()) {
275         if (!ProcessStickyEvent(eventRecord)) {
276             SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
277             return false;
278         }
279     }
280 
281     if (!controlPtr_) {
282         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
283         SendPublishHiSysEvent(user, bundleName, pid, uid, data.GetWant().GetAction(), false);
284         return false;
285     }
286     controlPtr_->PublishCommonEvent(eventRecord, commonEventListener);
287 
288     std::string mappedSupport = "";
289     if (DelayedSingleton<CommonEventSupportMapper>::GetInstance()->GetMappedSupport(
290         eventRecord.commonEventData->GetWant().GetAction(), mappedSupport)) {
291         Want want = eventRecord.commonEventData->GetWant();
292         want.SetAction(mappedSupport);
293         CommonEventRecord mappedEventRecord = eventRecord;
294         mappedEventRecord.commonEventData->SetWant(want);
295         controlPtr_->PublishCommonEvent(mappedEventRecord, commonEventListener);
296     }
297     return true;
298 }
299 
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)300 bool InnerCommonEventManager::SubscribeCommonEvent(const CommonEventSubscribeInfo &subscribeInfo,
301     const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime,
302     const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken,
303     const std::string &bundleName, const int32_t instanceKey, const int64_t startTime)
304 {
305     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
306     int64_t taskStartTime = SystemTime::GetNowSysTime();
307     EVENT_LOGD("enter %{public}s(pid = %{public}d, uid = %{public}d, userId = %{public}d)",
308         bundleName.c_str(), pid, uid, subscribeInfo.GetUserId());
309 
310     if (subscribeInfo.GetMatchingSkills().CountEvent() == 0) {
311         EVENT_LOGE("the subscriber has no event");
312         return false;
313     }
314     if (commonEventListener == nullptr) {
315         EVENT_LOGE("commonEventListener is nullptr");
316         return false;
317     }
318 
319     CommonEventSubscribeInfo subscribeInfo_(subscribeInfo);
320     int32_t userId = subscribeInfo_.GetUserId();
321     EventComeFrom comeFrom;
322     if (!CheckUserId(pid, uid, callerToken, comeFrom, userId)) {
323         return false;
324     }
325     subscribeInfo_.SetUserId(userId);
326 
327     std::shared_ptr<CommonEventSubscribeInfo> sp = std::make_shared<CommonEventSubscribeInfo>(subscribeInfo_);
328 
329     // create EventRecordInfo here
330     EventRecordInfo eventRecordInfo;
331     eventRecordInfo.pid = pid;
332     eventRecordInfo.uid = uid;
333     eventRecordInfo.callerToken = callerToken;
334     eventRecordInfo.bundleName = bundleName;
335     eventRecordInfo.isSubsystem = comeFrom.isSubsystem;
336     eventRecordInfo.isSystemApp = comeFrom.isSystemApp;
337     eventRecordInfo.isProxy = comeFrom.isProxy;
338 
339     // generate subscriber id : pid_uid_instanceKey_subCount_time
340     int64_t now = SystemTime::GetNowSysTime();
341     std::string subId = std::to_string(pid) + "_" + std::to_string(uid) + "_" +
342         std::to_string(instanceKey) + "_" + std::to_string(subCount.load()) + "_" + std::to_string(now);
343     subCount.fetch_add(1);
344     eventRecordInfo.subId = subId;
345     auto record = DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->InsertSubscriber(
346         sp, commonEventListener, recordTime, eventRecordInfo);
347 
348     now = SystemTime::GetNowSysTime();
349     EVENT_LOGI("Subscribe %{public}s(userId = %{public}d, subId = %{public}s, "
350         "ffrtCost %{public}s ms, taskCost %{public}s ms)", bundleName.c_str(), userId, subId.c_str(),
351         std::to_string(taskStartTime - startTime).c_str(), std::to_string(now - taskStartTime).c_str());
352     PublishStickyEvent(sp, record);
353     return true;
354 };
355 
UnsubscribeCommonEvent(const sptr<IRemoteObject> & commonEventListener)356 bool InnerCommonEventManager::UnsubscribeCommonEvent(const sptr<IRemoteObject> &commonEventListener)
357 {
358     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
359     EVENT_LOGD("enter");
360 
361     if (commonEventListener == nullptr) {
362         EVENT_LOGE("commonEventListener is nullptr");
363         return false;
364     }
365 
366     if (!controlPtr_) {
367         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
368         return false;
369     }
370 
371     std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(commonEventListener);
372     if (sp) {
373         EVENT_LOGD("Unsubscribe the subscriber who is waiting to receive finish feedback");
374         int32_t code = sp->commonEventData->GetCode();
375         std::string data = sp->commonEventData->GetData();
376         controlPtr_->FinishReceiverAction(sp, code, data, sp->resultAbort);
377     }
378     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->RemoveSubscriber(commonEventListener);
379     return true;
380 }
381 
GetStickyCommonEvent(const std::string & event,CommonEventData & eventData)382 bool InnerCommonEventManager::GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)
383 {
384     EVENT_LOGD("enter");
385 
386     return DelayedSingleton<CommonEventStickyManager>::GetInstance()->GetStickyCommonEvent(event, eventData);
387 }
388 
DumpState(const uint8_t & dumpType,const std::string & event,const int32_t & userId,std::vector<std::string> & state)389 void InnerCommonEventManager::DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId,
390     std::vector<std::string> &state)
391 {
392     EVENT_LOGD("enter");
393 
394     switch (dumpType) {
395         case DumpEventType::SUBSCRIBER: {
396             DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
397             break;
398         }
399         case DumpEventType::STICKY: {
400             DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
401             break;
402         }
403         case DumpEventType::PENDING: {
404             if (controlPtr_) {
405                 controlPtr_->DumpState(event, userId, state);
406             }
407             break;
408         }
409         case DumpEventType::HISTORY: {
410             break;
411         }
412         default: {
413             DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
414             DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
415             if (controlPtr_) {
416                 controlPtr_->DumpState(event, userId, state);
417             }
418             break;
419         }
420     }
421 
422     if (!controlPtr_) {
423         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
424     }
425 }
426 
FinishReceiver(const sptr<IRemoteObject> & proxy,const int32_t & code,const std::string & receiverData,const bool & abortEvent)427 void InnerCommonEventManager::FinishReceiver(
428     const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &receiverData, const bool &abortEvent)
429 {
430     EVENT_LOGD("enter");
431 
432     if (!controlPtr_) {
433         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
434         return;
435     }
436 
437     std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(proxy);
438     if (sp) {
439         controlPtr_->FinishReceiverAction(sp, code, receiverData, abortEvent);
440     }
441 
442     return;
443 }
444 
Freeze(const uid_t & uid)445 void InnerCommonEventManager::Freeze(const uid_t &uid)
446 {
447     EVENT_LOGD("enter");
448     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
449         uid, true, SystemTime::GetNowSysTime());
450 }
451 
Unfreeze(const uid_t & uid)452 void InnerCommonEventManager::Unfreeze(const uid_t &uid)
453 {
454     EVENT_LOGD("enter");
455     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(uid, false);
456     if (!controlPtr_) {
457         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
458         return;
459     }
460     controlPtr_->PublishFreezeCommonEvent(uid);
461 }
462 
SetFreezeStatus(std::set<int> pidList,bool isFreeze)463 bool InnerCommonEventManager::SetFreezeStatus(std::set<int> pidList, bool isFreeze)
464 {
465     EVENT_LOGD("enter");
466     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
467         pidList, isFreeze, SystemTime::GetNowSysTime());
468     if (!isFreeze) {
469         if (!controlPtr_) {
470             EVENT_LOGE("CommonEventControlManager ptr is nullptr");
471             return false;
472         }
473         return controlPtr_->PublishFreezeCommonEvent(pidList);
474     }
475     return true;
476 }
477 
UnfreezeAll()478 void InnerCommonEventManager::UnfreezeAll()
479 {
480     EVENT_LOGD("enter");
481     DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateAllFreezeInfos(false);
482     if (!controlPtr_) {
483         EVENT_LOGE("CommonEventControlManager ptr is nullptr");
484         return;
485     }
486     controlPtr_->PublishAllFreezeCommonEvents();
487 }
488 
ProcessStickyEvent(const CommonEventRecord & record)489 bool InnerCommonEventManager::ProcessStickyEvent(const CommonEventRecord &record)
490 {
491     EVENT_LOGD("enter");
492     const std::string permission = "ohos.permission.COMMONEVENT_STICKY";
493     bool result = AccessTokenHelper::VerifyAccessToken(record.eventRecordInfo.callerToken, permission);
494     // Only subsystems and system apps with permissions can publish sticky common events
495     if ((result && record.eventRecordInfo.isSystemApp) ||
496         (!record.eventRecordInfo.isProxy && record.eventRecordInfo.isSubsystem)) {
497         DelayedSingleton<CommonEventStickyManager>::GetInstance()->UpdateStickyEvent(record);
498         return true;
499     } else {
500         EVENT_LOGE("No permission to send a sticky common event from %{public}s (pid = %{public}d, uid = %{public}d)",
501             record.eventRecordInfo.bundleName.c_str(), record.eventRecordInfo.pid, record.eventRecordInfo.uid);
502         return false;
503     }
504 }
505 
SetSystemUserId(const uid_t & uid,EventComeFrom & comeFrom,int32_t & userId)506 void InnerCommonEventManager::SetSystemUserId(const uid_t &uid, EventComeFrom &comeFrom, int32_t &userId)
507 {
508     if (userId == CURRENT_USER) {
509         DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
510     } else if (userId == UNDEFINED_USER) {
511         if (comeFrom.isSubsystem) {
512             userId = ALL_USER;
513         } else {
514             DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
515             if (userId >= SUBSCRIBE_USER_SYSTEM_BEGIN && userId <= SUBSCRIBE_USER_SYSTEM_END) {
516                 userId = ALL_USER;
517             }
518         }
519     }
520 }
521 
CheckUserId(const pid_t & pid,const uid_t & uid,const Security::AccessToken::AccessTokenID & callerToken,EventComeFrom & comeFrom,int32_t & userId)522 bool InnerCommonEventManager::CheckUserId(const pid_t &pid, const uid_t &uid,
523     const Security::AccessToken::AccessTokenID &callerToken, EventComeFrom &comeFrom, int32_t &userId)
524 {
525     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
526     EVENT_LOGD("enter");
527 
528     if (userId < UNDEFINED_USER) {
529         EVENT_LOGE("Invalid User ID %{public}d", userId);
530         return false;
531     }
532 
533     comeFrom.isSubsystem = AccessTokenHelper::VerifyNativeToken(callerToken);
534 
535     if (!comeFrom.isSubsystem || supportCheckSaPermission_.compare("true") == 0) {
536         if (AccessTokenHelper::VerifyShellToken(callerToken)) {
537             comeFrom.isCemShell = true;
538         } else {
539             comeFrom.isSystemApp = DelayedSingleton<BundleManagerHelper>::GetInstance()->CheckIsSystemAppByUid(uid);
540         }
541     }
542     comeFrom.isProxy = pid == UNDEFINED_PID;
543     if ((comeFrom.isSystemApp || comeFrom.isSubsystem || comeFrom.isCemShell) && !comeFrom.isProxy) {
544         SetSystemUserId(uid, comeFrom, userId);
545     } else {
546         if (userId == UNDEFINED_USER) {
547             DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
548         } else {
549             EVENT_LOGE("No permission to subscribe or send a common event to another user from uid = %{public}d", uid);
550             return false;
551         }
552     }
553 
554     return true;
555 }
556 
PublishStickyEvent(const std::shared_ptr<CommonEventSubscribeInfo> & sp,const std::shared_ptr<EventSubscriberRecord> & subscriberRecord)557 bool InnerCommonEventManager::PublishStickyEvent(
558     const std::shared_ptr<CommonEventSubscribeInfo> &sp, const std::shared_ptr<EventSubscriberRecord> &subscriberRecord)
559 {
560     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
561     EVENT_LOGD("enter");
562 
563     if (!sp) {
564         EVENT_LOGE("sp is null");
565         return false;
566     }
567 
568     if (!subscriberRecord) {
569         EVENT_LOGE("subscriberRecord is null");
570         return false;
571     }
572 
573     std::vector<std::shared_ptr<CommonEventRecord>> commonEventRecords;
574     if (DelayedSingleton<CommonEventStickyManager>::GetInstance()->FindStickyEvents(sp, commonEventRecords)) {
575         return false;
576     }
577 
578     for (auto commonEventRecord : commonEventRecords) {
579         if (!commonEventRecord) {
580             EVENT_LOGW("commonEventRecord is nullptr and get next");
581             continue;
582         }
583         EVENT_LOGI("Publish sticky event : %{public}s",
584             commonEventRecord->commonEventData->GetWant().GetAction().c_str());
585 
586         if (!commonEventRecord->publishInfo->GetBundleName().empty() &&
587             commonEventRecord->publishInfo->GetBundleName() != subscriberRecord->eventRecordInfo.bundleName) {
588             EVENT_LOGW("Event only assigned to [%{public}s]",
589                 commonEventRecord->publishInfo->GetBundleName().c_str());
590             continue;
591         }
592 
593         commonEventRecord->publishInfo->SetOrdered(false);
594         if (!controlPtr_) {
595             EVENT_LOGE("CommonEventControlManager ptr is nullptr");
596             return false;
597         }
598         controlPtr_->PublishStickyCommonEvent(*commonEventRecord, subscriberRecord);
599     }
600 
601     return true;
602 }
603 
HiDump(const std::vector<std::u16string> & args,std::string & result)604 void InnerCommonEventManager::HiDump(const std::vector<std::u16string> &args, std::string &result)
605 {
606     if (args.size() == 0 || args.size() > HIDUMP_OPTION_MAX_SIZE) {
607         result = "error: unknown option.";
608         return;
609     }
610     std::string cmd = Str16ToStr8(args[0]);
611     if (HIDUMPER_CMD_MAP.find(cmd) == HIDUMPER_CMD_MAP.end()) {
612         result = "error: unknown option.";
613         return;
614     }
615     std::string event;
616     if (args.size() == HIDUMP_OPTION_MAX_SIZE) {
617         event = Str16ToStr8(args[1]);
618     }
619     char cmdValue = HIDUMPER_CMD_MAP.find(cmd)->second;
620     switch (cmdValue) {
621         case 'h' :
622             result = HIDUMPER_HELP_MSG;
623             return;
624         case 'a' :
625             event = "";
626             break;
627         case 'e' :
628             if (event.empty()) {
629                 result = "error: request a event value.";
630                 return;
631             }
632             break;
633         default:
634             break;
635     }
636     std::vector<std::string> records;
637     DumpState(DumpEventType::ALL, event, ALL_USER, records);
638     for (const auto &record : records) {
639         result.append(record).append("\n");
640     }
641 }
642 
SendPublishHiSysEvent(int32_t userId,const std::string & publisherName,int32_t pid,int32_t uid,const std::string & event,bool succeed)643 void InnerCommonEventManager::SendPublishHiSysEvent(int32_t userId, const std::string &publisherName, int32_t pid,
644     int32_t uid, const std::string &event, bool succeed)
645 {
646     EventInfo eventInfo;
647     eventInfo.userId = userId;
648     eventInfo.publisherName = publisherName;
649     eventInfo.pid = pid;
650     eventInfo.uid = uid;
651     eventInfo.eventName = event;
652 
653     if (!succeed) {
654         EventReport::SendHiSysEvent(PUBLISH_ERROR, eventInfo);
655     }
656 }
657 
RemoveStickyCommonEvent(const std::string & event,uint32_t callerUid)658 int32_t InnerCommonEventManager::RemoveStickyCommonEvent(const std::string &event, uint32_t callerUid)
659 {
660     return DelayedSingleton<CommonEventStickyManager>::GetInstance()->RemoveStickyCommonEvent(event, callerUid);
661 }
662 
SetStaticSubscriberState(bool enable)663 int32_t InnerCommonEventManager::SetStaticSubscriberState(bool enable)
664 {
665     if (staticSubscriberManager_ != nullptr) {
666         return staticSubscriberManager_->SetStaticSubscriberState(enable);
667     }
668     return Notification::ERR_NOTIFICATION_CESM_ERROR;
669 }
670 
SetStaticSubscriberState(const std::vector<std::string> & events,bool enable)671 int32_t InnerCommonEventManager::SetStaticSubscriberState(const std::vector<std::string> &events, bool enable)
672 {
673     if (staticSubscriberManager_ != nullptr) {
674         return staticSubscriberManager_->SetStaticSubscriberState(events, enable);
675     }
676     return Notification::ERR_NOTIFICATION_CESM_ERROR;
677 }
678 }  // namespace EventFwk
679 }  // namespace OHOS
680