• 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 <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 }