1 /*
2 * Copyright (c) 2021-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 "napi_hiappevent_builder.h"
16
17 #include "hiappevent_base.h"
18 #include "hiappevent_verify.h"
19 #include "hilog/log.h"
20 #include "napi_error.h"
21 #include "napi_util.h"
22
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN 0xD002D07
25
26 #undef LOG_TAG
27 #define LOG_TAG "NapiEventBuilder"
28
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 const std::string DOMAIN_PROPERTY = "domain";
33 const std::string NAME_PROPERTY = "name";
34 const std::string TYPE_PROPERTY = "eventType";
35 const std::string PARAM_PROPERTY = "params";
36 constexpr size_t MAX_LENGTH_OF_PARAM_NAME = 32;
37 const std::string PARAM_VALUE_TYPE = "boolean|number|string|array[boolean|number|string]";
38 }
39 using namespace OHOS::HiviewDFX::ErrorCode;
40
IsValidEventDomain(const napi_env env,const napi_value domain)41 bool NapiHiAppEventBuilder::IsValidEventDomain(const napi_env env, const napi_value domain)
42 {
43 if (domain == nullptr) {
44 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("domain"), isV9_);
45 return false;
46 }
47 if (!NapiUtil::IsString(env, domain)) {
48 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("domain", "string"), isV9_);
49 return false;
50 }
51 return true;
52 }
53
IsValidEventName(const napi_env env,const napi_value name)54 bool NapiHiAppEventBuilder::IsValidEventName(const napi_env env, const napi_value name)
55 {
56 if (name == nullptr) {
57 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("name"), isV9_);
58 return false;
59 }
60 if (!NapiUtil::IsString(env, name)) {
61 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("name", "string"), isV9_);
62 return false;
63 }
64 return true;
65 }
66
IsValidEventType(const napi_env env,const napi_value type)67 bool NapiHiAppEventBuilder::IsValidEventType(const napi_env env, const napi_value type)
68 {
69 if (type == nullptr) {
70 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("eventType"), isV9_);
71 return false;
72 }
73 if (!NapiUtil::IsNumber(env, type) || !OHOS::HiviewDFX::IsValidEventType(NapiUtil::GetInt32(env, type))) {
74 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("eventType", "EventType"), isV9_);
75 return false;
76 }
77 return true;
78 }
79
IsValidEventParam(const napi_env env,const napi_value param)80 bool NapiHiAppEventBuilder::IsValidEventParam(const napi_env env, const napi_value param)
81 {
82 if (param == nullptr) {
83 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("params"), isV9_);
84 return false;
85 }
86 if (!NapiUtil::IsObject(env, param)) {
87 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("params", "object"), isV9_);
88 return false;
89 }
90 return true;
91 }
92
IsValidEventInfo(const napi_env env,const napi_value eventInfo)93 bool NapiHiAppEventBuilder::IsValidEventInfo(const napi_env env, const napi_value eventInfo)
94 {
95 if (!NapiUtil::IsObject(env, eventInfo)) {
96 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("info", "AppEventInfo"), isV9_);
97 return false;
98 }
99 return IsValidEventDomain(env, NapiUtil::GetProperty(env, eventInfo, DOMAIN_PROPERTY))
100 && IsValidEventName(env, NapiUtil::GetProperty(env, eventInfo, NAME_PROPERTY))
101 && IsValidEventType(env, NapiUtil::GetProperty(env, eventInfo, TYPE_PROPERTY))
102 && IsValidEventParam(env, NapiUtil::GetProperty(env, eventInfo, PARAM_PROPERTY));
103 }
104
IsOldWriteParams(const napi_env env,const napi_value params[],size_t len)105 bool NapiHiAppEventBuilder::IsOldWriteParams(const napi_env env, const napi_value params[], size_t len)
106 {
107 return IsValidEventName(env, params[0]) // 0 means the index of event name
108 && IsValidEventType(env, params[1]) // 1 means the index of event type
109 && IsValidEventParam(env, params[2]); // 2 means the index of event param
110 }
111
IsNewWriteParams(const napi_env env,const napi_value params[],size_t len)112 bool NapiHiAppEventBuilder::IsNewWriteParams(const napi_env env, const napi_value params[], size_t len)
113 {
114 return IsValidEventInfo(env, params[0]);
115 }
116
AddArrayParam2EventPack(napi_env env,const std::string & key,const napi_value arr)117 bool NapiHiAppEventBuilder::AddArrayParam2EventPack(napi_env env, const std::string &key,
118 const napi_value arr)
119 {
120 napi_valuetype type = NapiUtil::GetArrayType(env, arr);
121 switch (type) {
122 case napi_boolean: {
123 std::vector<bool> bools;
124 NapiUtil::GetBooleans(env, arr, bools);
125 appEventPack_->AddParam(key, bools);
126 break;
127 }
128 case napi_number: {
129 std::vector<double> doubles;
130 NapiUtil::GetDoubles(env, arr, doubles);
131 appEventPack_->AddParam(key, doubles);
132 break;
133 }
134 case napi_string: {
135 std::vector<std::string> strs;
136 NapiUtil::GetStrings(env, arr, strs);
137 appEventPack_->AddParam(key, strs);
138 break;
139 }
140 case napi_null: {
141 appEventPack_->AddParam(key);
142 break;
143 }
144 default: {
145 HILOG_ERROR(LOG_CORE, "array param value type is invalid");
146 result_ = ERROR_INVALID_LIST_PARAM_TYPE;
147 std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
148 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
149 return false;
150 }
151 }
152 return true;
153 }
154
AddParam2EventPack(napi_env env,const std::string & key,const napi_value value)155 bool NapiHiAppEventBuilder::AddParam2EventPack(napi_env env, const std::string &key,
156 const napi_value value)
157 {
158 napi_valuetype type = NapiUtil::GetType(env, value);
159 switch (type) {
160 case napi_boolean:
161 appEventPack_->AddParam(key, NapiUtil::GetBoolean(env, value));
162 break;
163 case napi_number:
164 appEventPack_->AddParam(key, NapiUtil::GetDouble(env, value));
165 break;
166 case napi_string:
167 appEventPack_->AddParam(key, NapiUtil::GetString(env, value));
168 break;
169 case napi_object:
170 if (NapiUtil::IsArray(env, value)) {
171 return AddArrayParam2EventPack(env, key, value);
172 }
173 [[fallthrough]];
174 default:
175 HILOG_ERROR(LOG_CORE, "param value type is invalid");
176 result_ = ERROR_INVALID_PARAM_VALUE_TYPE;
177 std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
178 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
179 return false;
180 }
181 return true;
182 }
183
AddParams2EventPack(napi_env env,const napi_value paramObj)184 bool NapiHiAppEventBuilder::AddParams2EventPack(napi_env env, const napi_value paramObj)
185 {
186 std::vector<std::string> keys;
187 NapiUtil::GetPropertyNames(env, paramObj, keys);
188 for (auto key : keys) {
189 if (key.length() > MAX_LENGTH_OF_PARAM_NAME) {
190 result_ = ERROR_INVALID_PARAM_NAME;
191 HILOG_INFO(LOG_CORE, "the length=%{public}zu of the param key is invalid", key.length());
192 continue;
193 }
194 napi_value value = NapiUtil::GetProperty(env, paramObj, key);
195 if (value == nullptr) {
196 result_ = ERROR_INVALID_PARAM_VALUE_TYPE;
197 std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
198 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
199 return false;
200 }
201 if (!AddParam2EventPack(env, key, value)) {
202 return false;
203 }
204 }
205 return true;
206 }
207
BuildEventPack(napi_env env,const napi_value params[])208 void NapiHiAppEventBuilder::BuildEventPack(napi_env env, const napi_value params[])
209 {
210 int index = 0;
211 std::string name = NapiUtil::GetString(env, params[index++]);
212 int32_t type = NapiUtil::GetInt32(env, params[index++]);
213 appEventPack_ = std::make_shared<AppEventPack>(name, type);
214 AddParams2EventPack(env, params[index]);
215 }
216
BuildEventPack(napi_env env,const napi_value eventInfo)217 bool NapiHiAppEventBuilder::BuildEventPack(napi_env env, const napi_value eventInfo)
218 {
219 std::string domain = NapiUtil::GetString(env, NapiUtil::GetProperty(env, eventInfo, DOMAIN_PROPERTY));
220 std::string name = NapiUtil::GetString(env, NapiUtil::GetProperty(env, eventInfo, NAME_PROPERTY));
221 int32_t type = NapiUtil::GetInt32(env, NapiUtil::GetProperty(env, eventInfo, TYPE_PROPERTY));
222 appEventPack_ = std::make_shared<AppEventPack>(domain, name, type);
223 napi_value param = NapiUtil::GetProperty(env, eventInfo, PARAM_PROPERTY);
224 return AddParams2EventPack(env, param);
225 }
226
BuildCallback(const napi_env env,const napi_value callback)227 void NapiHiAppEventBuilder::BuildCallback(const napi_env env, const napi_value callback)
228 {
229 if (NapiUtil::IsFunction(env, callback)) {
230 callback_ = NapiUtil::CreateReference(env, callback);
231 }
232 }
233
Build(const napi_env env,const napi_value params[],size_t len)234 std::shared_ptr<AppEventPack> NapiHiAppEventBuilder::Build(const napi_env env, const napi_value params[], size_t len)
235 {
236 if (len < 3) { // the min number of params for write is 3
237 result_ = ERROR_INVALID_PARAM_NUM_JS;
238 return nullptr;
239 }
240
241 // 1. build AppEventPack
242 if (IsOldWriteParams(env, params, len)) {
243 BuildEventPack(env, params);
244 } else {
245 result_ = ERROR_INVALID_PARAM_TYPE_JS;
246 }
247
248 // 2. build callback if any
249 BuildCallback(env, params[len - 1]); // (len - 1) means the last param
250 return appEventPack_;
251 }
252
BuildV9(const napi_env env,const napi_value params[],size_t len)253 std::shared_ptr<AppEventPack> NapiHiAppEventBuilder::BuildV9(const napi_env env, const napi_value params[], size_t len)
254 {
255 isV9_ = true;
256 if (len < 1) { // the min number of params for writeV9 is 1
257 NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("info"), isV9_);
258 return nullptr;
259 }
260 if (!IsNewWriteParams(env, params, len)) {
261 return nullptr;
262 }
263 if (!BuildEventPack(env, params[0])) {
264 return nullptr;
265 }
266 BuildCallback(env, params[len - 1]); // (len - 1) means the last param
267 return appEventPack_;
268 }
269
GetResult() const270 int NapiHiAppEventBuilder::GetResult() const
271 {
272 return result_;
273 }
274
GetCallback() const275 napi_ref NapiHiAppEventBuilder::GetCallback() const
276 {
277 return callback_;
278 }
279 } // namespace HiviewDFX
280 } // namespace OHOS
281