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