• 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_STRING_LEN = 8 * 1024 + 2; // 2 for '\0' and extra symbol
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, MAX_STRING_LEN);
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, MAX_STRING_LEN));
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         napi_value value = NapiUtil::GetProperty(env, paramObj, key);
184         if (value == nullptr) {
185             result_ = ERROR_INVALID_PARAM_VALUE_TYPE;
186             std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
187             NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
188             continue;
189         }
190         AddParam2EventPack(env, key, value);
191     }
192 }
193 
BuildEventPack(napi_env env,const napi_value params[])194 void NapiHiAppEventBuilder::BuildEventPack(napi_env env, const napi_value params[])
195 {
196     int index = 0;
197     std::string name = NapiUtil::GetString(env, params[index++]);
198     int32_t type = NapiUtil::GetInt32(env, params[index++]);
199     appEventPack_ = std::make_shared<AppEventPack>(name, type);
200     AddParams2EventPack(env, params[index]);
201 }
202 
BuildEventPack(napi_env env,const napi_value eventInfo)203 void NapiHiAppEventBuilder::BuildEventPack(napi_env env, const napi_value eventInfo)
204 {
205     std::string domain = NapiUtil::GetString(env, NapiUtil::GetProperty(env, eventInfo, DOMAIN_PROPERTY));
206     std::string name = NapiUtil::GetString(env, NapiUtil::GetProperty(env, eventInfo, NAME_PROPERTY));
207     int32_t type = NapiUtil::GetInt32(env, NapiUtil::GetProperty(env, eventInfo, TYPE_PROPERTY));
208     appEventPack_ = std::make_shared<AppEventPack>(domain, name, type);
209     napi_value param = NapiUtil::GetProperty(env, eventInfo, PARAM_PROPERTY);
210     AddParams2EventPack(env, param);
211 }
212 
BuildCallback(const napi_env env,const napi_value callback)213 void NapiHiAppEventBuilder::BuildCallback(const napi_env env, const napi_value callback)
214 {
215     if (NapiUtil::IsFunction(env, callback)) {
216         callback_ = NapiUtil::CreateReference(env, callback);
217     }
218 }
219 
Build(const napi_env env,const napi_value params[],size_t len)220 std::shared_ptr<AppEventPack> NapiHiAppEventBuilder::Build(const napi_env env, const napi_value params[], size_t len)
221 {
222     if (len < 3) { // the min number of params for write is 3
223         result_ = ERROR_INVALID_PARAM_NUM_JS;
224         return nullptr;
225     }
226 
227     // 1. build AppEventPack
228     if (IsOldWriteParams(env, params, len)) {
229         BuildEventPack(env, params);
230     } else {
231         result_ = ERROR_INVALID_PARAM_TYPE_JS;
232     }
233 
234     // 2. build callback if any
235     BuildCallback(env, params[len - 1]); // (len - 1) means the last param
236     return appEventPack_;
237 }
238 
BuildV9(const napi_env env,const napi_value params[],size_t len)239 std::shared_ptr<AppEventPack> NapiHiAppEventBuilder::BuildV9(const napi_env env, const napi_value params[], size_t len)
240 {
241     isV9_ = true;
242     if (len < 1) { // the min number of params for writeV9 is 1
243         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("info"), isV9_);
244         return nullptr;
245     }
246     if (!IsNewWriteParams(env, params, len)) {
247         return nullptr;
248     }
249     BuildEventPack(env, params[0]);
250     BuildCallback(env, params[len - 1]); // (len - 1) means the last param
251     return appEventPack_;
252 }
253 
GetResult() const254 int NapiHiAppEventBuilder::GetResult() const
255 {
256     return result_;
257 }
258 
GetCallback() const259 napi_ref NapiHiAppEventBuilder::GetCallback() const
260 {
261     return callback_;
262 }
263 } // namespace HiviewDFX
264 } // namespace OHOS
265