1 /*
2 * Copyright (c) 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 #include "event_verify_util.h"
16
17 #include "focused_event_util.h"
18 #include "hiview_logger.h"
19 #include "running_status_logger.h"
20
21 namespace OHOS {
22 namespace HiviewDFX {
23 DEFINE_LOG_TAG("EventVerifyUtil");
24 constexpr char TEST_TYPE_KEY[] = "test_type_";
25
GenerateHash(std::shared_ptr<SysEvent> event)26 uint64_t GenerateHash(std::shared_ptr<SysEvent> event)
27 {
28 constexpr size_t infoLenLimit = 256;
29 size_t infoLen = event->rawData_->GetDataLength();
30 size_t hashLen = (infoLen < infoLenLimit) ? infoLen : infoLenLimit;
31 const uint8_t* p = event->rawData_->GetData();
32 uint64_t ret { 0xCBF29CE484222325ULL }; // basis value
33 size_t i = 0;
34 while (i < hashLen) {
35 ret ^= *(p + i);
36 ret *= 0x100000001B3ULL; // prime value
37 i++;
38 }
39 return ret;
40 }
41
Init(HiviewContext * context)42 void EventVerifyUtil::Init(HiviewContext* context)
43 {
44 eventPeriodInfoUtil_.Init(context);
45 paramWatcher_.Init();
46 }
47
IsValidEvent(std::shared_ptr<SysEvent> event)48 bool EventVerifyUtil::IsValidEvent(std::shared_ptr<SysEvent> event)
49 {
50 if (!IsValidSysEvent(event)) {
51 return false;
52 }
53
54 if (FocusedEventUtil::IsFocusedEvent(event->domain_, event->eventName_)) {
55 HIVIEW_LOGI("event[%{public}s|%{public}s|%{public}" PRIu64 "] is valid.",
56 event->domain_.c_str(), event->eventName_.c_str(), event->happenTime_);
57 }
58 eventPeriodInfoUtil_.UpdatePeriodInfo(event);
59 return true;
60 }
61
IsValidSysEvent(const std::shared_ptr<SysEvent> event)62 bool EventVerifyUtil::IsValidSysEvent(const std::shared_ptr<SysEvent> event)
63 {
64 if (event->domain_.empty() || event->eventName_.empty()) {
65 HIVIEW_LOGW("domain=%{public}s or name=%{public}s is empty.",
66 event->domain_.c_str(), event->eventName_.c_str());
67 return false;
68 }
69 auto baseInfo = EventJsonParser::GetInstance()->GetDefinedBaseInfoByDomainName(event->domain_, event->eventName_);
70 if (baseInfo.keyConfig.type == INVALID_EVENT_TYPE) {
71 HIVIEW_LOGD("type defined for event[%{public}s|%{public}s|%{public}" PRIu64 "] invalid, or privacy dismatch.",
72 event->domain_.c_str(), event->eventName_.c_str(), event->happenTime_);
73 return false;
74 }
75 if (event->GetEventType() != baseInfo.keyConfig.type) {
76 HIVIEW_LOGW("type=%{public}d of event[%{public}s|%{public}s|%{public}" PRIu64 "] is invalid.",
77 event->GetEventType(), event->domain_.c_str(), event->eventName_.c_str(), event->happenTime_);
78 return false;
79 }
80
81 // deduplicate Event
82 auto eventId = GenerateHash(event);
83 if (IsDuplicateEvent(eventId)) {
84 HIVIEW_LOGW("ignore duplicate event[%{public}s|%{public}s|%{public}" PRIu64 "].",
85 event->domain_.c_str(), event->eventName_.c_str(), eventId);
86 return false;
87 }
88
89 // append extra event info
90 DecorateSysEvent(event, baseInfo, eventId);
91 return true;
92 }
93
IsDuplicateEvent(const uint64_t eventId)94 bool EventVerifyUtil::IsDuplicateEvent(const uint64_t eventId)
95 {
96 for (auto iter = eventIdList_.rbegin(); iter != eventIdList_.rend(); ++iter) {
97 if (*iter == eventId) {
98 return true;
99 }
100 }
101 std::list<uint64_t>::size_type maxSize { 25 }; // size of queue limit to 25
102 if (eventIdList_.size() >= maxSize) {
103 eventIdList_.pop_front();
104 }
105 eventIdList_.emplace_back(eventId);
106 return false;
107 }
108
DecorateSysEvent(const std::shared_ptr<SysEvent> event,const BaseInfo & baseInfo,uint64_t id)109 void EventVerifyUtil::DecorateSysEvent(const std::shared_ptr<SysEvent> event, const BaseInfo& baseInfo, uint64_t id)
110 {
111 if (!baseInfo.level.empty()) {
112 event->SetLevel(baseInfo.level);
113 }
114 if (!baseInfo.tag.empty()) {
115 event->SetTag(baseInfo.tag);
116 }
117 event->SetPrivacy(baseInfo.keyConfig.privacy);
118 std::string testType = paramWatcher_.GetTestType();
119 if (!testType.empty()) {
120 event->SetEventValue(TEST_TYPE_KEY, testType);
121 }
122 event->preserve_ = baseInfo.keyConfig.preserve;
123 event->collect_ = baseInfo.keyConfig.collect;
124 event->SetId(id); // add hashcode id
125 event->SetInvalidParams(baseInfo.disallowParams);
126 event->SetReportInterval(baseInfo.reportInterval);
127 }
128 } // namespace HiviewDFX
129 } // namespace OHOS
130