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