• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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