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