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_processor_proxy.h"
16
17 #include <algorithm>
18 #include <sstream>
19
20 #include "app_event_store.h"
21 #include "hiappevent_base.h"
22 #include "hiappevent_userinfo.h"
23 #include "hilog/log.h"
24
25 #undef LOG_DOMAIN
26 #define LOG_DOMAIN 0xD002D07
27
28 #undef LOG_TAG
29 #define LOG_TAG "ProcessorProxy"
30
31 namespace OHOS {
32 namespace HiviewDFX {
33 namespace HiAppEvent {
34 namespace {
35 constexpr int MAX_SIZE_ON_EVENTS = 100;
36
CreateAppEventInfo(std::shared_ptr<AppEventPack> event)37 AppEventInfo CreateAppEventInfo(std::shared_ptr<AppEventPack> event)
38 {
39 AppEventInfo appEventInfo = {
40 .domain = event->GetDomain(),
41 .name = event->GetName(),
42 .eventType = event->GetType(),
43 .timestamp = event->GetTime(),
44 .params = event->GetParamStr(),
45 };
46 return appEventInfo;
47 }
48
GetStr(const std::unordered_set<std::string> & strSet)49 std::string GetStr(const std::unordered_set<std::string>& strSet)
50 {
51 if (strSet.empty()) {
52 return "[]";
53 }
54 std::string resStr("[");
55 for (const auto& str : strSet) {
56 resStr += str + ",";
57 }
58 resStr.pop_back(); // for delete ','
59 return resStr + "]";
60 }
61
GetStr(const std::vector<EventConfig> & eventConfigs)62 std::string GetStr(const std::vector<EventConfig>& eventConfigs)
63 {
64 if (eventConfigs.empty()) {
65 return "[]";
66 }
67 std::string resStr("[");
68 for (const auto& eventConfig : eventConfigs) {
69 resStr += eventConfig.ToString() + ",";
70 }
71 resStr.pop_back(); // for delete ','
72 return resStr + "]";
73 }
74
GetStr(const std::unordered_map<std::string,std::string> & customConfigs)75 std::string GetStr(const std::unordered_map<std::string, std::string>& customConfigs)
76 {
77 if (customConfigs.empty()) {
78 return "[]";
79 }
80 std::string resStr("[");
81 for (const auto& customConfig : customConfigs) {
82 resStr += "{" + customConfig.first + "," + customConfig.second + "}" + ",";
83 }
84 resStr.pop_back(); // for delete ','
85 return resStr +"]";
86 }
87 }
88
IsValidEvent(std::shared_ptr<AppEventPack> event) const89 bool EventConfig::IsValidEvent(std::shared_ptr<AppEventPack> event) const
90 {
91 if (domain.empty() && name.empty()) {
92 return false;
93 }
94 if (!domain.empty() && (domain != event->GetDomain())) {
95 return false;
96 }
97 if (!name.empty() && (name != event->GetName())) {
98 return false;
99 }
100 return true;
101 }
102
IsRealTimeEvent(std::shared_ptr<AppEventPack> event) const103 bool EventConfig::IsRealTimeEvent(std::shared_ptr<AppEventPack> event) const
104 {
105 return IsValidEvent(event) && isRealTime;
106 }
107
ToString() const108 std::string EventConfig::ToString() const
109 {
110 std::stringstream strStream;
111 strStream << "{" << domain << "," << name << "," << isRealTime << "}";
112 return strStream.str();
113 }
114
ToString() const115 std::string TriggerCondition::ToString() const
116 {
117 std::stringstream strStream;
118 strStream << "{" << row << "," << size << "," << timeout << "," << onStartup << "," << onBackground << "}";
119 return strStream.str();
120 }
121
ToString() const122 std::string ReportConfig::ToString() const
123 {
124 std::stringstream strStream;
125 strStream << "{" << name << "," << debugMode << "," << routeInfo << "," << appId << "," << triggerCond.ToString()
126 << "," << GetStr(userIdNames) << "," << GetStr(userPropertyNames) << "," << GetStr(eventConfigs) << ","
127 << configId << "," << GetStr(customConfigs) << "," << configName << "}";
128 return strStream.str();
129 }
130
OnEvents(const std::vector<std::shared_ptr<AppEventPack>> & events)131 void AppEventProcessorProxy::OnEvents(const std::vector<std::shared_ptr<AppEventPack>>& events)
132 {
133 if (events.empty()) {
134 return;
135 }
136
137 std::vector<UserId> userIds;
138 GetValidUserIds(userIds);
139 std::vector<UserProperty> userProperties;
140 GetValidUserProperties(userProperties);
141 int64_t observerSeq = GetSeq();
142 std::vector<AppEventInfo> eventInfos;
143 std::vector<int64_t> eventSeqs;
144 for (const auto& event : events) {
145 eventInfos.emplace_back(CreateAppEventInfo(event));
146 eventSeqs.emplace_back(event->GetSeq());
147 }
148 if (processor_->OnReport(observerSeq, userIds, userProperties, eventInfos) == 0) {
149 if (!AppEventStore::GetInstance().DeleteData(observerSeq, eventSeqs)) {
150 HILOG_ERROR(LOG_CORE, "failed to delete mapping data, seq=%{public}" PRId64 ", event num=%{public}zu",
151 observerSeq, eventSeqs.size());
152 }
153 } else {
154 HILOG_DEBUG(LOG_CORE, "failed to report event, seq=%{public}" PRId64 ", event num=%{public}zu",
155 observerSeq, eventSeqs.size());
156 }
157 }
158
GetValidUserIds(std::vector<UserId> & userIds)159 void AppEventProcessorProxy::GetValidUserIds(std::vector<UserId>& userIds)
160 {
161 int64_t userIdVerForAll = HiAppEvent::UserInfo::GetInstance().GetUserIdVersion();
162 std::lock_guard<std::mutex> lockGuard(mutex_);
163 if (userIdVerForAll == userIdVersion_) {
164 userIds = userIds_;
165 return;
166 }
167 std::vector<UserId> allUserIds = HiAppEvent::UserInfo::GetInstance().GetUserIds();
168 std::for_each(allUserIds.begin(), allUserIds.end(), [&userIds, this](const auto& userId) {
169 if (reportConfig_.userIdNames.find(userId.name) != reportConfig_.userIdNames.end()
170 && processor_->ValidateUserId(userId) == 0) {
171 userIds.emplace_back(userId);
172 }
173 });
174 userIds_ = userIds;
175 userIdVersion_ = userIdVerForAll;
176 }
177
GetValidUserProperties(std::vector<UserProperty> & userProperties)178 void AppEventProcessorProxy::GetValidUserProperties(std::vector<UserProperty>& userProperties)
179 {
180 int64_t userPropertyVerForAll = HiAppEvent::UserInfo::GetInstance().GetUserPropertyVersion();
181 std::lock_guard<std::mutex> lockGuard(mutex_);
182 if (userPropertyVerForAll == userPropertyVersion_) {
183 userProperties = userProperties_;
184 return;
185 }
186 std::vector<UserProperty> allUserProperties = HiAppEvent::UserInfo::GetInstance().GetUserProperties();
187 std::for_each(allUserProperties.begin(), allUserProperties.end(),
188 [&userProperties, this](const auto& userProperty) {
189 if (reportConfig_.userPropertyNames.find(userProperty.name) != reportConfig_.userPropertyNames.end()
190 && processor_->ValidateUserProperty(userProperty) == 0) {
191 userProperties.emplace_back(userProperty);
192 }
193 }
194 );
195 userProperties_ = userProperties;
196 userPropertyVersion_ = userPropertyVerForAll;
197 }
198
VerifyEvent(std::shared_ptr<AppEventPack> event)199 bool AppEventProcessorProxy::VerifyEvent(std::shared_ptr<AppEventPack> event)
200 {
201 return AppEventObserver::VerifyEvent(event)
202 && (processor_->ValidateEvent(CreateAppEventInfo(event)) == 0);
203 }
204
IsRealTimeEvent(std::shared_ptr<AppEventPack> event)205 bool AppEventProcessorProxy::IsRealTimeEvent(std::shared_ptr<AppEventPack> event)
206 {
207 std::lock_guard<std::mutex> lockGuard(mutex_);
208 const auto& eventConfigs = reportConfig_.eventConfigs;
209 if (eventConfigs.empty()) {
210 return false;
211 }
212 auto it = std::find_if(eventConfigs.begin(), eventConfigs.end(), [event](const auto& config) {
213 return config.IsRealTimeEvent(event);
214 });
215 return it != eventConfigs.end();
216 }
217
GetReportConfig()218 ReportConfig AppEventProcessorProxy::GetReportConfig()
219 {
220 std::lock_guard<std::mutex> lockGuard(mutex_);
221 return reportConfig_;
222 }
223
SetReportConfig(const ReportConfig & reportConfig)224 void AppEventProcessorProxy::SetReportConfig(const ReportConfig& reportConfig)
225 {
226 {
227 std::lock_guard<std::mutex> lockGuard(mutex_);
228 reportConfig_ = reportConfig;
229 }
230 SetTriggerCond(reportConfig.triggerCond);
231
232 std::vector<AppEventFilter> filters;
233 // if event configs is empty, do not report event
234 if (reportConfig.eventConfigs.empty()) {
235 filters.emplace_back(AppEventFilter()); // invalid filter
236 SetFilters(filters);
237 return;
238 }
239
240 for (const auto& eventConfig : reportConfig.eventConfigs) {
241 if (eventConfig.domain.empty() && eventConfig.name.empty()) {
242 continue;
243 }
244 std::unordered_set<std::string> names;
245 if (!eventConfig.name.empty()) {
246 names.emplace(eventConfig.name);
247 }
248 filters.emplace_back(AppEventFilter(eventConfig.domain, names));
249 }
250 SetFilters(filters);
251 }
252
GenerateHashCode()253 int64_t AppEventProcessorProxy::GenerateHashCode()
254 {
255 std::lock_guard<std::mutex> lockGuard(mutex_);
256 if (hashCode_ != 0) {
257 return hashCode_;
258 }
259 hashCode_ = (reportConfig_.configId > 0)
260 ? static_cast<int64_t>(reportConfig_.configId)
261 : static_cast<int64_t>(std::hash<std::string>{}(reportConfig_.ToString()));
262 return hashCode_;
263 }
264
OnTrigger(const TriggerCondition & triggerCond)265 void AppEventProcessorProxy::OnTrigger(const TriggerCondition& triggerCond)
266 {
267 std::vector<std::shared_ptr<AppEventPack>> events;
268 QueryEventsFromDb(events);
269 if (!events.empty()) {
270 OnEvents(events);
271 }
272 }
273
QueryEventsFromDb(std::vector<std::shared_ptr<AppEventPack>> & events)274 void AppEventProcessorProxy::QueryEventsFromDb(std::vector<std::shared_ptr<AppEventPack>>& events)
275 {
276 int64_t seq = GetSeq();
277 std::string name = GetName();
278 if (AppEventStore::GetInstance().QueryEvents(events, seq, MAX_SIZE_ON_EVENTS) != 0) {
279 HILOG_WARN(LOG_CORE, "failed to take data from observer=%{public}s, seq=%{public}" PRId64,
280 name.c_str(), seq);
281 return;
282 }
283 HILOG_INFO(LOG_CORE, "end to take data from observer=%{public}s, seq=%{public}" PRId64 ", size=%{public}zu",
284 name.c_str(), seq, events.size());
285 }
286 } // namespace HiAppEvent
287 } // namespace HiviewDFX
288 } // namespace OHOS
289