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 <regex>
17 #include <string>
18 #include <unordered_set>
19 #include <vector>
20
21 #include "appevent_watcher_impl.h"
22 #include "cj_ffi/cj_common_ffi.h"
23 #include "ffi_remote_data.h"
24 #include "hiappevent_ffi.h"
25 #include "hiappevent_impl.h"
26 #include "hiappevent_verify.h"
27 #include "hiappevent_write.h"
28 #include "log.h"
29 #include "error.h"
30 using namespace OHOS::HiviewDFX;
31 using namespace OHOS::CJSystemapi::HiAppEvent;
32
33 namespace {
34 constexpr int ERR_CODE_PARAM_FORMAT = -1;
35 constexpr int ERR_CODE_PARAM_INVALID = -2;
36 const int8_t INT32_VALUE = 0;
37 const int8_t DOUBLE_VALUE = 1;
38 const int8_t STRING_VALUE = 2;
39 const int8_t BOOL_VALUE = 3;
40 const int8_t INT32_ARRAY_VALUE = 4;
41 const int8_t DOUBLE_ARRAY_VALUE = 5;
42 const int8_t STRING_ARRAY_VALUE = 6;
43 const int8_t BOOL_ARRAY_VALUE = 7;
44 const int8_t INT64_VALUE = 8;
45 const int8_t INT64_ARRAY_VALUE = 9;
46 constexpr int BIT_MASK = 1;
47 constexpr unsigned int BIT_ALL_TYPES = 0xff;
48
CheckCondition(TriggerCondition & cond,CTriggerCondition triggerCondition)49 int CheckCondition(TriggerCondition &cond, CTriggerCondition triggerCondition)
50 {
51 int ret = ERR_PARAM;
52 cond.row = triggerCondition.row;
53 if (cond.row < 0) {
54 ret = ERR_INVALID_COND_ROW;
55 return ret;
56 }
57 cond.size = triggerCondition.size;
58 if (cond.size < 0) {
59 ret = ERR_INVALID_COND_SIZE;
60 return ret;
61 }
62 if (triggerCondition.timeOut * HiAppEvent::TIMEOUT_STEP < 0) {
63 ret = ERR_INVALID_COND_TIMEOUT;
64 return ret;
65 }
66 cond.timeout = triggerCondition.timeOut * HiAppEvent::TIMEOUT_STEP;
67 return ret;
68 }
69
CharPtrToVector(char ** charPtr,int size,std::vector<std::string> & result)70 void CharPtrToVector(char** charPtr, int size, std::vector<std::string> &result)
71 {
72 for (int i = 0; i < size; i++) {
73 result.push_back(std::string(charPtr[i]));
74 }
75 }
76
genArrString2Set(const CArrString & str)77 std::unordered_set<std::string> genArrString2Set(const CArrString& str)
78 {
79 std::vector<std::string> strVec;
80 CharPtrToVector(str.head, str.size, strVec);
81 std::unordered_set<std::string> res(strVec.begin(), strVec.end());
82 return res;
83 }
84
ConvertConfigReportProp(const CAppEventReportConfig & config,EventConfig reportConf)85 int ConvertConfigReportProp(const CAppEventReportConfig& config, EventConfig reportConf)
86 {
87 if (config.domain != nullptr) {
88 reportConf.domain = config.domain;
89 }
90 if (config.name != nullptr) {
91 reportConf.name = config.name;
92 }
93 reportConf.isRealTime = config.isRealTime;
94 if (!IsValidEventConfig(reportConf)) {
95 return ERR_CODE_PARAM_INVALID;
96 }
97 return SUCCESS_CODE;
98 }
99
ConvertReportConfig(const CProcessor & processor,ReportConfig & conf)100 int ConvertReportConfig(const CProcessor& processor, ReportConfig& conf)
101 {
102 if (processor.name != nullptr && IsValidProcessorName(std::string(processor.name))) {
103 conf.name = processor.name;
104 } else {
105 return ERR_CODE_PARAM_FORMAT;
106 }
107 conf.debugMode = processor.debugMode;
108 conf.routeInfo = processor.routeInfo;
109 conf.appId = processor.appId;
110 conf.triggerCond.onStartup = processor.onStartReport;
111 conf.triggerCond.onBackground = processor.onBackgroundReport;
112 if (!IsValidPeriodReport(processor.periodReport)) {
113 conf.triggerCond.timeout = 0;
114 } else {
115 conf.triggerCond.timeout = processor.periodReport;
116 }
117 if (!IsValidBatchReport(processor.batchReport)) {
118 conf.triggerCond.row = 0;
119 } else {
120 conf.triggerCond.row = processor.batchReport;
121 }
122 conf.userIdNames = genArrString2Set(processor.userIds);
123 conf.userPropertyNames = genArrString2Set(processor.userProperties);
124 std::vector<EventConfig> eventConfigs;
125 CAppEventReportConfig* configPtr = processor.eventConfigs.head;
126 for (int i = 0; i < processor.eventConfigs.size; i++) {
127 EventConfig reportConf;
128 int res = ConvertConfigReportProp(configPtr[i], reportConf);
129 if (res != 0) {
130 return res;
131 }
132 eventConfigs.push_back(reportConf);
133 }
134 conf.eventConfigs = eventConfigs;
135 return SUCCESS_CODE;
136 }
137
AddParams2EventPack(const CArrParameters & params,std::shared_ptr<AppEventPack> appEventPack_)138 void AddParams2EventPack(const CArrParameters& params, std::shared_ptr<AppEventPack> appEventPack_)
139 {
140 for (int i = 0; i < params.size; i++) {
141 auto head = params.head + i;
142 switch (head->valueType) {
143 case INT32_VALUE: // int32_t
144 appEventPack_->AddParam(std::string(head->key), *(static_cast<int32_t*>(head->value)));
145 break;
146 case INT64_VALUE: // int64_t
147 appEventPack_->AddParam(std::string(head->key), *(static_cast<int64_t*>(head->value)));
148 break;
149 case DOUBLE_VALUE: // double
150 appEventPack_->AddParam(std::string(head->key), *(static_cast<double*>(head->value)));
151 break;
152 case STRING_VALUE: // std::string
153 appEventPack_->AddParam(std::string(head->key), std::string(static_cast<char*>(head->value)));
154 break;
155 case BOOL_VALUE: // bool
156 appEventPack_->AddParam(std::string(head->key), *(static_cast<bool*>(head->value)));
157 break;
158 case INT32_ARRAY_VALUE: { // int32_array
159 int32_t* intArr = static_cast<int32_t*>(head->value);
160 std::vector<int32_t> intVec(intArr, intArr + head->size);
161 appEventPack_->AddParam(std::string(head->key), intVec);
162 break;
163 }
164 case INT64_ARRAY_VALUE: { // int64_array
165 int64_t* intArr = static_cast<int64_t*>(head->value);
166 std::vector<int64_t> intVec(intArr, intArr + head->size);
167 appEventPack_->AddParam(std::string(head->key), intVec);
168 break;
169 }
170 case DOUBLE_ARRAY_VALUE: { // double_array
171 double* doubleArr = static_cast<double*>(head->value);
172 std::vector<double> doubleVec(doubleArr, doubleArr + head->size);
173 appEventPack_->AddParam(std::string(head->key), doubleVec);
174 break;
175 }
176 case STRING_ARRAY_VALUE: { // string_array
177 char** strPtr = static_cast<char**>(head->value);
178 std::vector<std::string> strVec;
179 CharPtrToVector(strPtr, head->size, strVec);
180 appEventPack_->AddParam(std::string(head->key), strVec);
181 break;
182 }
183 case BOOL_ARRAY_VALUE: { // bool_array
184 bool* boolArr = static_cast<bool*>(head->value);
185 std::vector<bool> boolVec(boolArr, boolArr + head->size);
186 appEventPack_->AddParam(std::string(head->key), boolVec);
187 break;
188 }
189 default:
190 break;
191 }
192 }
193 }
194 }
195
196 extern "C" {
FfiOHOSHiAppEventConfigure(CConfigOption config)197 int FfiOHOSHiAppEventConfigure(CConfigOption config)
198 {
199 int code = HiAppEventImpl::Configure(config.disable, config.maxStorage);
200 if (code != SUCCESS_CODE) {
201 LOGE("FfiOHOSHiAppEventConfigure failed");
202 return code;
203 }
204 return SUCCESS_CODE;
205 }
206
FfiOHOSHiAppEventWrite(CAppEventInfo info)207 int FfiOHOSHiAppEventWrite(CAppEventInfo info)
208 {
209 auto appEventPack_ = std::make_shared<AppEventPack>(info.domain, info.name, info.event);
210 AddParams2EventPack(info.cArrParamters, appEventPack_);
211 int code = HiAppEventImpl::Write(appEventPack_);
212 if (code != SUCCESS_CODE) {
213 LOGE("HiAppEvent::FfiOHOSHiAppEventWrite failed");
214 return GetErrorCode(code);
215 }
216 return code;
217 }
218
FfiOHOSHiAppEventAddProcessor(CProcessor processor)219 RetDataBool FfiOHOSHiAppEventAddProcessor(CProcessor processor)
220 {
221 RetDataBool ret = { .code = ErrorCode::ERROR_UNKNOWN, .data = false };
222 ReportConfig conf;
223 int res = ConvertReportConfig(processor, conf);
224 if (res == ERR_CODE_PARAM_FORMAT) {
225 LOGE("failed to add processor, params format error");
226 ret.code = ERR_PARAM;
227 ret.data = false;
228 return ret;
229 }
230 if (HiAppEventImpl::Load(conf.name) != 0) {
231 LOGE("failed to add processor=%{public}s, name no found", conf.name.c_str());
232 return {ERR_CODE_PARAM_FORMAT, true};
233 }
234 int64_t processorId = HiAppEventImpl::AddProcessor(conf);
235 if (processorId <= 0) {
236 LOGE("HiAppEvent::FfiOHOSHiAppEventAddProcessor failed");
237 }
238 ret.code = processorId;
239 ret.data = true;
240 return ret;
241 }
242
FfiOHOSHiAppEventRemoveProcessor(int64_t id)243 int FfiOHOSHiAppEventRemoveProcessor(int64_t id)
244 {
245 int res = HiAppEventImpl::RemoveProcessor(id);
246 return res;
247 }
248
FfiOHOSHiAppEventSetUserId(const char * name,const char * value)249 int FfiOHOSHiAppEventSetUserId(const char* name, const char* value)
250 {
251 if (!IsValidUserIdName(std::string(name))) {
252 return ERR_PARAM;
253 }
254 int res = HiAppEventImpl::SetUserId(std::string(name), std::string(value));
255 if (res != 0) {
256 return ERR_PARAM;
257 }
258 return SUCCESS_CODE;
259 }
260
FfiOHOSHiAppEventGetUserId(const char * name)261 RetDataCString FfiOHOSHiAppEventGetUserId(const char* name)
262 {
263 RetDataCString ret = { .code = ERR_PARAM, .data = nullptr };
264 if (!IsValidUserIdName(std::string(name))) {
265 ret.code = ERR_PARAM;
266 ret.data = nullptr;
267 return ret;
268 }
269 auto [status, userId] = HiAppEventImpl::GetUserId(std::string(name));
270 if (status != 0) {
271 LOGE("HiAppEvent::FfiOHOSHiAppEventGetUserId error");
272 ret.code = status;
273 ret.data = nullptr;
274 return ret;
275 }
276 ret.code = status;
277 ret.data = MallocCString(userId);
278 return ret;
279 }
280
FfiOHOSHiAppEventSetUserProperty(const char * name,const char * value)281 int FfiOHOSHiAppEventSetUserProperty(const char* name, const char* value)
282 {
283 if (!IsValidUserPropName(name)) {
284 return ERR_PARAM;
285 }
286 if (!IsValidUserPropValue(value)) {
287 return ERR_PARAM;
288 }
289 int res = HiAppEventImpl::SetUserProperty(std::string(name), std::string(value));
290 if (res != 0) {
291 return ERR_PARAM;
292 }
293 return res;
294 }
295
FfiOHOSHiAppEventgetUserProperty(const char * name)296 RetDataCString FfiOHOSHiAppEventgetUserProperty(const char* name)
297 {
298 RetDataCString ret = { .code = ERR_PARAM, .data = nullptr };
299 if (!IsValidUserPropName(std::string(name))) {
300 ret.code = ERR_PARAM;
301 ret.data = nullptr;
302 return ret;
303 }
304 auto [status, propertyId] = HiAppEventImpl::GetUserProperty(std::string(name));
305 if (status != 0) {
306 LOGE("HiAppEvent::FfiOHOSHiAppEventgetUserProperty error");
307 ret.code = status;
308 ret.data = nullptr;
309 return ret;
310 }
311 ret.code = status;
312 ret.data = MallocCString(propertyId);
313 return ret;
314 }
315
FfiOHOSHiAppEventclearData()316 void FfiOHOSHiAppEventclearData()
317 {
318 HiAppEventImpl::ClearData();
319 }
320
FfiOHOSHiAppEventConstructor(char * cWatcherName)321 int64_t FfiOHOSHiAppEventConstructor(char* cWatcherName)
322 {
323 auto nativeHolder = OHOS::FFI::FFIData::Create<AppEventPackageHolderImpl>(cWatcherName, -1L);
324 if (nativeHolder == nullptr) {
325 return -1;
326 }
327 return nativeHolder->GetID();
328 }
329
FfiOHOSHiAppEventSetSize(int64_t id,int size)330 int FfiOHOSHiAppEventSetSize(int64_t id, int size)
331 {
332 auto nativeAppEventPackageHolder = OHOS::FFI::FFIData::GetData<AppEventPackageHolderImpl>(id);
333 if (nativeAppEventPackageHolder == nullptr) {
334 return -1;
335 }
336 int ret = SUCCESS_CODE;
337 if (size >= 0) {
338 nativeAppEventPackageHolder->SetSize(size);
339 } else {
340 ret = ERR_INVALID_SIZE;
341 }
342 return ret;
343 }
344
FfiOHOSHiAppEventTakeNext(int64_t id)345 ReTakeNext FfiOHOSHiAppEventTakeNext(int64_t id)
346 {
347 auto nativeAppEventPackageHolder = OHOS::FFI::FFIData::GetData<AppEventPackageHolderImpl>(id);
348 if (nativeAppEventPackageHolder == nullptr) {
349 return ReTakeNext{.status = -1, .event = RetAppEventPackage{0}};
350 }
351 auto [state, package] = nativeAppEventPackageHolder->TakeNext();
352 ReTakeNext ret;
353 ret.status = state;
354 ret.event = package;
355 return ret;
356 }
357
FfiOHOSHiAppEventAddWatcher(CWatcher watcher)358 RetDataI64 FfiOHOSHiAppEventAddWatcher(CWatcher watcher)
359 {
360 RetDataI64 ret = { .code = ERR_PARAM, .data = 0 };
361 // check isValid
362 std::string name = std::string(watcher.name);
363 if (!IsValidWatcherName(name)) {
364 ret.code = ERR_INVALID_WATCHER_NAME;
365 return ret;
366 }
367 TriggerCondition cond;
368 ret.code = CheckCondition(cond, watcher.triggerCondition);
369 if (ret.code != ERR_PARAM) {
370 return ret;
371 }
372 std::vector<AppEventFilter> filters;
373 std::unordered_set<std::string> names;
374 for (int i = 0; i < watcher.appEventFilters.size; i++) {
375 for (int j = 0; j < watcher.appEventFilters.head[i].names.size; j++) {
376 names.insert(std::string(watcher.appEventFilters.head[i].names.head[j]));
377 }
378 std::string domain = std::string(watcher.appEventFilters.head[i].domain);
379 if (!IsValidDomain(domain)) {
380 ret.code = ERR_INVALID_FILTER_DOMAIN;
381 return ret;
382 }
383 uint32_t types = 0;
384 for (int k = 0; k < watcher.appEventFilters.head[i].eventTypes.size; k++) {
385 types |= (BIT_MASK << watcher.appEventFilters.head[i].eventTypes.head[k]);
386 }
387 types = types > 0 ? types : BIT_ALL_TYPES;
388 filters.emplace_back(AppEventFilter(domain, names, types));
389 }
390
391 auto [status, holderId] = HiAppEventImpl::addWatcher(name, filters, cond,
392 watcher.callbackOnTriggerRef, watcher.callbackOnReceiveRef);
393 if (status != 0) {
394 ret.code = status;
395 return ret;
396 }
397 if (holderId == -1) {
398 ret.data = -1;
399 return ret;
400 }
401 ret.code = status;
402 ret.data = holderId;
403 return ret;
404 }
405
FfiOHOSHiAppEventRemoveWatcher(CWatcher watcher)406 int FfiOHOSHiAppEventRemoveWatcher(CWatcher watcher)
407 {
408 std::string name = std::string(watcher.name);
409 if (!IsValidWatcherName(name)) {
410 return ERR_INVALID_WATCHER_NAME;
411 }
412 HiAppEventImpl::removeWatcher(name);
413 return SUCCESS_CODE;
414 }
415
FfiOHOSHiAppEventSetEventParam(CArrParameters eventParams,char * domain,char * name)416 int32_t FfiOHOSHiAppEventSetEventParam(CArrParameters eventParams, char* domain, char* name)
417 {
418 int32_t ret = 0;
419 std::string domainStr = std::string(domain);
420 std::string nameStr = std::string(name);
421 auto appEventPack_ = std::make_shared<AppEventPack>(domainStr, nameStr);
422 AddParams2EventPack(eventParams, appEventPack_);
423 ret = VerifyCustomEventParams(appEventPack_);
424 if (ret != 0) {
425 return GetErrorCode(ret);
426 }
427 int32_t err = SetEventParam(appEventPack_);
428 if (err != 0) {
429 return GetErrorCode(err);
430 } else {
431 return 0;
432 }
433 }
434 }