1 /*
2 * Copyright (c) 2021-2022 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 "sys_event_service_ohos.h"
17
18 #include <codecvt>
19 #include <regex>
20 #include <set>
21
22 #include "accesstoken_kit.h"
23 #include "bundle_mgr_client.h"
24 #include "data_publisher.h"
25 #include "event_query_wrapper_builder.h"
26 #include "event_threshold_manager.h"
27 #include "if_system_ability_manager.h"
28 #include "ipc_skeleton.h"
29 #include "iservice_registry.h"
30 #include "logger.h"
31 #include "ret_code.h"
32 #include "running_status_log_util.h"
33 #include "string_ex.h"
34 #include "system_ability_definition.h"
35 #include "time_util.h"
36
37 using namespace std;
38 using namespace OHOS::HiviewDFX::EventStore;
39
40 namespace OHOS {
41 namespace HiviewDFX {
42 DEFINE_LOG_TAG("HiView-SysEventService");
43 namespace {
44 constexpr pid_t HID_ROOT = 0;
45 constexpr pid_t HID_SHELL = 2000;
46 constexpr pid_t HID_OHOS = 1000;
47 const std::vector<int> EVENT_TYPES = {1, 2, 3, 4}; // FAULT = 1, STATISTIC = 2 SECURITY = 3, BEHAVIOR = 4
48 constexpr uint32_t INVALID_EVENT_TYPE = 0;
49 const string READ_DFX_SYSEVENT_PERMISSION = "ohos.permission.READ_DFX_SYSEVENT";
50 const string DFX_DUMP_PERMISSION = "ohos.permission.DUMP";
51
MatchContent(int type,const string & rule,const string & match)52 bool MatchContent(int type, const string& rule, const string& match)
53 {
54 if (match.empty()) {
55 return false;
56 }
57 switch (type) {
58 case RuleType::WHOLE_WORD:
59 return rule.empty() || match.compare(rule) == 0;
60 case RuleType::PREFIX:
61 return rule.empty() || match.find(rule) == 0;
62 case RuleType::REGULAR: {
63 smatch result;
64 const regex pattern(rule);
65 return rule.empty() || regex_search(match, result, pattern);
66 }
67 default:
68 HIVIEW_LOGE("invalid rule type %{public}d.", type);
69 return false;
70 }
71 }
72
MatchEventType(int rule,int match)73 bool MatchEventType(int rule, int match)
74 {
75 return rule == INVALID_EVENT_TYPE || rule == match;
76 }
77
IsMatchedRule(const OHOS::HiviewDFX::SysEventRule & rule,const string & domain,const string & eventName,const string & tag,uint32_t eventType)78 bool IsMatchedRule(const OHOS::HiviewDFX::SysEventRule& rule, const string& domain,
79 const string& eventName, const string& tag, uint32_t eventType)
80 {
81 if (rule.tag.empty()) {
82 return MatchContent(rule.ruleType, rule.domain, domain)
83 && MatchContent(rule.ruleType, rule.eventName, eventName)
84 && MatchEventType(rule.eventType, eventType);
85 }
86 return MatchContent(rule.ruleType, rule.tag, tag)
87 && MatchEventType(rule.eventType, eventType);
88 }
89
MatchRules(const SysEventRuleGroupOhos & rules,const string & domain,const string & eventName,const string & tag,uint32_t eventType)90 bool MatchRules(const SysEventRuleGroupOhos& rules, const string& domain, const string& eventName,
91 const string& tag, uint32_t eventType)
92 {
93 return any_of(rules.begin(), rules.end(), [domain, eventName, tag, eventType] (auto& rule) {
94 if (IsMatchedRule(rule, domain, eventName, tag, eventType)) {
95 HIVIEW_LOGD("rule type is %{public}d, domain is %{public}s, eventName is %{public}s, "
96 "tag is %{public}s, eventType is %{public}u for matched",
97 rule.ruleType, rule.domain.empty() ? "empty" : rule.domain.c_str(),
98 rule.eventName.empty() ? "empty" : rule.eventName.c_str(),
99 rule.tag.empty() ? "empty" : rule.tag.c_str(), eventType);
100 return true;
101 }
102 return false;
103 });
104 }
105
CheckEventListenerAddingValidity(const std::vector<SysEventRule> & rules,RegisteredListeners & listeners)106 int32_t CheckEventListenerAddingValidity(const std::vector<SysEventRule>& rules, RegisteredListeners& listeners)
107 {
108 size_t watchRuleCntLimit = 20; // count of listener rule for each watcher is limited to 20.
109 if (rules.size() > watchRuleCntLimit) {
110 OHOS::HiviewDFX::RunningStatusLogUtil::LogTooManyWatchRules(rules);
111 return ERR_TOO_MANY_WATCH_RULES;
112 }
113 size_t watcherTotalCntLimit = 30; // count of total watches is limited to 30.
114 if (listeners.size() >= watcherTotalCntLimit) {
115 OHOS::HiviewDFX::RunningStatusLogUtil::LogTooManyWatchers(watcherTotalCntLimit);
116 return ERR_TOO_MANY_WATCHERS;
117 }
118 return IPC_CALL_SUCCEED;
119 }
120
CheckEventSubscriberAddingValidity(const std::vector<std::string> & events)121 int32_t CheckEventSubscriberAddingValidity(const std::vector<std::string>& events)
122 {
123 size_t maxEventNum = 30; // count of total events is limited to 30.
124 if (events.size() > maxEventNum) {
125 OHOS::HiviewDFX::RunningStatusLogUtil::LogTooManyEvents(maxEventNum);
126 return ERR_TOO_MANY_EVENTS;
127 }
128 return IPC_CALL_SUCCEED;
129 }
130
CheckEventQueryingValidity(const SysEventQueryRuleGroupOhos & rules,size_t limit)131 int32_t CheckEventQueryingValidity(const SysEventQueryRuleGroupOhos& rules, size_t limit)
132 {
133 if (rules.size() > limit) {
134 OHOS::HiviewDFX::RunningStatusLogUtil::LogTooManyQueryRules(rules);
135 return ERR_TOO_MANY_QUERY_RULES;
136 }
137 return IPC_CALL_SUCCEED;
138 }
139 }
140
141 OHOS::HiviewDFX::NotifySysEvent SysEventServiceOhos::gISysEventNotify_;
142 sptr<OHOS::HiviewDFX::SysEventServiceOhos> SysEventServiceOhos::instance(new SysEventServiceOhos);
143
GetInstance()144 sptr<OHOS::HiviewDFX::SysEventServiceOhos> SysEventServiceOhos::GetInstance()
145 {
146 return instance;
147 }
148
StartService(SysEventServiceBase * service,const OHOS::HiviewDFX::NotifySysEvent notify)149 void SysEventServiceOhos::StartService(SysEventServiceBase *service,
150 const OHOS::HiviewDFX::NotifySysEvent notify)
151 {
152 gISysEventNotify_ = notify;
153 GetSysEventService(service);
154 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
155 if (samgr == nullptr) {
156 HIVIEW_LOGE("failed to find SystemAbilityManager.");
157 return;
158 }
159 if (instance == nullptr) {
160 HIVIEW_LOGE("SysEventServiceOhos service is null.");
161 return;
162 }
163 int ret = samgr->AddSystemAbility(DFX_SYS_EVENT_SERVICE_ABILITY_ID, instance);
164 if (ret != 0) {
165 HIVIEW_LOGE("failed to add sys event service ability.");
166 }
167 }
168
GetTagByDomainAndName(const string & eventDomain,const string & eventName)169 string SysEventServiceOhos::GetTagByDomainAndName(const string& eventDomain, const string& eventName)
170 {
171 if (getTagFunc_ == nullptr) {
172 return "";
173 }
174 return getTagFunc_(eventDomain, eventName);
175 }
176
GetTypeByDomainAndName(const string & eventDomain,const string & eventName)177 uint32_t SysEventServiceOhos::GetTypeByDomainAndName(const string& eventDomain, const string& eventName)
178 {
179 if (getTypeFunc_ == nullptr) {
180 return INVALID_EVENT_TYPE;
181 }
182 return getTypeFunc_(eventDomain, eventName);
183 }
184
OnSysEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> & event)185 void SysEventServiceOhos::OnSysEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent>& event)
186 {
187 lock_guard<mutex> lock(mutex_);
188 for (auto listener = registeredListeners_.begin(); listener != registeredListeners_.end(); ++listener) {
189 SysEventCallbackPtrOhos callback = iface_cast<ISysEventCallback>(listener->first);
190 if (callback == nullptr) {
191 HIVIEW_LOGE("interface is null, no need to match rules.");
192 continue;
193 }
194 bool isMatched = MatchRules(listener->second.second, event->domain_, event->eventName_,
195 event->GetTag(), event->eventType_);
196 HIVIEW_LOGD("pid %{public}d rules match %{public}s.", listener->second.first,
197 isMatched ? "success" : "fail");
198 if (isMatched) {
199 callback->Handle(Str8ToStr16(event->domain_), Str8ToStr16(event->eventName_),
200 static_cast<int>(event->what_), Str8ToStr16(event->AsJsonStr()));
201 }
202 }
203 dataPublisher_->OnSysEvent(event);
204 }
205
UpdateEventSeq(int64_t seq)206 void SysEventServiceOhos::UpdateEventSeq(int64_t seq)
207 {
208 curSeq.store(seq, std::memory_order_release);
209 }
210
OnRemoteDied(const wptr<IRemoteObject> & remote)211 void SysEventServiceOhos::OnRemoteDied(const wptr<IRemoteObject>& remote)
212 {
213 if (remote == nullptr) {
214 HIVIEW_LOGE("remote is null");
215 return;
216 }
217 auto remoteObject = remote.promote();
218 if (remoteObject == nullptr) {
219 HIVIEW_LOGE("object in remote is null.");
220 return;
221 }
222 lock_guard<mutex> lock(mutex_);
223 if (debugModeCallback_ != nullptr) {
224 CallbackObjectOhos callbackObject = debugModeCallback_->AsObject();
225 if (callbackObject == remoteObject && isDebugMode_) {
226 HIVIEW_LOGE("quit debugmode.");
227 auto event = std::make_shared<Event>("SysEventSource");
228 event->messageType_ = Event::ENGINE_SYSEVENT_DEBUG_MODE;
229 event->SetValue("DEBUGMODE", "false");
230 gISysEventNotify_(event);
231 isDebugMode_ = false;
232 }
233 }
234 auto listener = registeredListeners_.find(remoteObject);
235 if (listener != registeredListeners_.end()) {
236 listener->first->RemoveDeathRecipient(deathRecipient_);
237 HIVIEW_LOGE("pid %{public}d has died and remove listener.", listener->second.first);
238 registeredListeners_.erase(listener);
239 }
240 }
241
BindGetTagFunc(const GetTagByDomainNameFunc & getTagFunc)242 void SysEventServiceOhos::BindGetTagFunc(const GetTagByDomainNameFunc& getTagFunc)
243 {
244 getTagFunc_ = getTagFunc;
245 }
246
BindGetTypeFunc(const GetTypeByDomainNameFunc & getTypeFunc)247 void SysEventServiceOhos::BindGetTypeFunc(const GetTypeByDomainNameFunc& getTypeFunc)
248 {
249 getTypeFunc_ = getTypeFunc;
250 }
251
GetSysEventService(SysEventServiceBase * service)252 SysEventServiceBase* SysEventServiceOhos::GetSysEventService(SysEventServiceBase* service)
253 {
254 static SysEventServiceBase* ref = nullptr;
255 if (service != nullptr) {
256 ref = service;
257 }
258 return ref;
259 }
260
AddListener(const std::vector<SysEventRule> & rules,const sptr<ISysEventCallback> & callback)261 int32_t SysEventServiceOhos::AddListener(const std::vector<SysEventRule>& rules,
262 const sptr<ISysEventCallback>& callback)
263 {
264 if (!HasAccessPermission()) {
265 return ERR_NO_PERMISSION;
266 }
267 auto checkRet = CheckEventListenerAddingValidity(rules, registeredListeners_);
268 if (checkRet != IPC_CALL_SUCCEED) {
269 return checkRet;
270 }
271 auto service = GetSysEventService();
272 if (service == nullptr) {
273 HIVIEW_LOGE("subscribe fail, sys event service is null.");
274 return ERR_REMOTE_SERVICE_IS_NULL;
275 }
276 if (callback == nullptr) {
277 HIVIEW_LOGE("subscribe fail, callback is null.");
278 return ERR_LISTENER_NOT_EXIST;
279 }
280 CallbackObjectOhos callbackObject = callback->AsObject();
281 if (callbackObject == nullptr) {
282 HIVIEW_LOGE("subscribe fail, object in callback is null.");
283 return ERR_LISTENER_STATUS_INVALID;
284 }
285 int32_t uid = IPCSkeleton::GetCallingUid();
286 int32_t pid = IPCSkeleton::GetCallingPid();
287 lock_guard<mutex> lock(mutex_);
288 pair<int32_t, SysEventRuleGroupOhos> rulesPair(pid, rules);
289 if (registeredListeners_.find(callbackObject) != registeredListeners_.end()) {
290 registeredListeners_[callbackObject] = rulesPair;
291 HIVIEW_LOGD("uid %{public}d pid %{public}d listener has been added and update rules.", uid, pid);
292 return IPC_CALL_SUCCEED;
293 }
294 if (!callbackObject->AddDeathRecipient(deathRecipient_)) {
295 HIVIEW_LOGE("subscribe fail, can not add death recipient.");
296 return ERR_ADD_DEATH_RECIPIENT;
297 }
298 registeredListeners_.insert(make_pair(callbackObject, rulesPair));
299 HIVIEW_LOGD("uid %{public}d pid %{public}d listener is added successfully, total is %{public}zu.",
300 uid, pid, registeredListeners_.size());
301 return IPC_CALL_SUCCEED;
302 }
303
RemoveListener(const SysEventCallbackPtrOhos & callback)304 int32_t SysEventServiceOhos::RemoveListener(const SysEventCallbackPtrOhos& callback)
305 {
306 if (!HasAccessPermission()) {
307 return ERR_NO_PERMISSION;
308 }
309 auto service = GetSysEventService();
310 if (service == nullptr) {
311 HIVIEW_LOGE("sys event service is null.");
312 return ERR_REMOTE_SERVICE_IS_NULL;
313 }
314 if (callback == nullptr) {
315 HIVIEW_LOGE("callback is null.");
316 return ERR_LISTENER_NOT_EXIST;
317 }
318 CallbackObjectOhos callbackObject = callback->AsObject();
319 if (callbackObject == nullptr) {
320 HIVIEW_LOGE("object in callback is null.");
321 return ERR_LISTENER_STATUS_INVALID;
322 }
323 int32_t uid = IPCSkeleton::GetCallingUid();
324 int32_t pid = IPCSkeleton::GetCallingPid();
325 lock_guard<mutex> lock(mutex_);
326 if (registeredListeners_.empty()) {
327 HIVIEW_LOGD("has no any listeners.");
328 return ERR_LISTENERS_EMPTY;
329 }
330 auto registeredListener = registeredListeners_.find(callbackObject);
331 if (registeredListener != registeredListeners_.end()) {
332 if (!callbackObject->RemoveDeathRecipient(deathRecipient_)) {
333 HIVIEW_LOGE("uid %{public}d pid %{public}d listener can not remove death recipient.", uid, pid);
334 return ERR_ADD_DEATH_RECIPIENT;
335 }
336 registeredListeners_.erase(registeredListener);
337 HIVIEW_LOGD("uid %{public}d pid %{public}d has found listener and removes it.", uid, pid);
338 return IPC_CALL_SUCCEED;
339 } else {
340 HIVIEW_LOGD("uid %{public}d pid %{public}d has not found listener.", uid, pid);
341 return ERR_LISTENER_NOT_EXIST;
342 }
343 }
344
BuildEventQuery(std::shared_ptr<EventQueryWrapperBuilder> builder,const SysEventQueryRuleGroupOhos & rules)345 bool SysEventServiceOhos::BuildEventQuery(std::shared_ptr<EventQueryWrapperBuilder> builder,
346 const SysEventQueryRuleGroupOhos& rules)
347 {
348 if (builder == nullptr) {
349 return false;
350 }
351 auto callingUid = IPCSkeleton::GetCallingUid();
352 if (rules.empty() && (callingUid == HID_SHELL || callingUid == HID_ROOT ||
353 callingUid == HID_OHOS)) {
354 builder->Append("", "", 0, "");
355 return true;
356 }
357 return !any_of(rules.cbegin(), rules.cend(), [this, callingUid, &builder] (auto& rule) {
358 if (rule.domain.empty() && callingUid != HID_SHELL && callingUid != HID_ROOT &&
359 callingUid != HID_OHOS) {
360 return true;
361 }
362 return any_of(rule.eventList.cbegin(), rule.eventList.cend(),
363 [this, callingUid, &builder, &rule] (auto& eventName) {
364 if (eventName.empty() && callingUid != HID_SHELL && callingUid != HID_ROOT &&
365 callingUid != HID_OHOS) {
366 return true;
367 }
368 auto eventType = this->GetTypeByDomainAndName(rule.domain, eventName);
369 HIVIEW_LOGD("event type configured with domain[%{public}s] and name[%{public}s] "
370 " is %{public}u, and event type in query rule is %{public}u.",
371 rule.domain.c_str(), eventName.c_str(), eventType, rule.eventType);
372 if ((!rule.domain.empty() && !eventName.empty() && eventType == INVALID_EVENT_TYPE) ||
373 (eventType != INVALID_EVENT_TYPE && rule.eventType != INVALID_EVENT_TYPE &&
374 eventType != rule.eventType)) {
375 return false;
376 }
377 eventType = eventType == INVALID_EVENT_TYPE ? rule.eventType : eventType;
378 builder->Append(rule.domain, eventName, eventType, rule.condition);
379 return false;
380 });
381 });
382 }
383
GetCallerQueryRuleLimit()384 size_t SysEventServiceOhos::GetCallerQueryRuleLimit()
385 {
386 using namespace Security::AccessToken;
387 auto callerType = AccessTokenKit::GetTokenType(IPCSkeleton::GetCallingTokenID());
388 if (callerType == TOKEN_HAP) {
389 std::string bundleName;
390 AppExecFwk::BundleMgrClient client;
391 client.GetNameForUid(IPCSkeleton::GetCallingUid(), bundleName);
392 return EventThreshold::EventThresholdManager::GetInstance().GetQueryRuleLimit(bundleName,
393 EventThreshold::ProcessType::HAP);
394 }
395 return EventThreshold::EventThresholdManager::GetInstance().GetDefaultQueryRuleLimit();
396 }
397
Query(const QueryArgument & queryArgument,const SysEventQueryRuleGroupOhos & rules,const OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback> & callback)398 int32_t SysEventServiceOhos::Query(const QueryArgument& queryArgument, const SysEventQueryRuleGroupOhos& rules,
399 const OHOS::sptr<OHOS::HiviewDFX::IQuerySysEventCallback>& callback)
400 {
401 if (callback == nullptr) {
402 return ERR_LISTENER_NOT_EXIST;
403 }
404 if (!HasAccessPermission()) {
405 callback->OnComplete(ERR_NO_PERMISSION, 0, curSeq.load(std::memory_order_acquire));
406 return ERR_NO_PERMISSION;
407 }
408 auto checkRet = CheckEventQueryingValidity(rules, GetCallerQueryRuleLimit());
409 if (checkRet != IPC_CALL_SUCCEED) {
410 callback->OnComplete(checkRet, 0, curSeq.load(std::memory_order_acquire));
411 return checkRet;
412 }
413 auto queryWrapperBuilder = std::make_shared<EventQueryWrapperBuilder>(queryArgument);
414 auto buildRet = BuildEventQuery(queryWrapperBuilder, rules);
415 if (!buildRet || queryWrapperBuilder == nullptr || !queryWrapperBuilder->IsValid()) {
416 HIVIEW_LOGW("invalid query rule, exit sys event querying.");
417 callback->OnComplete(ERR_QUERY_RULE_INVALID, 0, curSeq.load(std::memory_order_acquire));
418 return ERR_QUERY_RULE_INVALID;
419 }
420 if (queryArgument.maxEvents == 0) {
421 HIVIEW_LOGW("query count is 0, query complete directly.");
422 callback->OnComplete(IPC_CALL_SUCCEED, 0, curSeq.load(std::memory_order_acquire));
423 return IPC_CALL_SUCCEED;
424 }
425 auto queryWrapper = queryWrapperBuilder->Build();
426 if (queryWrapper == nullptr) {
427 HIVIEW_LOGW("query wrapper build failed.");
428 callback->OnComplete(ERR_QUERY_RULE_INVALID, 0, curSeq.load(std::memory_order_acquire));
429 return ERR_QUERY_RULE_INVALID;
430 }
431 queryWrapper->SetMaxSequence(curSeq.load(std::memory_order_acquire));
432 auto queryRetCode = IPC_CALL_SUCCEED;
433 queryWrapper->Query(callback, queryRetCode);
434 return queryRetCode;
435 }
436
HasAccessPermission() const437 bool SysEventServiceOhos::HasAccessPermission() const
438 {
439 using namespace Security::AccessToken;
440 auto tokenId = IPCSkeleton::GetFirstTokenID();
441 if (tokenId == 0) {
442 tokenId = IPCSkeleton::GetCallingTokenID();
443 }
444 if ((AccessTokenKit::VerifyAccessToken(tokenId, READ_DFX_SYSEVENT_PERMISSION) == RET_SUCCESS) ||
445 (AccessTokenKit::VerifyAccessToken(tokenId, DFX_DUMP_PERMISSION) == RET_SUCCESS)) {
446 return true;
447 }
448 return false;
449 }
450
SetDebugMode(const SysEventCallbackPtrOhos & callback,bool mode)451 int32_t SysEventServiceOhos::SetDebugMode(const SysEventCallbackPtrOhos& callback, bool mode)
452 {
453 if (!HasAccessPermission()) {
454 return ERR_NO_PERMISSION;
455 }
456 if (mode == isDebugMode_) {
457 HIVIEW_LOGE("same config, no need set");
458 return ERR_DEBUG_MODE_SET_REPEAT;
459 }
460 auto event = std::make_shared<Event>("SysEventSource");
461 event->messageType_ = Event::ENGINE_SYSEVENT_DEBUG_MODE;
462 event->SetValue("DEBUGMODE", mode ? "true" : "false");
463 gISysEventNotify_(event);
464
465 HIVIEW_LOGD("set debug mode %{public}s", mode ? "true" : "false");
466 debugModeCallback_ = callback;
467 isDebugMode_ = mode;
468 return IPC_CALL_SUCCEED;
469 }
470
Dump(int32_t fd,const std::vector<std::u16string> & args)471 int SysEventServiceOhos::Dump(int32_t fd, const std::vector<std::u16string> &args)
472 {
473 if (fd < 0) {
474 HIVIEW_LOGE("invalid fd.");
475 return -1;
476 }
477 dprintf(fd, "%s\n", "Hiview SysEventService");
478 return 0;
479 }
480
OnRemoteDied(const wptr<IRemoteObject> & remote)481 void CallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
482 {
483 auto service = SysEventServiceOhos::GetInstance();
484 if (service == nullptr) {
485 HIVIEW_LOGE("SysEventServiceOhos service is null.");
486 return;
487 }
488 service->OnRemoteDied(remote);
489 }
490
AddSubscriber(const SysEventQueryRuleGroupOhos & rules)491 int64_t SysEventServiceOhos::AddSubscriber(const SysEventQueryRuleGroupOhos &rules)
492 {
493 if (!HasAccessPermission()) {
494 return ERR_NO_PERMISSION;
495 }
496 std::vector<std::string> events;
497 MergeEventList(rules, events);
498 auto checkRet = CheckEventSubscriberAddingValidity(events);
499 if (checkRet != IPC_CALL_SUCCEED) {
500 return checkRet;
501 }
502 int32_t uid = IPCSkeleton::GetCallingUid();
503 lock_guard<mutex> lock(mutex_);
504 auto ret = dataPublisher_->AddSubscriber(uid, events);
505 if (ret != IPC_CALL_SUCCEED) {
506 return ret;
507 }
508 return TimeUtil::GetMilliseconds();
509 }
510
MergeEventList(const std::vector<SysEventQueryRule> & rules,std::vector<std::string> & events) const511 void SysEventServiceOhos::MergeEventList(const std::vector<SysEventQueryRule>& rules,
512 std::vector<std::string>& events) const
513 {
514 for_each(rules.cbegin(), rules.cend(), [&](const SysEventQueryRule &rule) {
515 auto eventList = rule.eventList;
516 for_each(eventList.cbegin(), eventList.cend(), [&](const std::string &event) {
517 events.push_back(event);
518 });
519 });
520 }
521
RemoveSubscriber()522 int32_t SysEventServiceOhos::RemoveSubscriber()
523 {
524 if (!HasAccessPermission()) {
525 return ERR_NO_PERMISSION;
526 }
527 int32_t uid = IPCSkeleton::GetCallingUid();
528 lock_guard<mutex> lock(mutex_);
529 auto ret = dataPublisher_->RemoveSubscriber(uid);
530 if (ret != IPC_CALL_SUCCEED) {
531 return ret;
532 }
533 return IPC_CALL_SUCCEED;
534 }
535
Export(const QueryArgument & queryArgument,const SysEventQueryRuleGroupOhos & rules)536 int64_t SysEventServiceOhos::Export(const QueryArgument &queryArgument, const SysEventQueryRuleGroupOhos &rules)
537 {
538 if (!HasAccessPermission()) {
539 return ERR_NO_PERMISSION;
540 }
541 auto checkRet = CheckEventQueryingValidity(rules, 10); // count of query rule limits to 10 in export.
542 if (checkRet != IPC_CALL_SUCCEED) {
543 return checkRet;
544 }
545 int32_t uid = IPCSkeleton::GetCallingUid();
546 auto lastTimeStamp = dataPublisher_->GetTimeStampByUid(uid);
547 int64_t currentTime = static_cast<int64_t>(TimeUtil::GetMilliseconds());
548 if (std::abs(currentTime - lastTimeStamp) < TimeUtil::SECONDS_PER_HOUR * TimeUtil::SEC_TO_MILLISEC) {
549 HIVIEW_LOGD("forbid export, time frequency limit < 1 h.");
550 return ERR_EXPORT_FREQUENCY_OVER_LIMIT;
551 }
552
553 auto queryWrapperBuilder = std::make_shared<EventQueryWrapperBuilder>(queryArgument);
554 auto buildRet = BuildEventQuery(queryWrapperBuilder, rules);
555 if (!buildRet || queryWrapperBuilder == nullptr || !queryWrapperBuilder->IsValid()) {
556 HIVIEW_LOGW("invalid query rule, exit sys event exporting.");
557 return ERR_QUERY_RULE_INVALID;
558 }
559 if (queryArgument.maxEvents == 0) {
560 HIVIEW_LOGW("export count is 0, export complete directly.");
561 return currentTime;
562 }
563 auto queryWrapper = queryWrapperBuilder->Build();
564 if (queryWrapper == nullptr) {
565 HIVIEW_LOGW("export wrapper build failed.");
566 return ERR_QUERY_RULE_INVALID;
567 }
568 queryWrapper->SetMaxSequence(curSeq.load(std::memory_order_acquire));
569 dataPublisher_->AddExportTask(queryWrapper, currentTime, uid);
570 return currentTime;
571 }
572
SetWorkLoop(std::shared_ptr<EventLoop> looper)573 void SysEventServiceOhos::SetWorkLoop(std::shared_ptr<EventLoop> looper)
574 {
575 if (looper == nullptr) {
576 HIVIEW_LOGW("SetWorkLoop failed, looper is null.");
577 return;
578 }
579 dataPublisher_->SetWorkLoop(looper);
580 }
581
582 } // namespace HiviewDFX
583 } // namespace OHOS