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