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 }
44 
AddProcessor(napi_env env,napi_callback_info info)45 static napi_value AddProcessor(napi_env env, napi_callback_info info)
46 {
47     napi_value params[MAX_PARAM_NUM] = { 0 };
48     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for addProcessor is 1
49         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("addProcessor"));
50         return nullptr;
51     }
52     napi_value id = nullptr;
53     if (!NapiHiAppEventProcessor::AddProcessor(env, params[0], id)) {
54         HILOG_ERROR(LOG_CORE, "failed to add processor");
55     }
56     return id;
57 }
58 
RemoveProcessor(napi_env env,napi_callback_info info)59 static napi_value RemoveProcessor(napi_env env, napi_callback_info info)
60 {
61     napi_value params[MAX_PARAM_NUM] = { 0 };
62     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for removeProcessor is 1
63         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("removeProcessor"));
64         return nullptr;
65     }
66     if (!NapiHiAppEventProcessor::RemoveProcessor(env, params[0])) {
67         HILOG_ERROR(LOG_CORE, "failed to remove processor");
68     }
69     return nullptr;
70 }
71 
Write(napi_env env,napi_callback_info info)72 static napi_value Write(napi_env env, napi_callback_info info)
73 {
74     napi_value params[MAX_PARAM_NUM] = { 0 };
75     size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
76     NapiHiAppEventBuilder builder;
77     auto appEventPack = builder.BuildV9(env, params, paramNum);
78     if (appEventPack == nullptr) {
79         HILOG_ERROR(LOG_CORE, "failed to build appEventPack.");
80         return nullptr;
81     }
82 
83     auto asyncContext = new(std::nothrow) NapiHiAppEventWrite::HiAppEventAsyncContext(env);
84     if (asyncContext == nullptr) {
85         HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
86         return nullptr;
87     }
88     asyncContext->appEventPack = appEventPack;
89     asyncContext->result = builder.GetResult();
90     asyncContext->callback = builder.GetCallback();
91     asyncContext->isV9 = true;
92 
93     // if the build is successful, the event verification is performed
94     if (asyncContext->result >= 0) {
95         if (auto ret = VerifyAppEvent(asyncContext->appEventPack); ret != 0) {
96             asyncContext->result = ret;
97         }
98     }
99 
100     napi_value promise = nullptr;
101     if (asyncContext->callback == nullptr && napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
102         HILOG_ERROR(LOG_CORE, "callback is null, failed to create promise.");
103         return nullptr;
104     }
105 
106     NapiHiAppEventWrite::Write(env, asyncContext);
107     return promise;
108 }
109 
Configure(napi_env env,napi_callback_info info)110 static napi_value Configure(napi_env env, napi_callback_info info)
111 {
112     napi_value params[MAX_PARAM_NUM] = { 0 };
113     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for configure is 1
114         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("config"));
115         return nullptr;
116     }
117     if (!NapiHiAppEventConfig::Configure(env, params[0], true)) {
118         HILOG_ERROR(LOG_CORE, "failed to configure HiAppEvent");
119     }
120     return nullptr;
121 }
122 
SetUserId(napi_env env,napi_callback_info info)123 static napi_value SetUserId(napi_env env, napi_callback_info info)
124 {
125     napi_value params[MAX_PARAM_NUM] = { 0 };
126     if (NapiUtil::GetCbInfo(env, info, params) < 2) { // The min num of params for setUserId is 2
127         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setUserId"));
128         return nullptr;
129     }
130     if (!NapiHiAppEventUserInfo::SetUserId(env, params[0], params[1])) {
131         HILOG_ERROR(LOG_CORE, "failed to set userId");
132     }
133     return nullptr;
134 }
135 
GetUserId(napi_env env,napi_callback_info info)136 static napi_value GetUserId(napi_env env, napi_callback_info info)
137 {
138     napi_value params[MAX_PARAM_NUM] = { 0 };
139     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for getUserId is 1
140         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("getUserId"));
141         return nullptr;
142     }
143 
144     napi_value userId = nullptr;
145     if (!NapiHiAppEventUserInfo::GetUserId(env, params[0], userId)) {
146         HILOG_ERROR(LOG_CORE, "failed to get userId");
147     }
148     return userId;
149 }
150 
SetUserProperty(napi_env env,napi_callback_info info)151 static napi_value SetUserProperty(napi_env env, napi_callback_info info)
152 {
153     napi_value params[MAX_PARAM_NUM] = { 0 };
154     if (NapiUtil::GetCbInfo(env, info, params) < 2) { // The min num of params for setUserProperty is 2
155         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setUserProperty"));
156         return nullptr;
157     }
158     if (!NapiHiAppEventUserInfo::SetUserProperty(env, params[0], params[1])) {
159         HILOG_ERROR(LOG_CORE, "failed to set userProperty");
160     }
161     return nullptr;
162 }
163 
GetUserProperty(napi_env env,napi_callback_info info)164 static napi_value GetUserProperty(napi_env env, napi_callback_info info)
165 {
166     napi_value params[MAX_PARAM_NUM] = { 0 };
167     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for getUserProperty is 1
168         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("getUserProperty"));
169         return nullptr;
170     }
171 
172     napi_value userProperty = nullptr;
173     if (!NapiHiAppEventUserInfo::GetUserProperty(env, params[0], userProperty)) {
174         HILOG_ERROR(LOG_CORE, "failed to get userProperty");
175     }
176     return userProperty;
177 }
178 
ClearData(napi_env env,napi_callback_info info)179 static napi_value ClearData(napi_env env, napi_callback_info info)
180 {
181     uint64_t beginTime = TimeUtil::GetMilliseconds();
182     HiAppEventClean::ClearData(NapiHiAppEventConfig::GetStorageDir());
183     AppEventStat::WriteApiEndEventAsync("clearData", beginTime, AppEventStat::SUCCESS, NapiError::ERR_OK);
184     return NapiUtil::CreateUndefined(env);
185 }
186 
AddWatcher(napi_env env,napi_callback_info info)187 static napi_value AddWatcher(napi_env env, napi_callback_info info)
188 {
189     uint64_t beginTime = TimeUtil::GetMilliseconds();
190     napi_value params[MAX_PARAM_NUM] = { 0 };
191     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for addWatcher is 1
192         AppEventStat::WriteApiEndEventAsync("addWatcher", beginTime, AppEventStat::FAILED, NapiError::ERR_PARAM);
193         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("watcher"));
194         return nullptr;
195     }
196     return NapiHiAppEventWatch::AddWatcher(env, params[0], beginTime);
197 }
198 
RemoveWatcher(napi_env env,napi_callback_info info)199 static napi_value RemoveWatcher(napi_env env, napi_callback_info info)
200 {
201     uint64_t beginTime = TimeUtil::GetMilliseconds();
202     napi_value params[MAX_PARAM_NUM] = { 0 };
203     if (NapiUtil::GetCbInfo(env, info, params) < 1) { // The min num of params for removeWatcher is 1
204         AppEventStat::WriteApiEndEventAsync("removeWatcher", beginTime, AppEventStat::FAILED, NapiError::ERR_PARAM);
205         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("watcher"));
206         return nullptr;
207     }
208     return NapiHiAppEventWatch::RemoveWatcher(env, params[0], beginTime);
209 }
210 
SetEventParam(napi_env env,napi_callback_info info)211 static napi_value SetEventParam(napi_env env, napi_callback_info info)
212 {
213     napi_value params[MAX_PARAM_NUM] = { 0 };
214     size_t paramNum = NapiUtil::GetCbInfo(env, info, params);
215     NapiParamBuilder builder;
216     auto appEventPack = builder.BuildEventParam(env, params, paramNum);
217     if (appEventPack == nullptr) {
218         HILOG_ERROR(LOG_CORE, "failed to build appEventPack.");
219         return nullptr;
220     }
221 
222     auto asyncContext = new(std::nothrow) NapiHiAppEventWrite::HiAppEventAsyncContext(env);
223     if (asyncContext == nullptr) {
224         HILOG_ERROR(LOG_CORE, "failed to new asyncContext.");
225         return nullptr;
226     }
227     asyncContext->appEventPack = appEventPack;
228     asyncContext->result = builder.GetResult();
229 
230     napi_value promise = nullptr;
231     if (napi_create_promise(env, &asyncContext->deferred, &promise) != napi_ok) {
232         HILOG_ERROR(LOG_CORE, "failed to create promise.");
233         return nullptr;
234     }
235 
236     NapiHiAppEventWrite::SetEventParam(env, asyncContext);
237     return promise;
238 }
239 
240 EXTERN_C_START
Init(napi_env env,napi_value exports)241 static napi_value Init(napi_env env, napi_value exports)
242 {
243     napi_property_descriptor desc[] = {
244         DECLARE_NAPI_FUNCTION("addProcessor", AddProcessor),
245         DECLARE_NAPI_FUNCTION("removeProcessor", RemoveProcessor),
246         DECLARE_NAPI_FUNCTION("setUserId", SetUserId),
247         DECLARE_NAPI_FUNCTION("getUserId", GetUserId),
248         DECLARE_NAPI_FUNCTION("setUserProperty", SetUserProperty),
249         DECLARE_NAPI_FUNCTION("getUserProperty", GetUserProperty),
250         DECLARE_NAPI_FUNCTION("write", Write),
251         DECLARE_NAPI_FUNCTION("configure", Configure),
252         DECLARE_NAPI_FUNCTION("clearData", ClearData),
253         DECLARE_NAPI_FUNCTION("addWatcher", AddWatcher),
254         DECLARE_NAPI_FUNCTION("removeWatcher", RemoveWatcher),
255         DECLARE_NAPI_FUNCTION("setEventParam", SetEventParam)
256     };
257     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
258     NapiHiAppEventInit::InitNapiClassV9(env, exports);
259     NapiAppEventHolder::NapiExport(env, exports);
260     return exports;
261 }
262 EXTERN_C_END
263 
264 static napi_module g_module_v9 = {
265     .nm_version = 1,
266     .nm_flags = 0,
267     .nm_filename = nullptr,
268     .nm_register_func = Init,
269     .nm_modname = "hiviewdfx.hiAppEvent",
270     .nm_priv = ((void *)0),
271     .reserved = {0}
272 };
273 
RegisterModule(void)274 extern "C" __attribute__((constructor)) void RegisterModule(void)
275 {
276     napi_module_register(&g_module_v9);
277 }
278