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
CovertArrDouble(CParameters & retValue,const Json::Value & jsonValue)181 void CovertArrDouble(CParameters &retValue, const Json::Value& jsonValue)
182 {
183 retValue.valueType = TYPE_ARRFLOAT;
184 double* retArrValue = static_cast<double*>(malloc(sizeof(double) * 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)].asDouble();
191 }
192 retValue.value = retArrValue;
193 }
194
CovertArrString(CParameters & retValue,const Json::Value & jsonValue)195 void CovertArrString(CParameters &retValue, const Json::Value& jsonValue)
196 {
197 retValue.valueType = TYPE_ARRSTRING;
198 char** retArrValue = static_cast<char**>(malloc(sizeof(char*) * 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] = MallocCString(jsonValue[static_cast<int>(i)].asString());
205 }
206 retValue.value = retArrValue;
207 }
208
CovertArrObjStr(CParameters & retValue,const Json::Value & jsonValue)209 void CovertArrObjStr(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 Json::FastWriter writer;
219 std::string json_string = writer.write(jsonValue[static_cast<int>(i)]);
220 retArrValue[i] = MallocCString(json_string);
221 }
222 retValue.value = retArrValue;
223 }
224
CreatArr(CParameters & retValue,const Json::Value & jsonValue)225 void CreatArr(CParameters &retValue, const Json::Value& jsonValue)
226 {
227 retValue.size = jsonValue.size();
228 if (jsonValue[static_cast<int>(0)].isBool()) {
229 ConvertArrBool(retValue, jsonValue);
230 } else if (jsonValue[static_cast<int>(0)].isInt()) {
231 ConvertArrInt(retValue, jsonValue);
232 } else if (jsonValue[static_cast<int>(0)].isDouble()) {
233 CovertArrDouble(retValue, jsonValue);
234 } else if (jsonValue[static_cast<int>(0)].isString()) {
235 CovertArrString(retValue, jsonValue);
236 } else {
237 CovertArrObjStr(retValue, jsonValue);
238 }
239 }
240
CreatElmInt(CParameters & retValue,const Json::Value & jsonValue)241 void CreatElmInt(CParameters &retValue, const Json::Value& jsonValue)
242 {
243 retValue.size = 1;
244 retValue.valueType = TYPE_INT;
245 int* retInt = static_cast<int*>(malloc(sizeof(int) * retValue.size));
246 if (retInt == nullptr) {
247 LOGE("malloc is failed");
248 return;
249 }
250 retInt[0] = jsonValue.asInt();
251 retValue.value = retInt;
252 }
253
CreatElmBool(CParameters & retValue,const Json::Value & jsonValue)254 void CreatElmBool(CParameters &retValue, const Json::Value& jsonValue)
255 {
256 retValue.size = 1;
257 retValue.valueType = TYPE_BOOL;
258 bool* retBool = static_cast<bool*>(malloc(sizeof(bool) * retValue.size));
259 if (retBool == nullptr) {
260 LOGE("malloc is failed");
261 return;
262 }
263 retBool[0] = jsonValue.asBool();
264 retValue.value = retBool;
265 }
266
CreatElmDou(CParameters & retValue,const Json::Value & jsonValue)267 void CreatElmDou(CParameters &retValue, const Json::Value& jsonValue)
268 {
269 retValue.size = 1;
270 retValue.valueType = TYPE_FLOAT;
271 double* retF = static_cast<double*>(malloc(sizeof(double) * retValue.size));
272 if (retF == nullptr) {
273 LOGE("malloc is failed");
274 return;
275 }
276 retF[0] = jsonValue.asDouble();
277 retValue.value = retF;
278 }
279
CreatElmStr(CParameters & retValue,const Json::Value & jsonValue)280 void CreatElmStr(CParameters &retValue, const Json::Value& jsonValue)
281 {
282 retValue.size = 1;
283 retValue.valueType = TYPE_STRING;
284 retValue.value = MallocCString(jsonValue.asString());
285 }
286
CreatObjStr(CParameters & retValue,const Json::Value & jsonValue)287 void CreatObjStr(CParameters &retValue, const Json::Value& jsonValue)
288 {
289 retValue.size = 1;
290 retValue.valueType = TYPE_STRING;
291 Json::FastWriter writer;
292 std::string json_string = writer.write(jsonValue);
293 retValue.value = MallocCString(json_string);
294 }
295
CreateValueByJson(CParameters & retValue,const Json::Value & jsonValue)296 void CreateValueByJson(CParameters &retValue, const Json::Value& jsonValue)
297 {
298 if (jsonValue.isArray()) {
299 CreatArr(retValue, jsonValue);
300 } else if (jsonValue.isInt()) {
301 CreatElmInt(retValue, jsonValue);
302 } else if (jsonValue.isBool()) {
303 CreatElmBool(retValue, jsonValue);
304 } else if (jsonValue.isDouble()) {
305 CreatElmDou(retValue, jsonValue);
306 } else if (jsonValue.isString()) {
307 CreatElmStr(retValue, jsonValue);
308 } else {
309 CreatObjStr(retValue, jsonValue);
310 }
311 }
312
CreateValueByJsonStr(const std::string & jsonStr)313 CArrParameters CreateValueByJsonStr(const std::string& jsonStr)
314 {
315 CArrParameters pameters{0};
316 Json::Value jsonValue;
317 Json::Reader reader(Json::Features::strictMode());
318 if (!reader.parse(jsonStr, jsonValue)) {
319 LOGE("parse event detail info failed, please check the style of json");
320 return pameters;
321 }
322
323 auto eventNameList = jsonValue.getMemberNames();
324 pameters.size = static_cast<int64_t>(eventNameList.size());
325 CParameters* retValue = static_cast<CParameters*>(malloc(sizeof(CParameters) * pameters.size));
326 if (retValue == nullptr) {
327 LOGE("malloc is failed");
328 return pameters;
329 }
330 int i = 0;
331 for (const auto& it : eventNameList) {
332 const auto& propertyName = it;
333 retValue[i].key = MallocCString(propertyName);
334 CreateValueByJson(retValue[i], jsonValue[propertyName]);
335 ++i;
336 }
337 pameters.head = retValue;
338 return pameters;
339 }
340
FreeRetValue(RetAppEventGroup * retValue,size_t index)341 void FreeRetValue(RetAppEventGroup* retValue, size_t index)
342 {
343 if (retValue == nullptr) {
344 return;
345 }
346 for (size_t i = 0; i < index; i++) {
347 free(retValue[i].name);
348 if (retValue[i].appEventInfos.head == nullptr) {
349 continue;
350 }
351 for (int64_t j = 0; j < retValue[i].appEventInfos.size; j++) {
352 FreeCAppEventInfo(retValue[i].appEventInfos.head[j]);
353 }
354 }
355 free(retValue);
356 LOGE("malloc is failed");
357 }
358
getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)359 CArrRetAppEventGroup getEventGroups(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
360 {
361 CArrRetAppEventGroup eventGroups;
362 std::unordered_map<std::string, std::vector<std::shared_ptr<AppEventPack>>> eventMap;
363 for (const auto& event : events) {
364 eventMap[event->GetName()].emplace_back(event);
365 }
366 eventGroups.size = static_cast<int64_t>(eventMap.size());
367 eventGroups.head = nullptr;
368 if (eventGroups.size > 0) {
369 RetAppEventGroup* retValue1 = static_cast<RetAppEventGroup*>
370 (malloc(sizeof(RetAppEventGroup) * eventGroups.size));
371 if (retValue1 == nullptr) {
372 LOGE("malloc is failed");
373 return eventGroups;
374 }
375 size_t index = 0;
376 bool fail = false;
377 for (const auto& it : eventMap) {
378 retValue1[index].name = MallocCString(it.first);
379 CArrAppEventInfo appEventInfos;
380 appEventInfos.size = static_cast<int64_t>(it.second.size());
381 CAppEventInfo* retValue2 = static_cast<CAppEventInfo*>(malloc(sizeof(CAppEventInfo)
382 * it.second.size()));
383 if (retValue2 == nullptr) {
384 free(retValue1[index].name);
385 fail = true;
386 break;
387 }
388 for (size_t i = 0; i < it.second.size(); ++i) {
389 retValue2[i].domain = MallocCString(it.second[i]->GetDomain());
390 retValue2[i].name = MallocCString(it.second[i]->GetName());
391 retValue2[i].event = it.second[i]->GetType();
392 retValue2[i].cArrParamters = CreateValueByJsonStr(it.second[i]->GetParamStr());
393 }
394 appEventInfos.head = retValue2;
395 retValue1[index++].appEventInfos = appEventInfos;
396 }
397 if (fail) {
398 FreeRetValue(retValue1, index);
399 return CArrRetAppEventGroup{0};
400 }
401 eventGroups.head = retValue1;
402 }
403 return eventGroups;
404 }
405
OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>> & events)406 void AppEventWatcherImpl::OnEvents(const std::vector<std::shared_ptr<OHOS::HiviewDFX::AppEventPack>>& events)
407 {
408 if (context_ == nullptr || context_->receiveContext == nullptr) {
409 LOGE("onReceive context is null");
410 return;
411 }
412 if (events.empty()) {
413 return;
414 }
415 context_->receiveContext->domain = events[0]->GetDomain();
416 context_->receiveContext->events = events;
417 CArrRetAppEventGroup eventGroups = getEventGroups(events);
418 if (eventGroups.head == nullptr) {
419 return;
420 }
421 char* cjDomain = MallocCString(context_->receiveContext->domain);
422 if (cjDomain == nullptr) {
423 free(eventGroups.head);
424 LOGE("malloc is failed");
425 return;
426 }
427 context_->receiveContext->onReceive(cjDomain, eventGroups);
428 }
429
OnTrigger(const HiviewDFX::TriggerCondition & triggerCond)430 void AppEventWatcherImpl::OnTrigger(const HiviewDFX::TriggerCondition& triggerCond)
431 {
432 if (context_ == nullptr || context_->triggerContext == nullptr) {
433 LOGE("onTrigger context is null");
434 return;
435 }
436 context_->triggerContext->row = triggerCond.row;
437 context_->triggerContext->size = triggerCond.size;
438 context_->triggerContext->onTrigger(triggerCond.row, triggerCond.size,
439 context_->triggerContext->holder->GetID());
440 }
441
IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)442 bool AppEventWatcherImpl::IsRealTimeEvent(std::shared_ptr<OHOS::HiviewDFX::AppEventPack> event)
443 {
444 return (context_ != nullptr && context_->receiveContext != nullptr);
445 }
446 } // HiAppEvent
447 } // CJSystemapi
448 } // OHOS
449
450