• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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             delete context_;
103             context_ = nullptr;
104             LOGE("InitTrigger is failed, context_->triggerContext is null");
105             return;
106         }
107     }
108     context_->triggerContext->onTrigger = CJLambda::Create(callbackRef);
109 }
110 
InitHolder(AppEventPackageHolderImpl * holder)111 void AppEventWatcherImpl::InitHolder(AppEventPackageHolderImpl* holder)
112 {
113     if (context_ == nullptr) {
114         context_ = new(std::nothrow) WatcherContext();
115         if (context_ == nullptr) {
116             LOGE("InitHolder is failed, context_ is null");
117             return;
118         }
119     }
120     if (context_->triggerContext == nullptr) {
121         context_->triggerContext = new(std::nothrow) OnTriggerContext();
122         if (context_->triggerContext == nullptr) {
123             delete context_;
124             context_ = nullptr;
125             LOGE("InitHolder is failed, context_->triggerContext is null");
126             return;
127         }
128     }
129     context_->triggerContext->holder = holder;
130 }
131 
InitReceiver(void (* callbackRef)(char *,CArrRetAppEventGroup))132 void AppEventWatcherImpl::InitReceiver(void (*callbackRef)(char*, CArrRetAppEventGroup))
133 {
134     if (context_ == nullptr) {
135         context_ = new(std::nothrow) WatcherContext();
136         if (context_ == nullptr) {
137             LOGE("context_ is null");
138             return;
139         }
140     }
141     if (context_->receiveContext == nullptr) {
142         context_->receiveContext = new(std::nothrow) OnReceiveContext();
143         if (context_->receiveContext == nullptr) {
144             delete context_;
145             context_ = nullptr;
146             LOGE("context_->receiveContext is null");
147             return;
148         }
149     }
150     context_->receiveContext->onReceive = CJLambda::Create(callbackRef);
151 }
152 
ConvertArrBool(CParameters & retValue,const Json::Value & jsonValue)153 void ConvertArrBool(CParameters &retValue, const Json::Value& jsonValue)
154 {
155     retValue.valueType = TYPE_ARRBOOL;
156     bool* retArrValue = static_cast<bool*>(malloc(sizeof(bool) * retValue.size));
157     if (retArrValue == nullptr) {
158         LOGE("malloc is failed");
159         return;
160     }
161     for (size_t i = 0; i < jsonValue.size(); ++i) {
162         retArrValue[i] = jsonValue[static_cast<int>(i)].asBool();
163     }
164     retValue.value = retArrValue;
165 }
166 
ConvertArrInt(CParameters & retValue,const Json::Value & jsonValue)167 void ConvertArrInt(CParameters &retValue, const Json::Value& jsonValue)
168 {
169     retValue.valueType = TYPE_ARRINT;
170     int32_t* retArrValue = static_cast<int32_t*>(malloc(sizeof(int32_t) * retValue.size));
171     if (retArrValue == nullptr) {
172         LOGE("malloc is failed");
173         return;
174     }
175     for (size_t i = 0; i < jsonValue.size(); ++i) {
176         retArrValue[i] = jsonValue[static_cast<int>(i)].asInt();
177     }
178     retValue.value = retArrValue;
179 }
180 
ConvertArrInt64(CParameters & retValue,const Json::Value & jsonValue)181 void ConvertArrInt64(CParameters &retValue, const Json::Value& jsonValue)
182 {
183     retValue.valueType = TYPE_ARRINT64;
184     int64_t* retArrValue = static_cast<int64_t*>(malloc(sizeof(int64_t) * retValue.size));
185     if (retArrValue == nullptr) {
186         LOGE("malloc is failed");
187         return;
188     }
189     for (size_t i = 0; i < jsonValue.size(); ++i) {
190         retArrValue[i] = jsonValue[static_cast<int>(i)].asInt64();
191     }
192     retValue.value = retArrValue;
193 }
194 
CovertArrDouble(CParameters & retValue,const Json::Value & jsonValue)195 void CovertArrDouble(CParameters &retValue, const Json::Value& jsonValue)
196 {
197     retValue.valueType = TYPE_ARRFLOAT;
198     double* retArrValue = static_cast<double*>(malloc(sizeof(double) * retValue.size));
199     if (retArrValue == nullptr) {
200         LOGE("malloc is failed");
201         return;
202     }
203     for (size_t i = 0; i < jsonValue.size(); ++i) {
204         retArrValue[i] = jsonValue[static_cast<int>(i)].asDouble();
205     }
206     retValue.value = retArrValue;
207 }
208 
CovertArrString(CParameters & retValue,const Json::Value & jsonValue)209 void CovertArrString(CParameters &retValue, const Json::Value& jsonValue)
210 {
211     retValue.valueType = TYPE_ARRSTRING;
212     char** retArrValue = static_cast<char**>(malloc(sizeof(char*) * retValue.size));
213     if (retArrValue == nullptr) {
214         LOGE("malloc is failed");
215         return;
216     }
217     for (size_t i = 0; i < jsonValue.size(); ++i) {
218         retArrValue[i] = MallocCString(jsonValue[static_cast<int>(i)].asString());
219     }
220     retValue.value = retArrValue;
221 }
222 
CovertArrObjStr(CParameters & retValue,const Json::Value & jsonValue)223 void CovertArrObjStr(CParameters &retValue, const Json::Value& jsonValue)
224 {
225     retValue.valueType = TYPE_ARRSTRING;
226     char** retArrValue = static_cast<char**>(malloc(sizeof(char*) * retValue.size));
227     if (retArrValue == nullptr) {
228         LOGE("malloc is failed");
229         return;
230     }
231     for (size_t i = 0; i < jsonValue.size(); ++i) {
232         Json::FastWriter writer;
233         std::string json_string = writer.write(jsonValue[static_cast<int>(i)]);
234         retArrValue[i] = MallocCString(json_string);
235     }
236     retValue.value = retArrValue;
237 }
238 
CheckArrBool(const Json::Value & jsonValue)239 bool CheckArrBool(const Json::Value& jsonValue)
240 {
241     size_t nBool = 0;
242     for (size_t i = 0; i < jsonValue.size(); ++i) {
243         if (jsonValue[static_cast<int>(i)].isBool()) {
244             nBool++;
245         }
246     }
247     return nBool == jsonValue.size();
248 }
249 
CheckArrInt(const Json::Value & jsonValue)250 bool CheckArrInt(const Json::Value& jsonValue)
251 {
252     size_t nInt = 0;
253     for (size_t i = 0; i < jsonValue.size(); ++i) {
254         if (jsonValue[static_cast<int>(i)].isInt()) {
255             nInt++;
256         }
257     }
258     return nInt == jsonValue.size();
259 }
260 
CheckArrInt64(const Json::Value & jsonValue)261 bool CheckArrInt64(const Json::Value& jsonValue)
262 {
263     size_t nInt = 0;
264     for (size_t i = 0; i < jsonValue.size(); ++i) {
265         if (jsonValue[static_cast<int>(i)].isInt64() && jsonValue.type() != Json::ValueType::uintValue) {
266             nInt++;
267         }
268     }
269     return nInt == jsonValue.size();
270 }
271 
CheckArrDouble(const Json::Value & jsonValue)272 bool CheckArrDouble(const Json::Value& jsonValue)
273 {
274     size_t nDouble = 0;
275     for (size_t i = 0; i < jsonValue.size(); ++i) {
276         if (jsonValue[static_cast<int>(i)].isDouble()) {
277             nDouble++;
278         }
279     }
280     return nDouble == jsonValue.size();
281 }
282 
CheckArrString(const Json::Value & jsonValue)283 bool CheckArrString(const Json::Value& jsonValue)
284 {
285     size_t nString = 0;
286     for (size_t i = 0; i < jsonValue.size(); ++i) {
287         if (jsonValue[static_cast<int>(i)].isString()) {
288             nString++;
289         }
290     }
291     return nString == jsonValue.size();
292 }
293 
CreatArr(CParameters & retValue,const Json::Value & jsonValue)294 void CreatArr(CParameters &retValue, const Json::Value& jsonValue)
295 {
296     retValue.size = jsonValue.size();
297     if (CheckArrBool(jsonValue)) {
298         ConvertArrBool(retValue, jsonValue);
299     } else if (CheckArrInt(jsonValue)) {
300         ConvertArrInt(retValue, jsonValue);
301     } else if (CheckArrDouble(jsonValue)) {
302         CovertArrDouble(retValue, jsonValue);
303     } else if (CheckArrString(jsonValue)) {
304         CovertArrString(retValue, jsonValue);
305     } else if (CheckArrInt64(jsonValue)) {
306         ConvertArrInt64(retValue, jsonValue);
307     } else {
308         CovertArrObjStr(retValue, jsonValue);
309     }
310 }
311 
CreatElmInt(CParameters & retValue,const Json::Value & jsonValue)312 void CreatElmInt(CParameters &retValue, const Json::Value& jsonValue)
313 {
314     retValue.size = 1;
315     retValue.valueType = TYPE_INT;
316     int32_t* retInt = static_cast<int32_t*>(malloc(sizeof(int32_t) * retValue.size));
317     if (retInt == nullptr) {
318         LOGE("malloc is failed");
319         return;
320     }
321     retInt[0] = jsonValue.asInt();
322     retValue.value = retInt;
323 }
324 
CreatElmInt64(CParameters & retValue,const Json::Value & jsonValue)325 void CreatElmInt64(CParameters &retValue, const Json::Value& jsonValue)
326 {
327     retValue.size = 1;
328     retValue.valueType = TYPE_INT64;
329     int64_t* retInt = static_cast<int64_t*>(malloc(sizeof(int64_t) * retValue.size));
330     if (retInt == nullptr) {
331         LOGE("malloc is failed");
332         return;
333     }
334     retInt[0] = jsonValue.asInt64();
335     retValue.value = retInt;
336 }
337 
CreatElmBool(CParameters & retValue,const Json::Value & jsonValue)338 void CreatElmBool(CParameters &retValue, const Json::Value& jsonValue)
339 {
340     retValue.size = 1;
341     retValue.valueType = TYPE_BOOL;
342     bool* retBool = static_cast<bool*>(malloc(sizeof(bool) * retValue.size));
343     if (retBool == nullptr) {
344         LOGE("malloc is failed");
345         return;
346     }
347     retBool[0] = jsonValue.asBool();
348     retValue.value = retBool;
349 }
350 
CreatElmDou(CParameters & retValue,const Json::Value & jsonValue)351 void CreatElmDou(CParameters &retValue, const Json::Value& jsonValue)
352 {
353     retValue.size = 1;
354     retValue.valueType = TYPE_FLOAT;
355     double* retF = static_cast<double*>(malloc(sizeof(double) * retValue.size));
356     if (retF == nullptr) {
357         LOGE("malloc is failed");
358         return;
359     }
360     retF[0] = jsonValue.asDouble();
361     retValue.value = retF;
362 }
363 
CreatElmStr(CParameters & retValue,const Json::Value & jsonValue)364 void CreatElmStr(CParameters &retValue, const Json::Value& jsonValue)
365 {
366     retValue.size = 1;
367     retValue.valueType = TYPE_STRING;
368     retValue.value = MallocCString(jsonValue.asString());
369 }
370 
CreatObjStr(CParameters & retValue,const Json::Value & jsonValue)371 void CreatObjStr(CParameters &retValue, const Json::Value& jsonValue)
372 {
373     retValue.size = 1;
374     retValue.valueType = TYPE_STRING;
375     Json::FastWriter writer;
376     std::string json_string = writer.write(jsonValue);
377     retValue.value = MallocCString(json_string);
378 }
379 
CreateValueByJson(CParameters & retValue,const Json::Value & jsonValue)380 void CreateValueByJson(CParameters &retValue, const Json::Value& jsonValue)
381 {
382     if (jsonValue.isArray()) {
383         CreatArr(retValue, jsonValue);
384     } else if (jsonValue.isInt()) {
385         CreatElmInt(retValue, jsonValue);
386     } else if (jsonValue.isBool()) {
387         CreatElmBool(retValue, jsonValue);
388     } else if (jsonValue.isDouble()) {
389         CreatElmDou(retValue, jsonValue);
390     } else if (jsonValue.isString()) {
391         CreatElmStr(retValue, jsonValue);
392     } else if (jsonValue.isInt64() && jsonValue.type() != Json::ValueType::uintValue) {
393         CreatElmInt64(retValue, jsonValue);
394     } else {
395         CreatObjStr(retValue, jsonValue);
396     }
397 }
398 
CreateValueByJsonStr(const std::string & jsonStr)399 CArrParameters CreateValueByJsonStr(const std::string& jsonStr)
400 {
401     CArrParameters pameters{0};
402     Json::Value jsonValue;
403     Json::Reader reader(Json::Features::strictMode());
404     if (!reader.parse(jsonStr, jsonValue)) {
405         LOGE("parse event detail info failed, please check the style of json");
406         return pameters;
407     }
408 
409     auto eventNameList = jsonValue.getMemberNames();
410     pameters.size = static_cast<int64_t>(eventNameList.size());
411     CParameters* retValue = static_cast<CParameters*>(malloc(sizeof(CParameters) * pameters.size));
412     if (retValue == nullptr) {
413         LOGE("malloc is failed");
414         return pameters;
415     }
416     int i = 0;
417     for (const auto& it : eventNameList) {
418         const auto& propertyName = it;
419         retValue[i].key = MallocCString(propertyName);
420         CreateValueByJson(retValue[i], jsonValue[propertyName]);
421         ++i;
422     }
423     pameters.head = retValue;
424     return pameters;
425 }
426 
FreeRetValue(RetAppEventGroup * retValue,size_t index)427 void FreeRetValue(RetAppEventGroup* retValue, size_t index)
428 {
429     if (retValue == nullptr) {
430         return;
431     }
432     for (size_t i = 0; i < index; i++) {
433         free(retValue[i].name);
434         if (retValue[i].appEventInfos.head == nullptr) {
435             continue;
436         }
437         for (int64_t j = 0; j < retValue[i].appEventInfos.size; j++) {
438             FreeCAppEventInfo(retValue[i].appEventInfos.head[j]);
439         }
440     }
441     free(retValue);
442     LOGE("malloc is failed");
443 }
444 
getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)445 CArrRetAppEventGroup getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
446 {
447     CArrRetAppEventGroup eventGroups;
448     std::unordered_map<std::string, std::vector<std::shared_ptr<AppEventPack>>> eventMap;
449     for (const auto& event : events) {
450         eventMap[event->GetName()].emplace_back(event);
451     }
452     eventGroups.size = static_cast<int64_t>(eventMap.size());
453     eventGroups.head = nullptr;
454     if (eventGroups.size > 0) {
455         RetAppEventGroup* retValue1 = static_cast<RetAppEventGroup*>
456                                         (malloc(sizeof(RetAppEventGroup) * eventGroups.size));
457         if (retValue1 == nullptr) {
458             LOGE("malloc is failed");
459             return eventGroups;
460         }
461         size_t index = 0;
462         bool fail = false;
463         for (const auto& it : eventMap) {
464             retValue1[index].name = MallocCString(it.first);
465             CArrAppEventInfo appEventInfos;
466             appEventInfos.size = static_cast<int64_t>(it.second.size());
467             CAppEventInfo* retValue2 = static_cast<CAppEventInfo*>(malloc(sizeof(CAppEventInfo)
468                                         * it.second.size()));
469             if (retValue2 == nullptr) {
470                 free(retValue1[index].name);
471                 fail = true;
472                 break;
473             }
474             for (size_t i = 0; i < it.second.size(); ++i) {
475                 retValue2[i].domain = MallocCString(it.second[i]->GetDomain());
476                 retValue2[i].name = MallocCString(it.second[i]->GetName());
477                 retValue2[i].event = it.second[i]->GetType();
478                 retValue2[i].cArrParamters = CreateValueByJsonStr(it.second[i]->GetParamStr());
479             }
480             appEventInfos.head = retValue2;
481             retValue1[index++].appEventInfos = appEventInfos;
482         }
483         if (fail) {
484             FreeRetValue(retValue1, index);
485             return CArrRetAppEventGroup{0};
486         }
487         eventGroups.head = retValue1;
488     }
489     return eventGroups;
490 }
491 
OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)492 void AppEventWatcherImpl::OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
493 {
494     if (context_ == nullptr || context_->receiveContext == nullptr) {
495         LOGE("onReceive context is null");
496         return;
497     }
498     if (events.empty()) {
499         return;
500     }
501     context_->receiveContext->domain = events[0]->GetDomain();
502     context_->receiveContext->events = events;
503     CArrRetAppEventGroup eventGroups = getEventGroups(events);
504     if (eventGroups.head == nullptr) {
505         return;
506     }
507     char* cjDomain = MallocCString(context_->receiveContext->domain);
508     if (cjDomain == nullptr) {
509         free(eventGroups.head);
510         LOGE("malloc is failed");
511         return;
512     }
513     context_->receiveContext->onReceive(cjDomain, eventGroups);
514 }
515 
OnTrigger(const HiviewDFX::TriggerCondition & triggerCond)516 void AppEventWatcherImpl::OnTrigger(const HiviewDFX::TriggerCondition& triggerCond)
517 {
518     if (context_ == nullptr || context_->triggerContext == nullptr) {
519         LOGE("onTrigger context is null");
520         return;
521     }
522     context_->triggerContext->row = triggerCond.row;
523     context_->triggerContext->size = triggerCond.size;
524     context_->triggerContext->onTrigger(triggerCond.row, triggerCond.size,
525                                         context_->triggerContext->holder->GetID());
526 }
527 
IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)528 bool AppEventWatcherImpl::IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)
529 {
530     return (context_ != nullptr && context_->receiveContext != nullptr);
531 }
532 } // HiAppEvent
533 } // CJSystemapi
534 } // OHOS
535 
536