1 /*
2 * Copyright (c) 2023-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 "app_event_observer.h"
16
17 #include "app_event.h"
18 #include "hiappevent_base.h"
19 #include "hiappevent_common.h"
20 #include "hilog/log.h"
21
22 #undef LOG_DOMAIN
23 #define LOG_DOMAIN 0xD002D07
24
25 #undef LOG_TAG
26 #define LOG_TAG "Observer"
27
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace HiAppEvent {
31 namespace {
32 constexpr uint64_t BIT_MASK = 1;
33 struct OsEventPosInfo {
34 std::string name;
35 EventType type;
36 uint8_t pos; // means position in binary
37 };
38 const std::vector<OsEventPosInfo> OS_EVENT_POS_INFOS = {
39 { EVENT_APP_CRASH, FAULT, 0 },
40 { EVENT_APP_FREEZE, FAULT, 1 },
41 { EVENT_APP_LAUNCH, BEHAVIOR, 2 },
42 { EVENT_SCROLL_JANK, FAULT, 3 },
43 { EVENT_CPU_USAGE_HIGH, FAULT, 4 },
44 { EVENT_BATTERY_USAGE, STATISTIC, 5 },
45 { EVENT_RESOURCE_OVERLIMIT, FAULT, 6 },
46 { EVENT_ADDRESS_SANITIZER, FAULT, 7 },
47 { EVENT_MAIN_THREAD_JANK, FAULT, 8 },
48 { EVENT_APP_START, BEHAVIOR, 9 },
49 { EVENT_APP_HICOLLIE, FAULT, 10 },
50 { EVENT_APP_KILLED, STATISTIC, 11 },
51 };
52
MeetNumberCondition(int currNum,int maxNum)53 bool MeetNumberCondition(int currNum, int maxNum)
54 {
55 return maxNum > 0 && currNum >= maxNum;
56 }
57
ResetCondition(TriggerCondition & cond)58 void ResetCondition(TriggerCondition& cond)
59 {
60 cond.row = 0;
61 cond.size = 0;
62 cond.timeout = 0;
63 }
64 }
65
AppEventFilter(const std::string & domain,const std::unordered_set<std::string> & names,uint32_t types)66 AppEventFilter::AppEventFilter(const std::string& domain, const std::unordered_set<std::string>& names,
67 uint32_t types) : domain(domain), names(names), types(types)
68 {}
69
AppEventFilter(const std::string & domain,uint32_t types)70 AppEventFilter::AppEventFilter(const std::string& domain, uint32_t types) : domain(domain), types(types)
71 {}
72
IsValidEvent(std::shared_ptr<AppEventPack> event) const73 bool AppEventFilter::IsValidEvent(std::shared_ptr<AppEventPack> event) const
74 {
75 return IsValidEvent(event->GetDomain(), event->GetName(), event->GetType());
76 }
77
IsValidEvent(const std::string & eventDomain,const std::string & eventName,int eventType) const78 bool AppEventFilter::IsValidEvent(const std::string& eventDomain, const std::string& eventName, int eventType) const
79 {
80 if (domain.empty()) {
81 return false;
82 }
83 if (!domain.empty() && domain != eventDomain) {
84 return false;
85 }
86 if (!names.empty() && (names.find(eventName) == names.end())) {
87 return false;
88 }
89 if (types != 0 && !(types & (1 << eventType))) { // 1: bit mask
90 return false;
91 }
92 return true;
93 }
94
GetOsEventsMask() const95 uint64_t AppEventFilter::GetOsEventsMask() const
96 {
97 uint64_t mask = 0;
98 for (const auto& event : OS_EVENT_POS_INFOS) {
99 if (IsValidEvent(DOMAIN_OS, event.name, event.type)) {
100 mask |= (BIT_MASK << event.pos);
101 }
102 }
103 return mask;
104 }
105
VerifyEvent(std::shared_ptr<AppEventPack> event)106 bool AppEventObserver::VerifyEvent(std::shared_ptr<AppEventPack> event)
107 {
108 std::lock_guard<std::mutex> lockGuard(mutex_);
109 if (filters_.empty()) {
110 return true;
111 }
112 auto it = std::find_if(filters_.begin(), filters_.end(), [event](const auto& filter) {
113 return filter.IsValidEvent(event);
114 });
115 return it != filters_.end();
116 }
117
ProcessEvent(std::shared_ptr<AppEventPack> event)118 void AppEventObserver::ProcessEvent(std::shared_ptr<AppEventPack> event)
119 {
120 HILOG_DEBUG(LOG_CORE, "observer=%{public}s start to process event", name_.c_str());
121 std::lock_guard<std::mutex> lockGuard(condMutex_);
122 ++currCond_.row;
123 currCond_.size += static_cast<int>(event->GetEventStr().size());
124 if (MeetNumberCondition(currCond_.row, triggerCond_.row)
125 || MeetNumberCondition(currCond_.size, triggerCond_.size)) {
126 OnTrigger(currCond_);
127 ResetCondition(currCond_);
128 }
129 }
130
ResetCurrCondition()131 void AppEventObserver::ResetCurrCondition()
132 {
133 std::lock_guard<std::mutex> lockGuard(condMutex_);
134 ResetCondition(currCond_);
135 }
136
ProcessTimeout()137 void AppEventObserver::ProcessTimeout()
138 {
139 std::lock_guard<std::mutex> lockGuard(condMutex_);
140 currCond_.timeout += TIMEOUT_STEP;
141 if (MeetNumberCondition(currCond_.timeout, triggerCond_.timeout) && currCond_.row > 0) {
142 OnTrigger(currCond_);
143 ResetCondition(currCond_);
144 }
145 }
146
HasTimeoutCondition()147 bool AppEventObserver::HasTimeoutCondition()
148 {
149 std::lock_guard<std::mutex> lockGuard(condMutex_);
150 return triggerCond_.timeout > 0 && currCond_.row > 0;
151 }
152
ProcessStartup()153 void AppEventObserver::ProcessStartup()
154 {
155 std::lock_guard<std::mutex> lockGuard(condMutex_);
156 if (triggerCond_.onStartup && currCond_.row > 0) {
157 OnTrigger(currCond_);
158 ResetCondition(currCond_);
159 }
160 }
161
ProcessBackground()162 void AppEventObserver::ProcessBackground()
163 {
164 std::lock_guard<std::mutex> lockGuard(condMutex_);
165 if (triggerCond_.onBackground && currCond_.row > 0) {
166 OnTrigger(currCond_);
167 ResetCondition(currCond_);
168 }
169 }
170
GetName()171 std::string AppEventObserver::GetName()
172 {
173 std::lock_guard<std::mutex> lockGuard(mutex_);
174 return name_;
175 }
176
GetSeq()177 int64_t AppEventObserver::GetSeq()
178 {
179 std::lock_guard<std::mutex> lockGuard(mutex_);
180 return seq_;
181 }
182
SetSeq(int64_t seq)183 void AppEventObserver::SetSeq(int64_t seq)
184 {
185 std::lock_guard<std::mutex> lockGuard(mutex_);
186 seq_ = seq;
187 }
188
SetCurrCondition(const TriggerCondition & triggerCond)189 void AppEventObserver::SetCurrCondition(const TriggerCondition& triggerCond)
190 {
191 std::lock_guard<std::mutex> lockGuard(condMutex_);
192 currCond_ = triggerCond;
193 }
194
SetTriggerCond(const TriggerCondition & triggerCond)195 void AppEventObserver::SetTriggerCond(const TriggerCondition& triggerCond)
196 {
197 std::lock_guard<std::mutex> lockGuard(condMutex_);
198 triggerCond_ = triggerCond;
199 }
200
GetFilters()201 std::vector<AppEventFilter> AppEventObserver::GetFilters()
202 {
203 std::lock_guard<std::mutex> lockGuard(mutex_);
204 return filters_;
205 }
206
SetFilters(const std::vector<AppEventFilter> & filters)207 void AppEventObserver::SetFilters(const std::vector<AppEventFilter>& filters)
208 {
209 std::lock_guard<std::mutex> lockGuard(mutex_);
210 filters_ = filters;
211 }
212
AddFilter(const AppEventFilter & filter)213 void AppEventObserver::AddFilter(const AppEventFilter& filter)
214 {
215 std::lock_guard<std::mutex> lockGuard(mutex_);
216 filters_.emplace_back(filter);
217 }
218 } // namespace HiAppEvent
219 } // namespace HiviewDFX
220 } // namespace OHOS
221