• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param : 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 }