• 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_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