1 /*
2  * Copyright (c) 2024 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 
16 #include "appevent_watcher_impl.h"
17 #include "log.h"
18 
19 using namespace OHOS::HiviewDFX;
20 
21 namespace OHOS {
22 namespace CJSystemapi {
23 namespace HiAppEvent {
FreeCParameters(CParameters par)24 void FreeCParameters(CParameters par)
25 {
26     free(par.key);
27     free(par.value);
28 }
29 
FreeCArrParameters(CArrParameters par)30 void FreeCArrParameters(CArrParameters par)
31 {
32     if (par.head != nullptr) {
33         for (int64_t i = 0; i < par.size; i++) {
34             FreeCParameters(par.head[i]);
35         }
36         free(par.head);
37     }
38 }
39 
FreeCAppEventInfo(CAppEventInfo info)40 void FreeCAppEventInfo(CAppEventInfo info)
41 {
42     free(const_cast<char*>(info.domain));
43     free(const_cast<char*>(info.name));
44     FreeCArrParameters(info.cArrParamters);
45 }
46 
~OnTriggerContext()47 OnTriggerContext::~OnTriggerContext()
48 {
49     if (onTrigger != nullptr) {
50         onTrigger = nullptr;
51     }
52     if (holder != nullptr) {
53         delete holder;
54         holder = nullptr;
55     }
56 }
57 
~OnReceiveContext()58 OnReceiveContext::~OnReceiveContext()
59 {
60     if (onReceive != nullptr) {
61         onReceive = nullptr;
62     }
63 }
64 
~WatcherContext()65 WatcherContext::~WatcherContext()
66 {
67     if (triggerContext != nullptr) {
68         delete triggerContext;
69         triggerContext = nullptr;
70     }
71     if (receiveContext != nullptr) {
72         delete receiveContext;
73         receiveContext = nullptr;
74     }
75 }
76 
~AppEventWatcherImpl()77 AppEventWatcherImpl::~AppEventWatcherImpl()
78 {
79     if (context_ != nullptr) {
80         delete context_;
81         context_ = nullptr;
82     }
83 }
84 
AppEventWatcherImpl(const std::string & name,const std::vector<AppEventFilter> & filters,TriggerCondition cond)85 AppEventWatcherImpl::AppEventWatcherImpl(
86     const std::string& name,
87     const std::vector<AppEventFilter>& filters, TriggerCondition cond)
88     : HiviewDFX::AppEventWatcher(name, filters, cond), context_(nullptr) {}
89 
InitTrigger(void (* callbackRef)(int,int,int64_t))90 void AppEventWatcherImpl::InitTrigger(void (*callbackRef)(int, int, int64_t))
91 {
92     if (context_ == nullptr) {
93         context_ = new(std::nothrow) WatcherContext();
94         if (context_ == nullptr) {
95             LOGE("InitTrigger is failed, context_ is null");
96             return;
97         }
98     }
99     if (context_->triggerContext == nullptr) {
100         context_->triggerContext = new(std::nothrow) OnTriggerContext();
101         if (context_->triggerContext == nullptr) {
102             LOGE("InitTrigger is failed, context_->triggerContext is null");
103             return;
104         }
105     }
106     context_->triggerContext->onTrigger = CJLambda::Create(callbackRef);
107 }
108 
InitHolder(AppEventPackageHolderImpl * holder)109 void AppEventWatcherImpl::InitHolder(AppEventPackageHolderImpl* holder)
110 {
111     if (context_ == nullptr) {
112         context_ = new(std::nothrow) WatcherContext();
113         if (context_ == nullptr) {
114             LOGE("InitHolder is failed, context_ is null");
115             return;
116         }
117     }
118     if (context_->triggerContext == nullptr) {
119         context_->triggerContext = new(std::nothrow) OnTriggerContext();
120         if (context_->triggerContext == nullptr) {
121             LOGE("InitHolder is failed, context_->triggerContext is null");
122             return;
123         }
124     }
125     context_->triggerContext->holder = holder;
126 }
127 
InitReceiver(void (* callbackRef)(char *,CArrRetAppEventGroup))128 void AppEventWatcherImpl::InitReceiver(void (*callbackRef)(char*, CArrRetAppEventGroup))
129 {
130     if (context_ == nullptr) {
131         context_ = new(std::nothrow) WatcherContext();
132         if (context_ == nullptr) {
133             LOGE("context_ is null");
134             return;
135         }
136     }
137     if (context_->receiveContext == nullptr) {
138         context_->receiveContext = new(std::nothrow) OnReceiveContext();
139         if (context_->receiveContext == nullptr) {
140             LOGE("context_->receiveContext is null");
141             return;
142         }
143     }
144     context_->receiveContext->onReceive = CJLambda::Create(callbackRef);
145 }
146 
ConvertArrBool(CParameters & retValue,const Json::Value & jsonValue)147 void ConvertArrBool(CParameters &retValue, const Json::Value& jsonValue)
148 {
149     retValue.valueType = TYPE_ARRBOOL;
150     bool* retArrValue = static_cast<bool*>(malloc(sizeof(bool) * retValue.size));
151     if (retArrValue == nullptr) {
152         LOGE("malloc is failed");
153         return;
154     }
155     for (size_t i = 0; i < jsonValue.size(); ++i) {
156         retArrValue[i] = jsonValue[static_cast<int>(i)].asBool();
157     }
158     retValue.value = retArrValue;
159 }
160 
ConvertArrInt(CParameters & retValue,const Json::Value & jsonValue)161 void ConvertArrInt(CParameters &retValue, const Json::Value& jsonValue)
162 {
163     retValue.valueType = TYPE_ARRINT;
164     int32_t* retArrValue = static_cast<int32_t*>(malloc(sizeof(int32_t) * retValue.size));
165     if (retArrValue == nullptr) {
166         LOGE("malloc is failed");
167         return;
168     }
169     for (size_t i = 0; i < jsonValue.size(); ++i) {
170         retArrValue[i] = jsonValue[static_cast<int>(i)].asInt();
171     }
172     retValue.value = retArrValue;
173 }
174 
CovertArrDouble(CParameters & retValue,const Json::Value & jsonValue)175 void CovertArrDouble(CParameters &retValue, const Json::Value& jsonValue)
176 {
177     retValue.valueType = TYPE_ARRFLOAT;
178     double* retArrValue = static_cast<double*>(malloc(sizeof(double) * retValue.size));
179     if (retArrValue == nullptr) {
180         LOGE("malloc is failed");
181         return;
182     }
183     for (size_t i = 0; i < jsonValue.size(); ++i) {
184         retArrValue[i] = jsonValue[static_cast<int>(i)].asDouble();
185     }
186     retValue.value = retArrValue;
187 }
188 
CovertArrString(CParameters & retValue,const Json::Value & jsonValue)189 void CovertArrString(CParameters &retValue, const Json::Value& jsonValue)
190 {
191     retValue.valueType = TYPE_ARRSTRING;
192     char** retArrValue = static_cast<char**>(malloc(sizeof(char*) * retValue.size));
193     if (retArrValue == nullptr) {
194         LOGE("malloc is failed");
195         return;
196     }
197     for (size_t i = 0; i < jsonValue.size(); ++i) {
198         retArrValue[i] = MallocCString(jsonValue[static_cast<int>(i)].asString());
199     }
200     retValue.value = retArrValue;
201 }
202 
CovertArrObjStr(CParameters & retValue,const Json::Value & jsonValue)203 void CovertArrObjStr(CParameters &retValue, const Json::Value& jsonValue)
204 {
205     retValue.valueType = TYPE_ARRSTRING;
206     char** retArrValue = static_cast<char**>(malloc(sizeof(char*) * retValue.size));
207     if (retArrValue == nullptr) {
208         LOGE("malloc is failed");
209         return;
210     }
211     for (size_t i = 0; i < jsonValue.size(); ++i) {
212         Json::FastWriter writer;
213         std::string json_string = writer.write(jsonValue[static_cast<int>(i)]);
214         retArrValue[i] = MallocCString(json_string);
215     }
216     retValue.value = retArrValue;
217 }
218 
CreatArr(CParameters & retValue,const Json::Value & jsonValue)219 void CreatArr(CParameters &retValue, const Json::Value& jsonValue)
220 {
221     retValue.size = jsonValue.size();
222     if (jsonValue[static_cast<int>(0)].isBool()) {
223         ConvertArrBool(retValue, jsonValue);
224     } else if (jsonValue[static_cast<int>(0)].isInt()) {
225         ConvertArrInt(retValue, jsonValue);
226     } else if (jsonValue[static_cast<int>(0)].isDouble()) {
227         CovertArrDouble(retValue, jsonValue);
228     } else if (jsonValue[static_cast<int>(0)].isString()) {
229         CovertArrString(retValue, jsonValue);
230     } else {
231         CovertArrObjStr(retValue, jsonValue);
232     }
233 }
234 
CreatElmInt(CParameters & retValue,const Json::Value & jsonValue)235 void CreatElmInt(CParameters &retValue, const Json::Value& jsonValue)
236 {
237     retValue.size = 1;
238     retValue.valueType = TYPE_INT;
239     int* retInt = static_cast<int*>(malloc(sizeof(int) * retValue.size));
240     if (retInt == nullptr) {
241         LOGE("malloc is failed");
242         return;
243     }
244     retInt[0] = jsonValue.asInt();
245     retValue.value = retInt;
246 }
247 
CreatElmBool(CParameters & retValue,const Json::Value & jsonValue)248 void CreatElmBool(CParameters &retValue, const Json::Value& jsonValue)
249 {
250     retValue.size = 1;
251     retValue.valueType = TYPE_BOOL;
252     bool* retBool = static_cast<bool*>(malloc(sizeof(bool) * retValue.size));
253     if (retBool == nullptr) {
254         LOGE("malloc is failed");
255         return;
256     }
257     retBool[0] = jsonValue.asBool();
258     retValue.value = retBool;
259 }
260 
CreatElmDou(CParameters & retValue,const Json::Value & jsonValue)261 void CreatElmDou(CParameters &retValue, const Json::Value& jsonValue)
262 {
263     retValue.size = 1;
264     retValue.valueType = TYPE_FLOAT;
265     double* retF = static_cast<double*>(malloc(sizeof(double) * retValue.size));
266     if (retF == nullptr) {
267         LOGE("malloc is failed");
268         return;
269     }
270     retF[0] = jsonValue.asDouble();
271     retValue.value = retF;
272 }
273 
CreatElmStr(CParameters & retValue,const Json::Value & jsonValue)274 void CreatElmStr(CParameters &retValue, const Json::Value& jsonValue)
275 {
276     retValue.size = 1;
277     retValue.valueType = TYPE_STRING;
278     retValue.value = MallocCString(jsonValue.asString());
279 }
280 
CreatObjStr(CParameters & retValue,const Json::Value & jsonValue)281 void CreatObjStr(CParameters &retValue, const Json::Value& jsonValue)
282 {
283     retValue.size = 1;
284     retValue.valueType = TYPE_STRING;
285     Json::FastWriter writer;
286     std::string json_string = writer.write(jsonValue);
287     retValue.value = MallocCString(json_string);
288 }
289 
CreateValueByJson(CParameters & retValue,const Json::Value & jsonValue)290 void CreateValueByJson(CParameters &retValue, const Json::Value& jsonValue)
291 {
292     if (jsonValue.isArray()) {
293         CreatArr(retValue, jsonValue);
294     } else if (jsonValue.isInt()) {
295         CreatElmInt(retValue, jsonValue);
296     } else if (jsonValue.isBool()) {
297         CreatElmBool(retValue, jsonValue);
298     } else if (jsonValue.isDouble()) {
299         CreatElmDou(retValue, jsonValue);
300     } else if (jsonValue.isString()) {
301         CreatElmStr(retValue, jsonValue);
302     } else {
303         CreatObjStr(retValue, jsonValue);
304     }
305 }
306 
CreateValueByJsonStr(const std::string & jsonStr)307 CArrParameters CreateValueByJsonStr(const std::string& jsonStr)
308 {
309     CArrParameters pameters{0};
310     Json::Value jsonValue;
311     Json::Reader reader(Json::Features::strictMode());
312     if (!reader.parse(jsonStr, jsonValue)) {
313         LOGE("parse event detail info failed, please check the style of json");
314         return pameters;
315     }
316 
317     auto eventNameList = jsonValue.getMemberNames();
318     pameters.size = static_cast<int64_t>(eventNameList.size());
319     CParameters* retValue = static_cast<CParameters*>(malloc(sizeof(CParameters) * pameters.size));
320     if (retValue == nullptr) {
321         LOGE("malloc is failed");
322         return pameters;
323     }
324     int i = 0;
325     for (const auto& it : eventNameList) {
326         const auto& propertyName = it;
327         retValue[i].key = MallocCString(propertyName);
328         CreateValueByJson(retValue[i], jsonValue[propertyName]);
329         ++i;
330     }
331     pameters.head = retValue;
332     return pameters;
333 }
334 
FreeRetValue(RetAppEventGroup * retValue,size_t index)335 void FreeRetValue(RetAppEventGroup* retValue, size_t index)
336 {
337     if (retValue == nullptr) {
338         return;
339     }
340     for (size_t i = 0; i < index; i++) {
341         free(retValue[i].name);
342         if (retValue[i].appEventInfos.head == nullptr) {
343             continue;
344         }
345         for (int64_t j = 0; j < retValue[i].appEventInfos.size; j++) {
346             FreeCAppEventInfo(retValue[i].appEventInfos.head[j]);
347         }
348     }
349     free(retValue);
350     LOGE("malloc is failed");
351 }
352 
getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)353 CArrRetAppEventGroup getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
354 {
355     CArrRetAppEventGroup eventGroups;
356     std::unordered_map<std::string, std::vector<std::shared_ptr<AppEventPack>>> eventMap;
357     for (const auto& event : events) {
358         eventMap[event->GetName()].emplace_back(event);
359     }
360     eventGroups.size = static_cast<int64_t>(eventMap.size());
361     eventGroups.head = nullptr;
362     if (eventGroups.size > 0) {
363         RetAppEventGroup* retValue1 = static_cast<RetAppEventGroup*>
364                                         (malloc(sizeof(RetAppEventGroup) * eventGroups.size));
365         if (retValue1 == nullptr) {
366             LOGE("malloc is failed");
367             return eventGroups;
368         }
369         size_t index = 0;
370         bool fail = false;
371         for (const auto& it : eventMap) {
372             retValue1[index].name = MallocCString(it.first);
373             CArrAppEventInfo appEventInfos;
374             appEventInfos.size = static_cast<int64_t>(it.second.size());
375             CAppEventInfo* retValue2 = static_cast<CAppEventInfo*>(malloc(sizeof(CAppEventInfo)
376                                         * it.second.size()));
377             if (retValue2 == nullptr) {
378                 free(retValue1[index].name);
379                 fail = true;
380                 break;
381             }
382             for (size_t i = 0; i < it.second.size(); ++i) {
383                 retValue2[i].domain = MallocCString(it.second[i]->GetDomain());
384                 retValue2[i].name = MallocCString(it.second[i]->GetName());
385                 retValue2[i].event = it.second[i]->GetType();
386                 retValue2[i].cArrParamters = CreateValueByJsonStr(it.second[i]->GetParamStr());
387             }
388             appEventInfos.head = retValue2;
389             retValue1[index++].appEventInfos = appEventInfos;
390         }
391         if (fail) {
392             FreeRetValue(retValue1, index);
393             return CArrRetAppEventGroup{0};
394         }
395         eventGroups.head = retValue1;
396     }
397     return eventGroups;
398 }
399 
OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)400 void AppEventWatcherImpl::OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
401 {
402     if (context_ == nullptr || context_->receiveContext == nullptr) {
403         LOGE("onReceive context is null");
404         return;
405     }
406     if (events.empty()) {
407         return;
408     }
409     context_->receiveContext->domain = events[0]->GetDomain();
410     context_->receiveContext->events = events;
411     CArrRetAppEventGroup eventGroups = getEventGroups(events);
412     if (eventGroups.head == nullptr) {
413         return;
414     }
415     char* cjDomain = MallocCString(context_->receiveContext->domain);
416     if (cjDomain == nullptr) {
417         free(eventGroups.head);
418         LOGE("malloc is failed");
419         return;
420     }
421     context_->receiveContext->onReceive(cjDomain, eventGroups);
422 }
423 
OnTrigger(const HiviewDFX::TriggerCondition & triggerCond)424 void AppEventWatcherImpl::OnTrigger(const HiviewDFX::TriggerCondition& triggerCond)
425 {
426     if (context_ == nullptr || context_->triggerContext == nullptr) {
427         LOGE("onTrigger context is null");
428         return;
429     }
430     context_->triggerContext->row = triggerCond.row;
431     context_->triggerContext->size = triggerCond.size;
432     context_->triggerContext->onTrigger(triggerCond.row, triggerCond.size,
433                                         context_->triggerContext->holder->GetID());
434 }
435 
IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)436 bool AppEventWatcherImpl::IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)
437 {
438     return (context_ != nullptr && context_->receiveContext != nullptr);
439 }
440 } // HiAppEvent
441 } // CJSystemapi
442 } // OHOS
443 
444