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