1 /*
2 * Copyright (c) 2025 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 <map>
17 #include <cinttypes>
18
19 #include "hiappevent_ani_helper.h"
20
21 #include "app_event_observer_mgr.h"
22 #include "app_event_stat.h"
23 #include "ani_app_event_holder.h"
24 #include "ani_app_event_watcher.h"
25 #include "hiappevent_verify.h"
26 #include "hiappevent_config.h"
27 #include "hiappevent_userinfo.h"
28 #include "hilog/log.h"
29 #include "hilog/log_cpp.h"
30
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD002D07
33
34 #undef LOG_TAG
35 #define LOG_TAG "HIAPPEVENT_ANI_HELPER"
36
37 using namespace OHOS::HiviewDFX;
38 using namespace HiAppEvent;
39
40 namespace {
41 constexpr int32_t INVALID_OUT = -1;
42
43 typedef struct ConfigProp {
44 std::string key;
45 int32_t(*func)(ani_env*, ani_object, const std::string&, ReportConfig&);
46 } ConfigProp;
47
48 const std::vector<std::string> ConfigOptionKeys = {"disable", "maxStorage"};
49 const std::string COND_PROPS[] = {"row", "size", "timeOut"};
50 }
51
AddParamToCustomConfigs(ani_env * env,ani_ref recordRef,HiAppEvent::ReportConfig & conf)52 static bool AddParamToCustomConfigs(ani_env *env, ani_ref recordRef, HiAppEvent::ReportConfig &conf)
53 {
54 if (!HiAppEventAniUtil::IsRefUndefined(env, recordRef)) {
55 std::map<std::string, ani_ref> CustomConfigsRecord;
56 HiAppEventAniUtil::ParseRecord(env, static_cast<ani_object>(recordRef), CustomConfigsRecord);
57 if (!IsValidCustomConfigsNum(CustomConfigsRecord.size())) {
58 HILOG_WARN(LOG_CORE, "invalid keys size=%{public}zu", CustomConfigsRecord.size());
59 return false;
60 }
61 for (const auto &CustomConfigsTemp : CustomConfigsRecord) {
62 conf.customConfigs[CustomConfigsTemp.first] =
63 HiAppEventAniUtil::ParseStringValue(env, CustomConfigsTemp.second);
64 }
65 }
66 return true;
67 }
68
GetConfigIdValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)69 static int32_t GetConfigIdValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
70 {
71 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
72 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
73 out.configId = static_cast<int32_t>(HiAppEventAniUtil::ParseNumberValue(env, ref));
74 }
75 return ERR_CODE_SUCC;
76 }
77
GetRouteInfoRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)78 static int32_t GetRouteInfoRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
79 {
80 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
81 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
82 out.routeInfo = HiAppEventAniUtil::ParseStringValue(env, ref);
83 if (!IsValidRouteInfo(out.routeInfo)) {
84 return ERR_CODE_PARAM_INVALID;
85 }
86 }
87 return ERR_CODE_SUCC;
88 }
89
GetAppIdRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)90 static int32_t GetAppIdRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
91 {
92 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
93 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
94 out.appId = HiAppEventAniUtil::ParseStringValue(env, ref);
95 if (!IsValidAppId(out.appId)) {
96 return ERR_CODE_PARAM_INVALID;
97 }
98 }
99 return ERR_CODE_SUCC;
100 }
101
GetNameRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)102 static int32_t GetNameRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
103 {
104 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
105 if (ref == nullptr) {
106 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Invalid processor name.");
107 return ERR_CODE_PARAM_FORMAT;
108 }
109 std::string name = HiAppEventAniUtil::ParseStringValue(env, ref);
110 if (!IsValidProcessorName(name)) {
111 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Invalid processor name.");
112 return ERR_CODE_PARAM_FORMAT;
113 }
114 out.name = name;
115 return ERR_CODE_SUCC;
116 }
117
GetPeriodReportInt(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)118 static int32_t GetPeriodReportInt(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
119 {
120 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
121 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
122 out.triggerCond.timeout = static_cast<int32_t>(HiAppEventAniUtil::ParseNumberValue(env, ref));
123 if (!IsValidPeriodReport(out.triggerCond.timeout)) {
124 return ERR_CODE_PARAM_INVALID;
125 }
126 }
127 return ERR_CODE_SUCC;
128 }
129
GetBatchReportInt(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)130 static int32_t GetBatchReportInt(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
131 {
132 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
133 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
134 out.triggerCond.row = static_cast<int32_t>(HiAppEventAniUtil::ParseNumberValue(env, ref));
135 if (!IsValidBatchReport(out.triggerCond.row)) {
136 return ERR_CODE_PARAM_INVALID;
137 }
138 }
139 return ERR_CODE_SUCC;
140 }
141
GetUserIdsRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)142 static int32_t GetUserIdsRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
143 {
144 std::unordered_set<std::string> userIdNames;
145 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
146 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
147 HiAppEventAniUtil::GetStringsToSet(env, ref, userIdNames);
148 for (auto userId : userIdNames) {
149 if (!IsValidUserIdName(userId)) {
150 return ERR_CODE_PARAM_INVALID;
151 }
152 }
153 }
154 out.userIdNames = userIdNames;
155 return ERR_CODE_SUCC;
156 }
157
GetUserPropertyRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)158 static int32_t GetUserPropertyRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
159 {
160 std::unordered_set<std::string> userPropertyNames;
161 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
162 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
163 HiAppEventAniUtil::GetStringsToSet(env, ref, userPropertyNames);
164 for (auto userProperty : userPropertyNames) {
165 if (!IsValidUserPropName(userProperty)) {
166 return ERR_CODE_PARAM_INVALID;
167 }
168 }
169 }
170 out.userPropertyNames = userPropertyNames;
171 return ERR_CODE_SUCC;
172 }
173
ParseEventConfigsValue(ani_env * env,ani_ref Ref,std::vector<EventConfig> & arr)174 static int32_t ParseEventConfigsValue(ani_env *env, ani_ref Ref, std::vector<EventConfig> &arr)
175 {
176 ani_size length = 0;
177 if (env->Array_GetLength(static_cast<ani_array_ref>(Ref), &length) != ANI_OK) {
178 HILOG_ERROR(LOG_CORE, "failed to get length.");
179 return ERR_CODE_PARAM_INVALID;
180 }
181 EventConfig config;
182 for (ani_size i = 0; i < length; i++) {
183 ani_ref value {};
184 if (env->Array_Get_Ref(static_cast<ani_array_ref>(Ref), i, &value) != ANI_OK) {
185 HILOG_ERROR(LOG_CORE, "failed to get element");
186 return ERR_CODE_PARAM_INVALID;
187 }
188 ani_ref domainRef =
189 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), EVENT_CONFIG_DOMAIN.c_str());
190 config.domain = HiAppEventAniUtil::ParseStringValue(env, domainRef);
191 ani_ref nameRef =
192 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), EVENT_CONFIG_NAME.c_str());
193 config.name = HiAppEventAniUtil::ParseStringValue(env, nameRef);
194 ani_ref isRealTimeBol =
195 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), EVENT_CONFIG_REALTIME.c_str());
196 if (!HiAppEventAniUtil::IsRefUndefined(env, isRealTimeBol)) {
197 config.isRealTime = HiAppEventAniUtil::ParseBoolValue(env, isRealTimeBol);
198 arr.emplace_back(config);
199 }
200 }
201 return ERR_CODE_SUCC;
202 }
203
GetEventConfigsRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)204 static int32_t GetEventConfigsRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
205 {
206 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
207 std::vector<EventConfig> arr;
208 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
209 ParseEventConfigsValue(env, ref, arr);
210 out.eventConfigs = arr;
211 }
212 return ERR_CODE_SUCC;
213 }
214
GetCustomConfigRefValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)215 static int32_t GetCustomConfigRefValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
216 {
217 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
218 if (HiAppEventAniUtil::IsRefUndefined(env, ref)) {
219 return ERR_CODE_SUCC;
220 }
221 if (!AddParamToCustomConfigs(env, ref, out)) {
222 HILOG_WARN(LOG_CORE, "AddParamToCustomConfigs failed");
223 return ERR_CODE_PARAM_INVALID;
224 }
225 return ERR_CODE_SUCC;
226 }
227
GetDebugModeValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)228 static int32_t GetDebugModeValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
229 {
230 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
231 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
232 out.debugMode = HiAppEventAniUtil::ParseBoolValue(env, ref);
233 }
234 return ERR_CODE_SUCC;
235 }
236
GetOnStartUpValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)237 static int32_t GetOnStartUpValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
238 {
239 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
240 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
241 out.triggerCond.onStartup = HiAppEventAniUtil::ParseBoolValue(env, ref);
242 }
243 return ERR_CODE_SUCC;
244 }
245
GetOnBackgroundValue(ani_env * env,ani_object processor,const std::string & key,ReportConfig & out)246 static int32_t GetOnBackgroundValue(ani_env *env, ani_object processor, const std::string &key, ReportConfig &out)
247 {
248 ani_ref ref = HiAppEventAniUtil::GetProperty(env, processor, key);
249 if (!HiAppEventAniUtil::IsRefUndefined(env, ref)) {
250 out.triggerCond.onBackground = HiAppEventAniUtil::ParseBoolValue(env, ref);
251 }
252 return ERR_CODE_SUCC;
253 }
254
255 static const ConfigProp CONFIG_PROPS[] = {
256 {
257 .key = PROCESSOR_NAME,
258 .func = GetNameRefValue
259 },
260 {
261 .key = ROUTE_INFO,
262 .func = GetRouteInfoRefValue
263 },
264 {
265 .key = APP_ID,
266 .func = GetAppIdRefValue
267 },
268 {
269 .key = USER_IDS,
270 .func = GetUserIdsRefValue
271 },
272 {
273 .key = USER_PROPERTIES,
274 .func = GetUserPropertyRefValue
275 },
276 {
277 .key = DEBUG_MODE,
278 .func = GetDebugModeValue
279 },
280 {
281 .key = START_REPORT,
282 .func = GetOnStartUpValue
283 },
284 {
285 .key = BACKGROUND_REPORT,
286 .func = GetOnBackgroundValue
287 },
288 {
289 .key = PERIOD_REPORT,
290 .func = GetPeriodReportInt
291 },
292 {
293 .key = BATCH_REPORT,
294 .func = GetBatchReportInt
295 },
296 {
297 .key = EVENT_CONFIGS,
298 .func = GetEventConfigsRefValue
299 },
300 {
301 .key = CONFIG_ID,
302 .func = GetConfigIdValue
303 },
304 {
305 .key = CUSTOM_CONFIG,
306 .func = GetCustomConfigRefValue
307 }
308 };
309
TransConfig(ani_env * env,ani_object processor,ReportConfig & out)310 static int32_t TransConfig(ani_env *env, ani_object processor, ReportConfig& out)
311 {
312 for (auto prop : CONFIG_PROPS) {
313 int32_t ret = (prop.func)(env, processor, prop.key, out);
314 if (ret == ERR_CODE_PARAM_FORMAT) {
315 HILOG_ERROR(LOG_CORE, "failed to add processor, params format error");
316 return ERR_CODE_PARAM_FORMAT;
317 } else if (ret == ERR_CODE_PARAM_INVALID) {
318 HILOG_WARN(LOG_CORE, "Parameter error. The %{public}s parameter is invalid.", prop.key.c_str());
319 }
320 }
321 return ERR_CODE_SUCC;
322 }
323
AddProcessor(ani_env * env,ani_object processor,int64_t & out)324 bool HiAppEventAniHelper::AddProcessor(ani_env *env, ani_object processor, int64_t &out)
325 {
326 ReportConfig conf;
327 int32_t ret = TransConfig(env, processor, conf);
328 if (ret != 0) {
329 HILOG_ERROR(LOG_CORE, "TransConfig failed.");
330 out = INVALID_OUT;
331 return false;
332 }
333 std::string name = conf.name;
334 if (name.empty()) {
335 HILOG_ERROR(LOG_CORE, "processor name can not be empty.");
336 out = INVALID_OUT;
337 return false;
338 }
339 if (AppEventObserverMgr::GetInstance().Load(name) != 0) {
340 HILOG_WARN(LOG_CORE, "failed to add processor=%{public}s, name no found", name.c_str());
341 out = INVALID_OUT;
342 return false;
343 }
344 int64_t processorId = AppEventObserverMgr::GetInstance().AddProcessor(name, conf);
345 if (processorId <= 0) {
346 HILOG_WARN(LOG_CORE, "failed to add processor=%{public}s, register processor error", name.c_str());
347 out = INVALID_OUT;
348 return false;
349 }
350 out = processorId;
351 return true;
352 }
353
GetPropertyDomain(ani_object info,ani_env * env,std::string & domain)354 bool HiAppEventAniHelper::GetPropertyDomain(ani_object info, ani_env *env, std::string &domain)
355 {
356 ani_ref domainResultTemp {};
357 if (env->Object_GetPropertyByName_Ref(info, "domain", &domainResultTemp) != ANI_OK) {
358 HILOG_ERROR(LOG_CORE, "get property domain failed");
359 return false;
360 }
361
362 domain = HiAppEventAniUtil::ParseStringValue(env, domainResultTemp);
363 return true;
364 }
365
GetPropertyName(ani_object info,ani_env * env,std::string & name)366 bool HiAppEventAniHelper::GetPropertyName(ani_object info, ani_env *env, std::string &name)
367 {
368 ani_ref nameResultTemp {};
369 if (env->Object_GetPropertyByName_Ref(info, "name", &nameResultTemp) != ANI_OK) {
370 HILOG_ERROR(LOG_CORE, "get property name failed");
371 return false;
372 }
373
374 name = HiAppEventAniUtil::ParseStringValue(env, nameResultTemp);
375 return true;
376 }
377
GeteventTypeValue(ani_object info,ani_env * env,int32_t & enumValue)378 bool HiAppEventAniHelper::GeteventTypeValue(ani_object info, ani_env *env, int32_t &enumValue)
379 {
380 ani_ref eventTypeRef {};
381 if (env->Object_GetPropertyByName_Ref(info, "eventType", &eventTypeRef) != ANI_OK) {
382 HILOG_ERROR(LOG_CORE, "get property eventType failed");
383 return false;
384 }
385
386 ani_enum_item eventTypeItem = static_cast<ani_enum_item>(eventTypeRef);
387 if (HiAppEventAniHelper::ParseEnumGetValueInt32(env, eventTypeItem, enumValue) != ANI_OK) {
388 HILOG_ERROR(LOG_CORE, "fail to get 'enumValue'");
389 return false;
390 }
391 return true;
392 }
393
ParseEnumGetValueInt32(ani_env * env,ani_enum_item enumItem,int32_t & value)394 ani_status HiAppEventAniHelper::ParseEnumGetValueInt32(ani_env *env, ani_enum_item enumItem, int32_t &value)
395 {
396 ani_int aniInt = 0;
397 if (env->EnumItem_GetValue_Int(enumItem, &aniInt) != ANI_OK) {
398 HILOG_ERROR(LOG_CORE, "enumItem get int value failed");
399 return ANI_ERROR;
400 }
401 value = static_cast<int32_t>(aniInt);
402 return ANI_OK;
403 }
404
AddArrayParamToAppEventPack(ani_env * env,const std::string & key,ani_ref arrayRef,std::shared_ptr<AppEventPack> & appEventPack)405 bool HiAppEventAniHelper::AddArrayParamToAppEventPack(ani_env *env, const std::string &key, ani_ref arrayRef,
406 std::shared_ptr<AppEventPack> &appEventPack)
407 {
408 AniArgsType arrayType = HiAppEventAniUtil::GetArrayType(env, static_cast<ani_array_ref>(arrayRef));
409 switch (arrayType) {
410 case AniArgsType::ANI_INT: {
411 std::vector<int> ints = HiAppEventAniUtil::GetInts(env, arrayRef);
412 appEventPack->AddParam(key, ints);
413 break;
414 }
415 case AniArgsType::ANI_BOOLEAN: {
416 std::vector<bool> bools = HiAppEventAniUtil::GetBooleans(env, arrayRef);
417 appEventPack->AddParam(key, bools);
418 break;
419 }
420 case AniArgsType::ANI_DOUBLE: {
421 std::vector<double> doubles = HiAppEventAniUtil::GetDoubles(env, arrayRef);
422 appEventPack->AddParam(key, doubles);
423 break;
424 }
425 case AniArgsType::ANI_STRING: {
426 std::vector<std::string> strs = HiAppEventAniUtil::GetStrings(env, arrayRef);
427 appEventPack->AddParam(key, strs);
428 break;
429 }
430 case AniArgsType::ANI_NULL: {
431 appEventPack->AddParam(key);
432 break;
433 }
434 default:
435 HILOG_ERROR(LOG_CORE, "array param value type is invalid");
436 return false;
437 }
438 return true;
439 }
440
AddParamToAppEventPack(ani_env * env,const std::string & key,ani_ref element,std::shared_ptr<AppEventPack> & appEventPack)441 bool HiAppEventAniHelper::AddParamToAppEventPack(ani_env *env, const std::string &key, ani_ref element,
442 std::shared_ptr<AppEventPack> &appEventPack)
443 {
444 ani_object elementObj = static_cast<ani_object>(element);
445 AniArgsType type = HiAppEventAniUtil::GetArgType(env, elementObj);
446 if (type <= AniArgsType::ANI_UNKNOWN || type >= AniArgsType::ANI_UNDEFINED) {
447 return false;
448 }
449 switch (type) {
450 case AniArgsType::ANI_INT:
451 appEventPack->AddParam(key, HiAppEventAniUtil::ParseIntValue(env, element));
452 break;
453 case AniArgsType::ANI_BOOLEAN:
454 appEventPack->AddParam(key, HiAppEventAniUtil::ParseBoolValue(env, element));
455 break;
456 case AniArgsType::ANI_DOUBLE:
457 appEventPack->AddParam(key, HiAppEventAniUtil::ParseNumberValue(env, element));
458 break;
459 case AniArgsType::ANI_STRING:
460 appEventPack->AddParam(key, HiAppEventAniUtil::ParseStringValue(env, element));
461 break;
462 default:
463 HILOG_ERROR(LOG_CORE, "param value type is invalid");
464 return false;
465 }
466 return true;
467 }
468
ParseParamsInAppEventPack(ani_env * env,ani_ref params,std::shared_ptr<AppEventPack> & appEventPack)469 bool HiAppEventAniHelper::ParseParamsInAppEventPack(ani_env *env, ani_ref params,
470 std::shared_ptr<AppEventPack> &appEventPack)
471 {
472 if (HiAppEventAniUtil::IsRefUndefined(env, params)) {
473 HILOG_ERROR(LOG_CORE, "AppEventInfo params undefined");
474 return false;
475 }
476 std::map<std::string, ani_ref> appEventParams;
477 HiAppEventAniUtil::ParseRecord(env, static_cast<ani_object>(params), appEventParams);
478 for (const auto ¶m : appEventParams) {
479 if (param.first.length() > MAX_LENGTH_OF_PARAM_NAME) {
480 result_ = ERROR_INVALID_PARAM_NAME;
481 HILOG_INFO(LOG_CORE, "the length=%{public}zu of the param key is invalid", param.first.length());
482 continue;
483 }
484 if (!HiAppEventAniHelper::AddAppEventPackParam(env, param, appEventPack)) {
485 return false;
486 }
487 }
488 return true;
489 }
490
GetResult()491 int32_t HiAppEventAniHelper::GetResult()
492 {
493 return result_;
494 }
495
AddAppEventPackParam(ani_env * env,std::pair<std::string,ani_ref> recordTemp,std::shared_ptr<AppEventPack> & appEventPack)496 bool HiAppEventAniHelper::AddAppEventPackParam(ani_env *env,
497 std::pair<std::string, ani_ref> recordTemp, std::shared_ptr<AppEventPack> &appEventPack)
498 {
499 if (HiAppEventAniUtil::IsArray(env, static_cast<ani_object>(recordTemp.second))) {
500 if (!AddArrayParamToAppEventPack(env, recordTemp.first, recordTemp.second, appEventPack)) {
501 return false;
502 }
503 } else {
504 if (!HiAppEventAniHelper::AddParamToAppEventPack(env, recordTemp.first, recordTemp.second, appEventPack)) {
505 return false;
506 }
507 }
508 return true;
509 }
510
Configure(ani_env * env,ani_object configObj)511 bool HiAppEventAniHelper::Configure(ani_env *env, ani_object configObj)
512 {
513 for (const auto &key: ConfigOptionKeys) {
514 ani_ref valueRef = HiAppEventAniUtil::GetProperty(env, configObj, key);
515 if (HiAppEventAniUtil::IsRefUndefined(env, valueRef)) {
516 continue;
517 }
518 if (!HiAppEventConfig::GetInstance().SetConfigurationItem(
519 key, HiAppEventAniUtil::ConvertToString(env, valueRef))) {
520 std::string errMsg = "Invalid max storage quota value.";
521 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_MAX_STORAGE, errMsg);
522 return false;
523 }
524 }
525 return true;
526 }
527
SetUserId(ani_env * env,ani_string name,ani_string value)528 bool HiAppEventAniHelper::SetUserId(ani_env *env, ani_string name, ani_string value)
529 {
530 std::string strName = HiAppEventAniUtil::ParseStringValue(env, name);
531 if (!IsValidUserIdName(strName)) {
532 HILOG_WARN(LOG_CORE, "Parameter error. The name parameter is invalid.");
533 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The name parameter is invalid.");
534 return false;
535 }
536 std::string strUserId = HiAppEventAniUtil::ParseStringValue(env, value);
537 if (strUserId.empty()) {
538 if (HiAppEvent::UserInfo::GetInstance().RemoveUserId(strName) != 0) {
539 HILOG_ERROR(LOG_CORE, "failed to remove userId");
540 return false;
541 }
542 return true;
543 }
544 if (!IsValidUserIdValue(strUserId)) {
545 HILOG_WARN(LOG_CORE, "Parameter error. The value parameter is invalid.");
546 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The value parameter is invalid.");
547 return false;
548 }
549 if (HiAppEvent::UserInfo::GetInstance().SetUserId(strName, strUserId) != 0) {
550 HILOG_ERROR(LOG_CORE, "failed to set userId");
551 return false;
552 }
553 return true;
554 }
555
GetUserId(ani_env * env,ani_string name,ani_string & userId)556 bool HiAppEventAniHelper::GetUserId(ani_env *env, ani_string name, ani_string &userId)
557 {
558 std::string strName = HiAppEventAniUtil::ParseStringValue(env, name);
559 if (!IsValidUserIdName(strName)) {
560 HILOG_WARN(LOG_CORE, "Parameter error. The name parameter is invalid.");
561 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The name parameter is invalid.");
562 return false;
563 }
564 std::string strUserId = "";
565 if (HiAppEvent::UserInfo::GetInstance().GetUserId(strName, strUserId) != 0) {
566 HILOG_ERROR(LOG_CORE, "failed to get userId");
567 return false;
568 }
569 env->String_NewUTF8(strUserId.c_str(), strUserId.size(), &userId);
570 return true;
571 }
572
SetUserProperty(ani_env * env,ani_string name,ani_string value)573 bool HiAppEventAniHelper::SetUserProperty(ani_env *env, ani_string name, ani_string value)
574 {
575 std::string strName = HiAppEventAniUtil::ParseStringValue(env, name);
576 if (!IsValidUserPropName(strName)) {
577 HILOG_WARN(LOG_CORE, "Parameter error. The name parameter is invalid.");
578 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The name parameter is invalid.");
579 return false;
580 }
581 std::string strUserProperty = HiAppEventAniUtil::ParseStringValue(env, value);
582 if (strUserProperty.empty()) {
583 if (HiAppEvent::UserInfo::GetInstance().RemoveUserProperty(strName) != 0) {
584 HILOG_ERROR(LOG_CORE, "failed to remove user property");
585 return false;
586 }
587 return true;
588 }
589 if (!IsValidUserPropValue(strUserProperty)) {
590 HILOG_WARN(LOG_CORE, "Parameter error. The value parameter is invalid.");
591 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The value parameter is invalid.");
592 return false;
593 }
594 if (HiAppEvent::UserInfo::GetInstance().SetUserProperty(strName, strUserProperty) != 0) {
595 HILOG_ERROR(LOG_CORE, "failed to set user property");
596 return false;
597 }
598 return true;
599 }
600
GetUserProperty(ani_env * env,ani_string name,ani_string & userProperty)601 bool HiAppEventAniHelper::GetUserProperty(ani_env *env, ani_string name, ani_string &userProperty)
602 {
603 std::string strName = HiAppEventAniUtil::ParseStringValue(env, name);
604 if (!IsValidUserPropName(strName)) {
605 HILOG_WARN(LOG_CORE, "Parameter error. The name parameter is invalid.");
606 HiAppEventAniUtil::ThrowAniError(env, ERR_PARAM, "Parameter error. The name parameter is invalid.");
607 return false;
608 }
609 std::string strUserProperty = "";
610 if (HiAppEvent::UserInfo::GetInstance().GetUserProperty(strName, strUserProperty) != 0) {
611 HILOG_ERROR(LOG_CORE, "failed to get user property");
612 return false;
613 }
614 env->String_NewUTF8(strUserProperty.c_str(), strUserProperty.size(), &userProperty);
615 return true;
616 }
617
RemoveProcessor(ani_env * env,ani_double id)618 bool HiAppEventAniHelper::RemoveProcessor(ani_env *env, ani_double id)
619 {
620 int64_t processorId = static_cast<int64_t>(id);
621 if (processorId <= 0) {
622 HILOG_ERROR(LOG_CORE, "failed to remove processor id=%{public}" PRId64, processorId);
623 return true;
624 }
625 if (AppEventObserverMgr::GetInstance().RemoveObserver(processorId) != 0) {
626 HILOG_WARN(LOG_CORE, "failed to remove processor id=%{public}" PRId64, processorId);
627 return false;
628 }
629 return true;
630 }
631
IsValidName(ani_env * env,ani_ref nameRef,int32_t & errCode)632 static bool IsValidName(ani_env *env, ani_ref nameRef, int32_t& errCode)
633 {
634 if (!IsValidWatcherName(HiAppEventAniUtil::ParseStringValue(env, nameRef))) {
635 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_WATCHER_NAME, "Invalid watcher name.");
636 errCode = ERR_INVALID_WATCHER_NAME;
637 return false;
638 }
639 return true;
640 }
641
IsValidFilter(ani_env * env,ani_ref filterValue,int32_t & errCode)642 static bool IsValidFilter(ani_env *env, ani_ref filterValue, int32_t& errCode)
643 {
644 ani_ref domainRef =
645 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(filterValue), FILTER_DOMAIN.c_str());
646 if (!IsValidDomain(HiAppEventAniUtil::ParseStringValue(env, domainRef))) {
647 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_FILTER_DOMAIN, "Invalid filtering event domain.");
648 errCode = ERR_INVALID_FILTER_DOMAIN;
649 return false;
650 }
651 return true;
652 }
653
IsValidFilters(ani_env * env,ani_ref filtersRef,int32_t & errCode)654 static bool IsValidFilters(ani_env *env, ani_ref filtersRef, int32_t& errCode)
655 {
656 if (HiAppEventAniUtil::IsRefUndefined(env, filtersRef)) {
657 return true;
658 }
659 ani_size length = 0;
660 if (env->Array_GetLength(static_cast<ani_array_ref>(filtersRef), &length) != ANI_OK) {
661 HILOG_ERROR(LOG_CORE, "get array length failed");
662 return false;
663 }
664 for (ani_size i = 0; i < length; i++) {
665 ani_ref filterValue {};
666 if (env->Array_Get_Ref(static_cast<ani_array_ref>(filtersRef), i, &filterValue) != ANI_OK) {
667 HILOG_ERROR(LOG_CORE, "get array element failed");
668 return false;
669 }
670 if (!IsValidFilter(env, filterValue, errCode)) {
671 return false;
672 }
673 }
674 return true;
675 }
676
IsValidWatcher(ani_env * env,ani_object watcher,int32_t & errCode)677 static bool IsValidWatcher(ani_env *env, ani_object watcher, int32_t& errCode)
678 {
679 return IsValidName(env, HiAppEventAniUtil::GetProperty(env, watcher, WATCHER_NAME.c_str()), errCode)
680 && IsValidFilters(env, HiAppEventAniUtil::GetProperty(env, watcher, APPEVENT_FILTERS.c_str()), errCode);
681 }
682
GetFilters(ani_env * env,ani_object watcher,std::vector<AppEventFilter> & filters)683 static void GetFilters(ani_env *env, ani_object watcher, std::vector<AppEventFilter>& filters)
684 {
685 ani_ref filtersRef = HiAppEventAniUtil::GetProperty(env, watcher, APPEVENT_FILTERS.c_str());
686 if (HiAppEventAniUtil::IsRefUndefined(env, filtersRef)) {
687 return;
688 }
689 ani_size len = 0;
690 if (env->Array_GetLength(static_cast<ani_array_ref>(filtersRef), &len) != ANI_OK) {
691 HILOG_ERROR(LOG_CORE, "get array length failed");
692 return;
693 }
694 for (ani_size i = 0; i < len; i++) {
695 ani_ref value {};
696 if (env->Array_Get_Ref(static_cast<ani_array_ref>(filtersRef), i, &value) != ANI_OK) {
697 HILOG_ERROR(LOG_CORE, "failed to get length");
698 return;
699 }
700 ani_ref domainValue =
701 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), FILTER_DOMAIN.c_str());
702 std::string domain = HiAppEventAniUtil::ParseStringValue(env, domainValue);
703 ani_ref namesValue =
704 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), FILTER_NAMES.c_str());
705 std::unordered_set<std::string> names;
706 if (!HiAppEventAniUtil::IsRefUndefined(env, namesValue)) {
707 HiAppEventAniUtil::GetStringsToSet(env, namesValue, names);
708 }
709 ani_ref typesValue =
710 HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(value), FILTER_TYPES.c_str());
711 if (HiAppEventAniUtil::IsRefUndefined(env, typesValue)) {
712 filters.emplace_back(AppEventFilter(domain, names, BIT_ALL_TYPES));
713 continue;
714 }
715 std::vector<int> types;
716 HiAppEventAniUtil::GetIntValueToVector(env, typesValue, types);
717 unsigned int filterType = 0;
718 for (auto type : types) {
719 filterType |= (BIT_MASK << type);
720 }
721 filterType = filterType > 0 ? filterType : BIT_ALL_TYPES;
722 filters.emplace_back(AppEventFilter(domain, names, filterType));
723 }
724 }
725
GetConditionValue(ani_env * env,ani_ref cond,const std::string & name)726 static int GetConditionValue(ani_env *env, ani_ref cond, const std::string& name)
727 {
728 auto value = HiAppEventAniUtil::GetProperty(env, static_cast<ani_object>(cond), name);
729 if (!HiAppEventAniUtil::IsRefUndefined(env, value)) {
730 return HiAppEventAniUtil::ParseNumberValue(env, value);
731 }
732 return 0;
733 }
734
GetCondition(ani_env * env,ani_object watcher,TriggerCondition & resCond)735 static bool GetCondition(ani_env *env, ani_object watcher, TriggerCondition& resCond)
736 {
737 ani_ref cond = HiAppEventAniUtil::GetProperty(env, watcher, TRIGGER_CONDITION.c_str());
738 if (HiAppEventAniUtil::IsRefUndefined(env, cond)) {
739 return true;
740 }
741
742 size_t index = 0;
743 int row = GetConditionValue(env, cond, COND_PROPS[index++]);
744 if (row < 0) {
745 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_COND_ROW, "Invalid row value.");
746 return false;
747 }
748 resCond.row = row;
749
750 int size = GetConditionValue(env, cond, COND_PROPS[index++]);
751 if (size < 0) {
752 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_COND_SIZE, "Invalid size value.");
753 return false;
754 }
755 resCond.size = size;
756
757 int timeout = GetConditionValue(env, cond, COND_PROPS[index++]);
758 if (timeout < 0) {
759 HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_COND_TIMEOUT, "Invalid timeout value.");
760 return false;
761 }
762 resCond.timeout = timeout * HiAppEvent::TIMEOUT_STEP;
763 return true;
764 }
765
CreateHolderObject(ani_env * env,ani_string watcherName)766 static ani_object CreateHolderObject(ani_env *env, ani_string watcherName)
767 {
768 ani_class cls {};
769 if (env->FindClass(CLASS_NAME_EVENT_PACKAGE_HOLDER, &cls) != ANI_OK) {
770 HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", CLASS_NAME_EVENT_PACKAGE_HOLDER);
771 }
772
773 ani_method ctor {};
774 if (env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor) != ANI_OK) {
775 HILOG_ERROR(LOG_CORE, "get %{public}s ctor Failed", CLASS_NAME_EVENT_PACKAGE_HOLDER);
776 }
777
778 ani_object obj {};
779 if (env->Object_New(cls, ctor, &obj, watcherName) != ANI_OK) {
780 HILOG_ERROR(LOG_CORE, "Create Object Failed: %{public}s", CLASS_NAME_EVENT_PACKAGE_HOLDER);
781 }
782 return obj;
783 }
784
AddWatcher(ani_env * env,ani_object watcher,uint64_t beginTime)785 ani_object HiAppEventAniHelper::AddWatcher(ani_env *env, ani_object watcher, uint64_t beginTime)
786 {
787 int32_t errCode = ERR_CODE_SUCC;
788 if (!IsValidWatcher(env, watcher, errCode)) {
789 HILOG_ERROR(LOG_CORE, "invalid watcher");
790 AppEventStat::WriteApiEndEventAsync("addWatcher", beginTime, AppEventStat::FAILED, errCode);
791 return {};
792 }
793 std::vector<AppEventFilter> filters;
794 GetFilters(env, watcher, filters);
795 std::string name = HiAppEventAniUtil::ParseStringValue(env,
796 HiAppEventAniUtil::GetProperty(env, watcher, WATCHER_NAME.c_str()));
797 TriggerCondition cond {
798 .row = 0,
799 .size = 0,
800 .timeout = 0
801 };
802 if (!GetCondition(env, watcher, cond)) {
803 return {};
804 }
805 auto watcherPtr = std::make_shared<AniAppEventWatcher>(name, filters, cond);
806
807 ani_ref trigger = HiAppEventAniUtil::GetProperty(env, watcher, FUNCTION_ONTRIGGER.c_str());
808 if (!HiAppEventAniUtil::IsRefUndefined(env, trigger)) {
809 watcherPtr->InitTrigger(env, trigger);
810 }
811
812 ani_ref receiver = HiAppEventAniUtil::GetProperty(env, watcher, FUNCTION_ONRECEIVE.c_str());
813 if (!HiAppEventAniUtil::IsRefUndefined(env, receiver)) {
814 watcherPtr->InitReceiver(env, receiver);
815 }
816
817 int64_t observerSeq = AppEventObserverMgr::GetInstance().AddWatcher(watcherPtr);
818 if (observerSeq <= 0) {
819 HILOG_ERROR(LOG_CORE, "invalid observer sequence");
820 AppEventStat::WriteApiEndEventAsync("addWatcher", beginTime, AppEventStat::FAILED, ERR_CODE_SUCC);
821 return {};
822 }
823
824 ani_object holder = CreateHolderObject(env, HiAppEventAniUtil::CreateAniString(env, name));
825 watcherPtr->InitHolder(env, holder);
826 AppEventStat::WriteApiEndEventAsync("addWatcher", beginTime, AppEventStat::SUCCESS, ERR_CODE_SUCC);
827 return static_cast<ani_object>(holder);
828 }
829
RemoveWatcher(ani_env * env,ani_object watcher,uint64_t beginTime)830 void HiAppEventAniHelper::RemoveWatcher(ani_env *env, ani_object watcher, uint64_t beginTime)
831 {
832 ani_ref nameRef = HiAppEventAniUtil::GetProperty(env, watcher, WATCHER_NAME.c_str());
833 int32_t errCode = ERR_CODE_SUCC;
834 if (!IsValidName(env, nameRef, errCode)) {
835 AppEventStat::WriteApiEndEventAsync("removeWatcher", beginTime, AppEventStat::FAILED, errCode);
836 return;
837 }
838 (void)AppEventObserverMgr::GetInstance().RemoveObserver(HiAppEventAniUtil::ParseStringValue(env, nameRef));
839 AppEventStat::WriteApiEndEventAsync("removeWatcher", beginTime, AppEventStat::SUCCESS, ERR_CODE_SUCC);
840 return;
841 }