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_LOGD("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=%{public}s to %{public}d",
255 bundleName.c_str(), pid, uid, data.GetWant().GetAction().c_str(), user);
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 return true;
299 }
300
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)301 bool InnerCommonEventManager::SubscribeCommonEvent(const CommonEventSubscribeInfo &subscribeInfo,
302 const sptr<IRemoteObject> &commonEventListener, const struct tm &recordTime,
303 const pid_t &pid, const uid_t &uid, const Security::AccessToken::AccessTokenID &callerToken,
304 const std::string &bundleName, const int32_t instanceKey, const int64_t startTime)
305 {
306 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
307 int64_t taskStartTime = SystemTime::GetNowSysTime();
308 EVENT_LOGD("enter %{public}s(pid = %{public}d, uid = %{public}d, userId = %{public}d)",
309 bundleName.c_str(), pid, uid, subscribeInfo.GetUserId());
310
311 if (subscribeInfo.GetMatchingSkills().CountEvent() == 0) {
312 EVENT_LOGE("the subscriber has no event");
313 return false;
314 }
315 if (commonEventListener == nullptr) {
316 EVENT_LOGE("commonEventListener is nullptr");
317 return false;
318 }
319
320 CommonEventSubscribeInfo subscribeInfo_(subscribeInfo);
321 int32_t userId = subscribeInfo_.GetUserId();
322 EventComeFrom comeFrom;
323 if (!CheckUserId(pid, uid, callerToken, comeFrom, userId)) {
324 return false;
325 }
326 subscribeInfo_.SetUserId(userId);
327
328 std::shared_ptr<CommonEventSubscribeInfo> sp = std::make_shared<CommonEventSubscribeInfo>(subscribeInfo_);
329
330 // create EventRecordInfo here
331 EventRecordInfo eventRecordInfo;
332 eventRecordInfo.pid = pid;
333 eventRecordInfo.uid = uid;
334 eventRecordInfo.callerToken = callerToken;
335 eventRecordInfo.bundleName = bundleName;
336 eventRecordInfo.isSubsystem = comeFrom.isSubsystem;
337 eventRecordInfo.isSystemApp = comeFrom.isSystemApp;
338 eventRecordInfo.isProxy = comeFrom.isProxy;
339
340 // generate subscriber id : pid_uid_instanceKey_subCount_time
341 int64_t now = SystemTime::GetNowSysTime();
342 std::string subId = std::to_string(pid) + "_" + std::to_string(uid) + "_" +
343 std::to_string(instanceKey) + "_" + std::to_string(subCount.load()) + "_" + std::to_string(now);
344 subCount.fetch_add(1);
345 eventRecordInfo.subId = subId;
346 auto record = DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->InsertSubscriber(
347 sp, commonEventListener, recordTime, eventRecordInfo);
348
349 now = SystemTime::GetNowSysTime();
350 EVENT_LOGI("Subscribe %{public}s(userId = %{public}d, subId = %{public}s, "
351 "ffrtCost %{public}s ms, taskCost %{public}s ms)", bundleName.c_str(), userId, subId.c_str(),
352 std::to_string(taskStartTime - startTime).c_str(), std::to_string(now - taskStartTime).c_str());
353 PublishStickyEvent(sp, record);
354 return true;
355 };
356
UnsubscribeCommonEvent(const sptr<IRemoteObject> & commonEventListener)357 bool InnerCommonEventManager::UnsubscribeCommonEvent(const sptr<IRemoteObject> &commonEventListener)
358 {
359 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
360 EVENT_LOGD("enter");
361
362 if (commonEventListener == nullptr) {
363 EVENT_LOGE("commonEventListener is nullptr");
364 return false;
365 }
366
367 if (!controlPtr_) {
368 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
369 return false;
370 }
371
372 std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(commonEventListener);
373 if (sp) {
374 EVENT_LOGD("Unsubscribe the subscriber who is waiting to receive finish feedback");
375 int32_t code = sp->commonEventData->GetCode();
376 std::string data = sp->commonEventData->GetData();
377 controlPtr_->FinishReceiverAction(sp, code, data, sp->resultAbort);
378 }
379 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->RemoveSubscriber(commonEventListener);
380 return true;
381 }
382
GetStickyCommonEvent(const std::string & event,CommonEventData & eventData)383 bool InnerCommonEventManager::GetStickyCommonEvent(const std::string &event, CommonEventData &eventData)
384 {
385 EVENT_LOGD("enter");
386
387 return DelayedSingleton<CommonEventStickyManager>::GetInstance()->GetStickyCommonEvent(event, eventData);
388 }
389
DumpState(const uint8_t & dumpType,const std::string & event,const int32_t & userId,std::vector<std::string> & state)390 void InnerCommonEventManager::DumpState(const uint8_t &dumpType, const std::string &event, const int32_t &userId,
391 std::vector<std::string> &state)
392 {
393 EVENT_LOGD("enter");
394
395 switch (dumpType) {
396 case DumpEventType::SUBSCRIBER: {
397 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
398 break;
399 }
400 case DumpEventType::STICKY: {
401 DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
402 break;
403 }
404 case DumpEventType::PENDING: {
405 if (controlPtr_) {
406 controlPtr_->DumpState(event, userId, state);
407 }
408 break;
409 }
410 case DumpEventType::HISTORY: {
411 break;
412 }
413 default: {
414 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->DumpState(event, userId, state);
415 DelayedSingleton<CommonEventStickyManager>::GetInstance()->DumpState(event, userId, state);
416 if (controlPtr_) {
417 controlPtr_->DumpState(event, userId, state);
418 }
419 break;
420 }
421 }
422
423 if (!controlPtr_) {
424 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
425 }
426 }
427
FinishReceiver(const sptr<IRemoteObject> & proxy,const int32_t & code,const std::string & receiverData,const bool & abortEvent)428 void InnerCommonEventManager::FinishReceiver(
429 const sptr<IRemoteObject> &proxy, const int32_t &code, const std::string &receiverData, const bool &abortEvent)
430 {
431 EVENT_LOGD("enter");
432
433 if (!controlPtr_) {
434 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
435 return;
436 }
437
438 std::shared_ptr<OrderedEventRecord> sp = controlPtr_->GetMatchingOrderedReceiver(proxy);
439 if (sp) {
440 controlPtr_->FinishReceiverAction(sp, code, receiverData, abortEvent);
441 }
442
443 return;
444 }
445
Freeze(const uid_t & uid)446 void InnerCommonEventManager::Freeze(const uid_t &uid)
447 {
448 EVENT_LOGD("enter");
449 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
450 uid, true, SystemTime::GetNowSysTime());
451 }
452
Unfreeze(const uid_t & uid)453 void InnerCommonEventManager::Unfreeze(const uid_t &uid)
454 {
455 EVENT_LOGD("enter");
456 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(uid, false);
457 if (!controlPtr_) {
458 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
459 return;
460 }
461 controlPtr_->PublishFreezeCommonEvent(uid);
462 }
463
SetFreezeStatus(std::set<int> pidList,bool isFreeze)464 bool InnerCommonEventManager::SetFreezeStatus(std::set<int> pidList, bool isFreeze)
465 {
466 EVENT_LOGD("enter");
467 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateFreezeInfo(
468 pidList, isFreeze, SystemTime::GetNowSysTime());
469 if (!isFreeze) {
470 if (!controlPtr_) {
471 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
472 return false;
473 }
474 return controlPtr_->PublishFreezeCommonEvent(pidList);
475 }
476 return true;
477 }
478
UnfreezeAll()479 void InnerCommonEventManager::UnfreezeAll()
480 {
481 EVENT_LOGD("enter");
482 DelayedSingleton<CommonEventSubscriberManager>::GetInstance()->UpdateAllFreezeInfos(false);
483 if (!controlPtr_) {
484 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
485 return;
486 }
487 controlPtr_->PublishAllFreezeCommonEvents();
488 }
489
ProcessStickyEvent(const CommonEventRecord & record)490 bool InnerCommonEventManager::ProcessStickyEvent(const CommonEventRecord &record)
491 {
492 EVENT_LOGD("enter");
493 const std::string permission = "ohos.permission.COMMONEVENT_STICKY";
494 bool result = AccessTokenHelper::VerifyAccessToken(record.eventRecordInfo.callerToken, permission);
495 // Only subsystems and system apps with permissions can publish sticky common events
496 if ((result && record.eventRecordInfo.isSystemApp) ||
497 (!record.eventRecordInfo.isProxy && record.eventRecordInfo.isSubsystem)) {
498 DelayedSingleton<CommonEventStickyManager>::GetInstance()->UpdateStickyEvent(record);
499 return true;
500 } else {
501 EVENT_LOGE("No permission to send a sticky common event from %{public}s (pid = %{public}d, uid = %{public}d)",
502 record.eventRecordInfo.bundleName.c_str(), record.eventRecordInfo.pid, record.eventRecordInfo.uid);
503 return false;
504 }
505 }
506
SetSystemUserId(const uid_t & uid,EventComeFrom & comeFrom,int32_t & userId)507 void InnerCommonEventManager::SetSystemUserId(const uid_t &uid, EventComeFrom &comeFrom, int32_t &userId)
508 {
509 if (userId == CURRENT_USER) {
510 DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
511 } else if (userId == UNDEFINED_USER) {
512 if (comeFrom.isSubsystem) {
513 userId = ALL_USER;
514 } else {
515 DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
516 if (userId >= SUBSCRIBE_USER_SYSTEM_BEGIN && userId <= SUBSCRIBE_USER_SYSTEM_END) {
517 userId = ALL_USER;
518 }
519 }
520 }
521 }
522
CheckUserId(const pid_t & pid,const uid_t & uid,const Security::AccessToken::AccessTokenID & callerToken,EventComeFrom & comeFrom,int32_t & userId)523 bool InnerCommonEventManager::CheckUserId(const pid_t &pid, const uid_t &uid,
524 const Security::AccessToken::AccessTokenID &callerToken, EventComeFrom &comeFrom, int32_t &userId)
525 {
526 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
527 EVENT_LOGD("enter");
528
529 if (userId < UNDEFINED_USER) {
530 EVENT_LOGE("Invalid User ID %{public}d", userId);
531 return false;
532 }
533
534 comeFrom.isSubsystem = AccessTokenHelper::VerifyNativeToken(callerToken);
535
536 if (!comeFrom.isSubsystem || supportCheckSaPermission_.compare("true") == 0) {
537 if (AccessTokenHelper::VerifyShellToken(callerToken)) {
538 comeFrom.isCemShell = true;
539 } else {
540 comeFrom.isSystemApp = DelayedSingleton<BundleManagerHelper>::GetInstance()->CheckIsSystemAppByUid(uid);
541 }
542 }
543 comeFrom.isProxy = pid == UNDEFINED_PID;
544 if ((comeFrom.isSystemApp || comeFrom.isSubsystem || comeFrom.isCemShell) && !comeFrom.isProxy) {
545 SetSystemUserId(uid, comeFrom, userId);
546 } else {
547 if (userId == UNDEFINED_USER) {
548 DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId);
549 } else {
550 EVENT_LOGE("No permission to subscribe or send a common event to another user from uid = %{public}d", uid);
551 return false;
552 }
553 }
554
555 return true;
556 }
557
PublishStickyEvent(const std::shared_ptr<CommonEventSubscribeInfo> & sp,const std::shared_ptr<EventSubscriberRecord> & subscriberRecord)558 bool InnerCommonEventManager::PublishStickyEvent(
559 const std::shared_ptr<CommonEventSubscribeInfo> &sp, const std::shared_ptr<EventSubscriberRecord> &subscriberRecord)
560 {
561 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
562 EVENT_LOGD("enter");
563
564 if (!sp) {
565 EVENT_LOGE("sp is null");
566 return false;
567 }
568
569 if (!subscriberRecord) {
570 EVENT_LOGE("subscriberRecord is null");
571 return false;
572 }
573
574 std::vector<std::shared_ptr<CommonEventRecord>> commonEventRecords;
575 if (DelayedSingleton<CommonEventStickyManager>::GetInstance()->FindStickyEvents(sp, commonEventRecords)) {
576 return false;
577 }
578
579 for (auto commonEventRecord : commonEventRecords) {
580 if (!commonEventRecord) {
581 EVENT_LOGW("commonEventRecord is nullptr and get next");
582 continue;
583 }
584 EVENT_LOGI("Publish sticky event : %{public}s",
585 commonEventRecord->commonEventData->GetWant().GetAction().c_str());
586
587 if (!commonEventRecord->publishInfo->GetBundleName().empty() &&
588 commonEventRecord->publishInfo->GetBundleName() != subscriberRecord->eventRecordInfo.bundleName) {
589 EVENT_LOGW("Event only assigned to [%{public}s]",
590 commonEventRecord->publishInfo->GetBundleName().c_str());
591 continue;
592 }
593
594 commonEventRecord->publishInfo->SetOrdered(false);
595 if (!controlPtr_) {
596 EVENT_LOGE("CommonEventControlManager ptr is nullptr");
597 return false;
598 }
599 controlPtr_->PublishStickyCommonEvent(*commonEventRecord, subscriberRecord);
600 }
601
602 return true;
603 }
604
HiDump(const std::vector<std::u16string> & args,std::string & result)605 void InnerCommonEventManager::HiDump(const std::vector<std::u16string> &args, std::string &result)
606 {
607 if (args.size() == 0 || args.size() > HIDUMP_OPTION_MAX_SIZE) {
608 result = "error: unknown option.";
609 return;
610 }
611 std::string cmd = Str16ToStr8(args[0]);
612 if (HIDUMPER_CMD_MAP.find(cmd) == HIDUMPER_CMD_MAP.end()) {
613 result = "error: unknown option.";
614 return;
615 }
616 std::string event;
617 if (args.size() == HIDUMP_OPTION_MAX_SIZE) {
618 event = Str16ToStr8(args[1]);
619 }
620 char cmdValue = HIDUMPER_CMD_MAP.find(cmd)->second;
621 switch (cmdValue) {
622 case 'h' :
623 result = HIDUMPER_HELP_MSG;
624 return;
625 case 'a' :
626 event = "";
627 break;
628 case 'e' :
629 if (event.empty()) {
630 result = "error: request a event value.";
631 return;
632 }
633 break;
634 default:
635 break;
636 }
637 std::vector<std::string> records;
638 DumpState(DumpEventType::ALL, event, ALL_USER, records);
639 for (const auto &record : records) {
640 result.append(record).append("\n");
641 }
642 }
643
SendPublishHiSysEvent(int32_t userId,const std::string & publisherName,int32_t pid,int32_t uid,const std::string & event,bool succeed)644 void InnerCommonEventManager::SendPublishHiSysEvent(int32_t userId, const std::string &publisherName, int32_t pid,
645 int32_t uid, const std::string &event, bool succeed)
646 {
647 EventInfo eventInfo;
648 eventInfo.userId = userId;
649 eventInfo.publisherName = publisherName;
650 eventInfo.pid = pid;
651 eventInfo.uid = uid;
652 eventInfo.eventName = event;
653
654 if (!succeed) {
655 EventReport::SendHiSysEvent(PUBLISH_ERROR, eventInfo);
656 }
657 }
658
RemoveStickyCommonEvent(const std::string & event,uint32_t callerUid)659 int32_t InnerCommonEventManager::RemoveStickyCommonEvent(const std::string &event, uint32_t callerUid)
660 {
661 return DelayedSingleton<CommonEventStickyManager>::GetInstance()->RemoveStickyCommonEvent(event, callerUid);
662 }
663
SetStaticSubscriberState(bool enable)664 int32_t InnerCommonEventManager::SetStaticSubscriberState(bool enable)
665 {
666 if (staticSubscriberManager_ != nullptr) {
667 return staticSubscriberManager_->SetStaticSubscriberState(enable);
668 }
669 return Notification::ERR_NOTIFICATION_CESM_ERROR;
670 }
671
SetStaticSubscriberState(const std::vector<std::string> & events,bool enable)672 int32_t InnerCommonEventManager::SetStaticSubscriberState(const std::vector<std::string> &events, bool enable)
673 {
674 if (staticSubscriberManager_ != nullptr) {
675 return staticSubscriberManager_->SetStaticSubscriberState(events, enable);
676 }
677 return Notification::ERR_NOTIFICATION_CESM_ERROR;
678 }
679 } // namespace EventFwk
680 } // namespace OHOS
681