1 /*
2 * Copyright (c) 2022-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 #include "app_event_stat.h"
16 #include "hiappevent_base.h"
17 #include "hiappevent_clean.h"
18 #include "hiappevent_verify.h"
19 #include "hilog/log.h"
20 #include "napi_app_event_holder.h"
21 #include "napi_config_builder.h"
22 #include "napi_error.h"
23 #include "napi_hiappevent_builder.h"
24 #include "napi_hiappevent_config.h"
25 #include "napi_hiappevent_processor.h"
26 #include "napi_hiappevent_userinfo.h"
27 #include "napi_hiappevent_init.h"
28 #include "napi_hiappevent_watch.h"
29 #include "napi_hiappevent_write.h"
30 #include "napi_param_builder.h"
31 #include "napi_util.h"
32 #include "time_util.h"
33
34 #undef LOG_DOMAIN
35 #define LOG_DOMAIN 0xD002D07
36
37 #undef LOG_TAG
38 #define LOG_TAG "Napi"
39
40 using namespace OHOS::HiviewDFX;
41
42 namespace {
43 constexpr size_t MAX_PARAM_NUM = 4;
44 }
45
AddProcessor(napi_env env,napi_callback_info info)46 static napi_value AddProcessor(napi_env env, napi_callback_info info)
47 {
48 napi_value params[MAX_PARAM_NUM] = { 0 };
49 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for addProcessor is 1
50 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("addProcessor"));
51 return nullptr;
52 }
53 napi_value id = nullptr;
54 if (!NapiHiAppEventProcessor::AddProcessor(env, params[0], id)) {
55 HILOG_ERROR(LOG_CORE, "failed to add processor");
56 }
57 return id;
58 }
59
AddProcessorFromConfig(napi_env env,napi_callback_info info)60 static napi_value AddProcessorFromConfig(napi_env env, napi_callback_info info)
61 {
62 napi_value params[MAX_PARAM_NUM] = { 0 };
63 size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
64 if (paramNum < 1) { // The min num of params for AddProcessorFromConfig is 1
65 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("AddProcessorFromConfig"));
66 return nullptr;
67 }
68 if (!NapiUtil::IsString(env, params[0])) {
69 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("processorName", "string"));
70 return nullptr;
71 }
72 if (paramNum > 1 && !NapiUtil::IsString(env, params[1])) { // for configName
73 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("configName", "string"));
74 return nullptr;
75 }
76
77 auto asyncContext = new(std::nothrow) NapiHiAppEventProcessor::AddProcessorFromConfigAsyncContext;
78 if (asyncContext == nullptr) {
79 HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
80 return nullptr;
81 }
82 asyncContext->processorName = NapiUtil::GetString(env, params[0]);
83 asyncContext->configName = paramNum > 1 ? NapiUtil::GetString(env, params[1]) : asyncContext->configName;
84
85 napi_value promise = nullptr;
86 if (napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
87 HILOG_ERROR(LOG_CORE, "failed to create promise.");
88 delete asyncContext;
89 return nullptr;
90 }
91
92 NapiHiAppEventProcessor::AddProcessorFromConfig(env, asyncContext);
93 return promise;
94 }
95
RemoveProcessor(napi_env env,napi_callback_info info)96 static napi_value RemoveProcessor(napi_env env, napi_callback_info info)
97 {
98 napi_value params[MAX_PARAM_NUM] = { 0 };
99 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for removeProcessor is 1
100 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("removeProcessor"));
101 return nullptr;
102 }
103 if (!NapiHiAppEventProcessor::RemoveProcessor(env, params[0])) {
104 HILOG_ERROR(LOG_CORE, "failed to remove processor");
105 }
106 return nullptr;
107 }
108
Write(napi_env env,napi_callback_info info)109 static napi_value Write(napi_env env, napi_callback_info info)
110 {
111 napi_value params[MAX_PARAM_NUM] = { 0 };
112 size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
113 NapiHiAppEventBuilder builder;
114 auto appEventPack = builder.BuildV9(env, params, paramNum);
115 if (appEventPack == nullptr) {
116 HILOG_ERROR(LOG_CORE, "failed to build appEventPack.");
117 return nullptr;
118 }
119
120 auto asyncContext = new(std::nothrow) NapiHiAppEventWrite::HiAppEventAsyncContext(env);
121 if (asyncContext == nullptr) {
122 HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
123 return nullptr;
124 }
125 asyncContext->appEventPack = appEventPack;
126 asyncContext->result = builder.GetResult();
127 asyncContext->callback = builder.GetCallback();
128 asyncContext->isV9 = true;
129
130 // if the build is successful, the event verification is performed
131 if (asyncContext->result >= 0) {
132 if (auto ret = VerifyAppEvent(asyncContext->appEventPack); ret != 0) {
133 asyncContext->result = ret;
134 }
135 }
136
137 napi_value promise = nullptr;
138 if (asyncContext->callback == nullptr && napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
139 HILOG_ERROR(LOG_CORE, "callback is null, failed to create promise.");
140 delete asyncContext;
141 return nullptr;
142 }
143
144 NapiHiAppEventWrite::Write(env, asyncContext);
145 return promise;
146 }
147
Configure(napi_env env,napi_callback_info info)148 static napi_value Configure(napi_env env, napi_callback_info info)
149 {
150 napi_value params[MAX_PARAM_NUM] = { 0 };
151 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for configure is 1
152 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("config"));
153 return nullptr;
154 }
155 if (!NapiHiAppEventConfig::Configure(env, params[0], true)) {
156 HILOG_ERROR(LOG_CORE, "failed to configure HiAppEvent");
157 }
158 return nullptr;
159 }
160
SetUserId(napi_env env,napi_callback_info info)161 static napi_value SetUserId(napi_env env, napi_callback_info info)
162 {
163 napi_value params[MAX_PARAM_NUM] = { 0 };
164 if (NapiUtil::GetCbInfo(env, info, params) < 2) { // The min num of params for setUserId is 2
165 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setUserId"));
166 return nullptr;
167 }
168 if (!NapiHiAppEventUserInfo::SetUserId(env, params[0], params[1])) {
169 HILOG_ERROR(LOG_CORE, "failed to set userId");
170 }
171 return nullptr;
172 }
173
GetUserId(napi_env env,napi_callback_info info)174 static napi_value GetUserId(napi_env env, napi_callback_info info)
175 {
176 napi_value params[MAX_PARAM_NUM] = { 0 };
177 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for getUserId is 1
178 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("getUserId"));
179 return nullptr;
180 }
181
182 napi_value userId = nullptr;
183 if (!NapiHiAppEventUserInfo::GetUserId(env, params[0], userId)) {
184 HILOG_ERROR(LOG_CORE, "failed to get userId");
185 }
186 return userId;
187 }
188
SetUserProperty(napi_env env,napi_callback_info info)189 static napi_value SetUserProperty(napi_env env, napi_callback_info info)
190 {
191 napi_value params[MAX_PARAM_NUM] = { 0 };
192 if (NapiUtil::GetCbInfo(env, info, params) < 2) { // The min num of params for setUserProperty is 2
193 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setUserProperty"));
194 return nullptr;
195 }
196 if (!NapiHiAppEventUserInfo::SetUserProperty(env, params[0], params[1])) {
197 HILOG_ERROR(LOG_CORE, "failed to set userProperty");
198 }
199 return nullptr;
200 }
201
GetUserProperty(napi_env env,napi_callback_info info)202 static napi_value GetUserProperty(napi_env env, napi_callback_info info)
203 {
204 napi_value params[MAX_PARAM_NUM] = { 0 };
205 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for getUserProperty is 1
206 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("getUserProperty"));
207 return nullptr;
208 }
209
210 napi_value userProperty = nullptr;
211 if (!NapiHiAppEventUserInfo::GetUserProperty(env, params[0], userProperty)) {
212 HILOG_ERROR(LOG_CORE, "failed to get userProperty");
213 }
214 return userProperty;
215 }
216
ClearData(napi_env env,napi_callback_info info)217 static napi_value ClearData(napi_env env, napi_callback_info info)
218 {
219 uint64_t beginTime = static_cast<uint64_t>(TimeUtil::GetElapsedMilliSecondsSinceBoot());
220 HiAppEventClean::ClearData(NapiHiAppEventConfig::GetStorageDir());
221 AppEventStat::WriteApiEndEventAsync("clearData", beginTime, AppEventStat::SUCCESS, NapiError::ERR_OK);
222 return NapiUtil::CreateUndefined(env);
223 }
224
AddWatcher(napi_env env,napi_callback_info info)225 static napi_value AddWatcher(napi_env env, napi_callback_info info)
226 {
227 uint64_t beginTime = static_cast<uint64_t>(TimeUtil::GetElapsedMilliSecondsSinceBoot());
228 napi_value params[MAX_PARAM_NUM] = { 0 };
229 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for addWatcher is 1
230 AppEventStat::WriteApiEndEventAsync("addWatcher", beginTime, AppEventStat::FAILED, NapiError::ERR_PARAM);
231 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("watcher"));
232 return nullptr;
233 }
234 return NapiHiAppEventWatch::AddWatcher(env, params[0], beginTime);
235 }
236
RemoveWatcher(napi_env env,napi_callback_info info)237 static napi_value RemoveWatcher(napi_env env, napi_callback_info info)
238 {
239 uint64_t beginTime = static_cast<uint64_t>(TimeUtil::GetElapsedMilliSecondsSinceBoot());
240 napi_value params[MAX_PARAM_NUM] = { 0 };
241 if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for removeWatcher is 1
242 AppEventStat::WriteApiEndEventAsync("removeWatcher", beginTime, AppEventStat::FAILED, NapiError::ERR_PARAM);
243 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("watcher"));
244 return nullptr;
245 }
246 return NapiHiAppEventWatch::RemoveWatcher(env, params[0], beginTime);
247 }
248
SetEventParam(napi_env env,napi_callback_info info)249 static napi_value SetEventParam(napi_env env, napi_callback_info info)
250 {
251 napi_value params[MAX_PARAM_NUM] = { 0 };
252 size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
253 NapiParamBuilder builder;
254 auto appEventPack = builder.BuildEventParam(env, params, paramNum);
255 if (appEventPack == nullptr) {
256 HILOG_ERROR(LOG_CORE, "failed to build appEventPack.");
257 return nullptr;
258 }
259
260 auto asyncContext = new(std::nothrow) NapiHiAppEventWrite::HiAppEventAsyncContext(env);
261 if (asyncContext == nullptr) {
262 HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
263 return nullptr;
264 }
265 asyncContext->appEventPack = appEventPack;
266 asyncContext->result = builder.GetResult();
267
268 napi_value promise = nullptr;
269 if (napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
270 HILOG_ERROR(LOG_CORE, "failed to create promise.");
271 delete asyncContext;
272 return nullptr;
273 }
274
275 NapiHiAppEventWrite::SetEventParam(env, asyncContext);
276 return promise;
277 }
278
SetEventConfig(napi_env env,napi_callback_info info)279 static napi_value SetEventConfig(napi_env env, napi_callback_info info)
280 {
281 napi_value params[MAX_PARAM_NUM] = { 0 };
282 size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
283 NapiConfigBuilder builder;
284 auto eventConfigPack = builder.BuildEventConfig(env, params, paramNum);
285 if (eventConfigPack == nullptr) {
286 HILOG_ERROR(LOG_CORE, "failed to build eventConfigPack.");
287 return nullptr;
288 }
289
290 auto asyncContext = new(std::nothrow) NapiHiAppEventConfig::HiAppEventConfigAsyncContext;
291 if (asyncContext == nullptr) {
292 HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
293 return nullptr;
294 }
295 asyncContext->eventConfigPack = std::move(eventConfigPack);
296
297 napi_value promise = nullptr;
298 if (napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
299 HILOG_ERROR(LOG_CORE, "failed to create promise.");
300 delete asyncContext;
301 return nullptr;
302 }
303
304 NapiHiAppEventConfig::SetEventConfig(env, asyncContext);
305 return promise;
306 }
307
308 EXTERN_C_START
Init(napi_env env,napi_value exports)309 static napi_value Init(napi_env env, napi_value exports)
310 {
311 napi_property_descriptor desc[] = {
312 DECLARE_NAPI_FUNCTION("addProcessor", AddProcessor),
313 DECLARE_NAPI_FUNCTION("removeProcessor", RemoveProcessor),
314 DECLARE_NAPI_FUNCTION("addProcessorFromConfig", AddProcessorFromConfig),
315 DECLARE_NAPI_FUNCTION("setUserId", SetUserId),
316 DECLARE_NAPI_FUNCTION("getUserId", GetUserId),
317 DECLARE_NAPI_FUNCTION("setUserProperty", SetUserProperty),
318 DECLARE_NAPI_FUNCTION("getUserProperty", GetUserProperty),
319 DECLARE_NAPI_FUNCTION("write", Write),
320 DECLARE_NAPI_FUNCTION("configure", Configure),
321 DECLARE_NAPI_FUNCTION("clearData", ClearData),
322 DECLARE_NAPI_FUNCTION("addWatcher", AddWatcher),
323 DECLARE_NAPI_FUNCTION("removeWatcher", RemoveWatcher),
324 DECLARE_NAPI_FUNCTION("setEventParam", SetEventParam),
325 DECLARE_NAPI_FUNCTION("setEventConfig", SetEventConfig)
326 };
327 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
328 NapiHiAppEventInit::InitNapiClassV9(env, exports);
329 NapiAppEventHolder::NapiExport(env, exports);
330 return exports;
331 }
332 EXTERN_C_END
333
334 static napi_module g_module_v9 = {
335 .nm_version = 1,
336 .nm_flags = 0,
337 .nm_filename = nullptr,
338 .nm_register_func = Init,
339 .nm_modname = "hiviewdfx.hiAppEvent",
340 .nm_priv = ((void *)0),
341 .reserved = {0}
342 };
343
RegisterModule(void)344 extern "C" __attribute__((constructor)) void RegisterModule(void)
345 {
346 napi_module_register(&g_module_v9);
347 }
348