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