1 /*
2 * Copyright (C) 2021 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
16 #include "napi_util.h"
17
18 #include <codecvt>
19 #include <cstdio>
20 #include <cstring>
21 #include <locale>
22 #include <memory>
23 #include <unordered_map>
24 #include <vector>
25
26 #include "core_service_errors.h"
27 #include "enum_convert_for_js.h"
28 #include "state_registry_errors.h"
29 #include "telephony_log_wrapper.h"
30
31 namespace OHOS {
32 namespace Telephony {
33 static constexpr int32_t MAX_TEXT_LENGTH = 4096;
34 static constexpr const char *JS_ERROR_TELEPHONY_PERMISSION_DENIED_STRING = "Permission denied.";
35 static constexpr const char *JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API_STRING = "Non-system applications use system APIs.";
36 static constexpr const char *JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER_STRING =
37 "Parameter error. The type of parameter should match or the number of parameters must match.";
38 static constexpr const char *JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API_STRING = "The device does not support this API.";
39 static constexpr const char *JS_ERROR_TELEPHONY_SUCCESS_STRING = "Success.";
40 static constexpr const char *JS_ERROR_TELEPHONY_ARGUMENT_ERROR_STRING = "Invalid parameter value.";
41 static constexpr const char *JS_ERROR_TELEPHONY_SERVICE_ERROR_STRING = "Operation failed. Cannot connect to service.";
42 static constexpr const char *JS_ERROR_TELEPHONY_SYSTEM_ERROR_STRING = "System internal error.";
43 static constexpr const char *JS_ERROR_TELEPHONY_NO_SIM_CARD_STRING = "Do not have sim card.";
44 static constexpr const char *JS_ERROR_TELEPHONY_UNKNOW_ERROR_STRING = "Unknown error code.";
45 static constexpr const char *JS_ERROR_SIM_BASE_ERROR_STRING = "Sim module base error.";
46 static constexpr const char *JS_ERROR_SIM_CARD_IS_NOT_ACTIVE_STRING = "SIM card is not activated.";
47 static constexpr const char *JS_ERROR_SIM_CARD_OPERATION_ERROR_STRING = "SIM card operation error.";
48 static constexpr const char *JS_ERROR_OPERATOR_CONFIG_ERROR_STRING = "Operator config error.";
49 static constexpr const char *JS_ERROR_NETWORK_SEARCH_BASE_ERROR_STRING = "Network search module base error.";
50 static constexpr const char *JS_ERROR_CALL_MANAGER_BASE_ERROR_STRING = "Call manager module base error.";
51 static constexpr const char *JS_ERROR_CELLULAR_CALL_CS_BASE_ERROR_STRING = "Cellular call module cs base error.";
52 static constexpr const char *JS_ERROR_CELLULAR_CALL_IMS_BASE_ERROR_STRING = "Cellular call module ims base error.";
53 static constexpr const char *JS_ERROR_CELLULAR_DATA_BASE_ERROR_STRING = "Cellular data module base error.";
54 static constexpr const char *JS_ERROR_SMS_MMS_BASE_ERROR_STRING = "Sms mms module base error.";
55 static constexpr const char *JS_ERROR_STATE_REGISTRY_BASE_ERROR_STRING = "State registry module base error.";
56 static constexpr const char *JS_ERROR_AIRPLANE_MODE_ON_STRING = "Airplane mode is on.";
57 static constexpr const char *JS_ERROR_NETWORK_NOT_IN_SERVICE = "Network not in service.";
58 static constexpr const char *JS_ERROR_CONFERENCE_EXCEED_LIMIT_STRING = "Conference call is exceed limit.";
59 static constexpr const char *JS_ERROR_CONFERENCE_CALL_IS_NOT_ACTIVE_STRING = "Conference call is not active.";
60 static constexpr const char *JS_ERROR_TELEPHONY_CALL_COUNTS_EXCEED_LIMIT_STRING = "call count exceeds limit";
61 static constexpr const char *JS_ERROR_TELEPHONY_DIAL_IS_BUSY_STRING =
62 "Current on a call, unable to initiate a new call";
63
64 static std::unordered_map<int32_t, const char *> errorMap_ = {
65 { JsErrorCode::JS_ERROR_TELEPHONY_PERMISSION_DENIED, JS_ERROR_TELEPHONY_PERMISSION_DENIED_STRING },
66 { JsErrorCode::JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API, JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API_STRING },
67 { JsErrorCode::JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER, JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER_STRING },
68 { JsErrorCode::JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API, JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API_STRING },
69 { JsErrorCode::JS_ERROR_TELEPHONY_SUCCESS, JS_ERROR_TELEPHONY_SUCCESS_STRING },
70 { JsErrorCode::JS_ERROR_TELEPHONY_ARGUMENT_ERROR, JS_ERROR_TELEPHONY_ARGUMENT_ERROR_STRING },
71 { JsErrorCode::JS_ERROR_TELEPHONY_SERVICE_ERROR, JS_ERROR_TELEPHONY_SERVICE_ERROR_STRING },
72 { JsErrorCode::JS_ERROR_TELEPHONY_SYSTEM_ERROR, JS_ERROR_TELEPHONY_SYSTEM_ERROR_STRING },
73 { JsErrorCode::JS_ERROR_TELEPHONY_NO_SIM_CARD, JS_ERROR_TELEPHONY_NO_SIM_CARD_STRING },
74 { JsErrorCode::JS_ERROR_TELEPHONY_UNKNOW_ERROR, JS_ERROR_TELEPHONY_UNKNOW_ERROR_STRING },
75 { JsErrorCode::JS_ERROR_SIM_BASE_ERROR, JS_ERROR_SIM_BASE_ERROR_STRING },
76 { JsErrorCode::JS_ERROR_SIM_CARD_IS_NOT_ACTIVE, JS_ERROR_SIM_CARD_IS_NOT_ACTIVE_STRING },
77 { JsErrorCode::JS_ERROR_SIM_CARD_OPERATION_ERROR, JS_ERROR_SIM_CARD_OPERATION_ERROR_STRING },
78 { JsErrorCode::JS_ERROR_OPERATOR_CONFIG_ERROR, JS_ERROR_OPERATOR_CONFIG_ERROR_STRING },
79 { JsErrorCode::JS_ERROR_NETWORK_SEARCH_BASE_ERROR, JS_ERROR_NETWORK_SEARCH_BASE_ERROR_STRING },
80 { JsErrorCode::JS_ERROR_CALL_MANAGER_BASE_ERROR, JS_ERROR_CALL_MANAGER_BASE_ERROR_STRING },
81 { JsErrorCode::JS_ERROR_CELLULAR_CALL_CS_BASE_ERROR, JS_ERROR_CELLULAR_CALL_CS_BASE_ERROR_STRING },
82 { JsErrorCode::JS_ERROR_CELLULAR_CALL_IMS_BASE_ERROR, JS_ERROR_CELLULAR_CALL_IMS_BASE_ERROR_STRING },
83 { JsErrorCode::JS_ERROR_CELLULAR_DATA_BASE_ERROR, JS_ERROR_CELLULAR_DATA_BASE_ERROR_STRING },
84 { JsErrorCode::JS_ERROR_SMS_MMS_BASE_ERROR, JS_ERROR_SMS_MMS_BASE_ERROR_STRING },
85 { JsErrorCode::JS_ERROR_STATE_REGISTRY_BASE_ERROR, JS_ERROR_STATE_REGISTRY_BASE_ERROR_STRING },
86 { JsErrorCode::JS_ERROR_TELEPHONY_AIRPLANE_MODE_ON, JS_ERROR_AIRPLANE_MODE_ON_STRING },
87 { JsErrorCode::JS_ERROR_TELEPHONY_NETWORK_NOT_IN_SERVICE, JS_ERROR_NETWORK_NOT_IN_SERVICE },
88 { JsErrorCode::JS_ERROR_TELEPHONY_CONFERENCE_EXCEED_LIMIT, JS_ERROR_CONFERENCE_EXCEED_LIMIT_STRING },
89 { JsErrorCode::JS_ERROR_TELEPHONY_CONFERENCE_CALL_NOT_ACTIVE, JS_ERROR_CONFERENCE_CALL_IS_NOT_ACTIVE_STRING },
90 { JsErrorCode::JS_ERROR_TELEPHONY_CALL_COUNTS_EXCEED_LIMIT, JS_ERROR_TELEPHONY_CALL_COUNTS_EXCEED_LIMIT_STRING },
91 { JsErrorCode::JS_ERROR_TELEPHONY_DIAL_IS_BUSY, JS_ERROR_TELEPHONY_DIAL_IS_BUSY_STRING },
92 };
93 const std::string ERROR_STRING = "error";
94 const std::u16string ERROR_USTRING = u"error";
95
GetErrorMessage(int32_t errorCode)96 std::string NapiUtil::GetErrorMessage(int32_t errorCode)
97 {
98 std::string result = "";
99 auto iter = errorMap_.find(errorCode);
100 if (iter == errorMap_.end()) {
101 TELEPHONY_LOGE("NapiUtil::GetErrorMessage return null.");
102 return result;
103 }
104 TELEPHONY_LOGD("NapiUtil::GetErrorMessage errorCode %{public}d, message = %{public}s", errorCode, iter->second);
105 result = iter->second;
106 return result;
107 }
108
ToUtf8(std::u16string str16)109 std::string NapiUtil::ToUtf8(std::u16string str16)
110 {
111 if (str16 == ERROR_USTRING) {
112 return ERROR_STRING;
113 }
114 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(ERROR_STRING);
115 std::string result = convert.to_bytes(str16);
116 return result == ERROR_STRING ? "" : result;
117 }
118
ToUtf16(std::string str)119 std::u16string NapiUtil::ToUtf16(std::string str)
120 {
121 if (str == ERROR_STRING) {
122 return ERROR_USTRING;
123 }
124 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(ERROR_STRING, ERROR_USTRING);
125 std::u16string result = convert.from_bytes(str);
126 return result == ERROR_USTRING ? u"" : result;
127 }
128
CreateErrorMessage(napi_env env,const std::string & msg,int32_t errorCode)129 napi_value NapiUtil::CreateErrorMessage(napi_env env, const std::string &msg, int32_t errorCode)
130 {
131 napi_value result = nullptr;
132 napi_value message = nullptr;
133 NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.length(), &message));
134 napi_value codeValue = nullptr;
135 NAPI_CALL(env, napi_create_int32(env, errorCode, &codeValue));
136 NAPI_CALL(env, napi_create_object(env, &result));
137 NAPI_CALL(env, napi_set_named_property(env, result, "code", codeValue));
138 NAPI_CALL(env, napi_set_named_property(env, result, "message", message));
139 return result;
140 }
141
CreateUndefined(napi_env env)142 napi_value NapiUtil::CreateUndefined(napi_env env)
143 {
144 napi_value result = nullptr;
145 NAPI_CALL(env, napi_get_undefined(env, &result));
146 return result;
147 }
148
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)149 bool NapiUtil::MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
150 {
151 napi_valuetype valueType = napi_undefined;
152 NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
153 return valueType == targetType;
154 }
155
MatchParameters(napi_env env,const napi_value parameters[],std::initializer_list<napi_valuetype> valueTypes)156 bool NapiUtil::MatchParameters(
157 napi_env env, const napi_value parameters[], std::initializer_list<napi_valuetype> valueTypes)
158 {
159 if (parameters == nullptr) {
160 return false;
161 }
162 int i = 0;
163 for (auto beg = valueTypes.begin(); beg != valueTypes.end(); ++beg) {
164 if (!MatchValueType(env, parameters[i], *beg)) {
165 return false;
166 }
167 ++i;
168 }
169 return true;
170 }
171
SetPropertyInt32(napi_env env,napi_value object,const std::string & name,int32_t value)172 void NapiUtil::SetPropertyInt32(napi_env env, napi_value object, const std::string &name, int32_t value)
173 {
174 napi_value propertyValue = nullptr;
175 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, value, &propertyValue));
176 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
177 }
178
SetPropertyInt64(napi_env env,napi_value object,const std::string & name,int64_t value)179 void NapiUtil::SetPropertyInt64(napi_env env, napi_value object, const std::string &name, int64_t value)
180 {
181 napi_value propertyValue = nullptr;
182 NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, value, &propertyValue));
183 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
184 }
185
SetPropertyStringUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)186 void NapiUtil::SetPropertyStringUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
187 {
188 napi_value propertyValue = nullptr;
189 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, value.c_str(), value.length(), &propertyValue));
190 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
191 }
192
SetPropertyBoolean(napi_env env,napi_value object,const std::string & name,bool value)193 void NapiUtil::SetPropertyBoolean(napi_env env, napi_value object, const std::string &name, bool value)
194 {
195 napi_value propertyValue = nullptr;
196 NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &propertyValue));
197 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
198 }
199
ToInt32Value(napi_env env,int32_t value)200 napi_value NapiUtil::ToInt32Value(napi_env env, int32_t value)
201 {
202 napi_value staticValue = nullptr;
203 NAPI_CALL(env, napi_create_int32(env, value, &staticValue));
204 return staticValue;
205 }
206
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)207 bool NapiUtil::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
208 {
209 bool hasProperty = false;
210 NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
211 return hasProperty;
212 }
213
HasNamedTypeProperty(napi_env env,napi_value object,napi_valuetype type,const std::string & propertyName)214 bool NapiUtil::HasNamedTypeProperty(
215 napi_env env, napi_value object, napi_valuetype type, const std::string &propertyName)
216 {
217 bool hasProperty = false;
218 NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
219 if (hasProperty) {
220 napi_value value = nullptr;
221 NAPI_CALL_BASE(env, napi_get_named_property(env, object, propertyName.data(), &value), false);
222 return MatchValueType(env, value, type);
223 }
224 return false;
225 }
226
MatchObjectProperty(napi_env env,napi_value object,std::initializer_list<std::pair<std::string,napi_valuetype>> pairList)227 bool NapiUtil::MatchObjectProperty(
228 napi_env env, napi_value object, std::initializer_list<std::pair<std::string, napi_valuetype>> pairList)
229 {
230 if (object == nullptr) {
231 return false;
232 }
233 for (auto beg = pairList.begin(); beg != pairList.end(); ++beg) {
234 if (!HasNamedTypeProperty(env, object, beg->second, beg->first)) {
235 return false;
236 }
237 }
238 return true;
239 }
240
MatchOptionPropertyType(napi_env env,napi_value object,napi_valuetype type,const std::string & propertyName)241 bool NapiUtil::MatchOptionPropertyType(
242 napi_env env, napi_value object, napi_valuetype type, const std::string &propertyName)
243 {
244 bool hasProperty = false;
245 NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
246 if (hasProperty) {
247 napi_value value = nullptr;
248 NAPI_CALL_BASE(env, napi_get_named_property(env, object, propertyName.data(), &value), false);
249 return MatchValueType(env, value, type);
250 }
251 return true;
252 }
253
GetStringFromValue(napi_env env,napi_value value)254 std::string NapiUtil::GetStringFromValue(napi_env env, napi_value value)
255 {
256 char msgChars[MAX_TEXT_LENGTH] = {0};
257 size_t msgLength = 0;
258 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, msgChars, MAX_TEXT_LENGTH, &msgLength), "");
259 TELEPHONY_LOGI("msgLength = %{public}zu", msgLength);
260 if (msgLength > 0) {
261 return std::string(msgChars, 0, msgLength);
262 } else {
263 return "";
264 }
265 }
266
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)267 napi_value NapiUtil::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
268 {
269 napi_value value = nullptr;
270 bool hasProperty = false;
271 NAPI_CALL(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty));
272 if (hasProperty) {
273 NAPI_CALL(env, napi_get_named_property(env, object, propertyName.data(), &value));
274 }
275 return value;
276 }
277
HandleAsyncWork(napi_env env,BaseContext * baseContext,const std::string & workName,napi_async_execute_callback execute,napi_async_complete_callback complete)278 napi_value NapiUtil::HandleAsyncWork(napi_env env, BaseContext *baseContext, const std::string &workName,
279 napi_async_execute_callback execute, napi_async_complete_callback complete)
280 {
281 TELEPHONY_LOGD("workName = %{public}s", workName.c_str());
282 std::unique_ptr<BaseContext> context(baseContext);
283 if (context == nullptr) {
284 ThrowParameterError(env);
285 return nullptr;
286 }
287 napi_value result = nullptr;
288 if (context->callbackRef == nullptr) {
289 NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
290 } else {
291 NAPI_CALL(env, napi_get_undefined(env, &result));
292 }
293 napi_value resource = CreateUndefined(env);
294 napi_value resourceName = nullptr;
295 NAPI_CALL(env, napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName));
296 NAPI_CALL(env,
297 napi_create_async_work(env, resource, resourceName, execute, complete, (void *)context.get(), &context->work));
298 napi_status queueWorkStatus = napi_queue_async_work_with_qos(env, context->work, napi_qos_default);
299 if (queueWorkStatus == napi_ok) {
300 context.release();
301 } else {
302 std::string errorCode = std::to_string(queueWorkStatus);
303 std::string errorMessage = "error at napi_queue_async_work_with_qos";
304 NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
305 }
306 TELEPHONY_LOGD("NapiUtil HandleAsyncWork end");
307 return result;
308 }
309
Handle1ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)310 void NapiUtil::Handle1ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
311 {
312 TELEPHONY_LOGD("Handle1ValueCallback start");
313 if (baseContext == nullptr) {
314 TELEPHONY_LOGE("Handle1ValueCallback baseContext is nullptr");
315 NapiUtil::ThrowParameterError(env);
316 return;
317 }
318 if (baseContext->callbackRef != nullptr) {
319 TELEPHONY_LOGI("start normal callback");
320 napi_value recv = CreateUndefined(env);
321 napi_value callbackFunc = nullptr;
322 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
323 napi_value callbackValues[] = {callbackValue};
324 napi_value result = nullptr;
325 NAPI_CALL_RETURN_VOID(
326 env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
327 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
328 TELEPHONY_LOGD("normal callback end");
329 } else if (baseContext->deferred != nullptr) {
330 TELEPHONY_LOGI("start promise callback");
331 if (baseContext->resolved) {
332 NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
333 TELEPHONY_LOGI("napi_resolve_deferred end");
334 } else {
335 NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
336 TELEPHONY_LOGI("napi_reject_deferred end");
337 }
338 TELEPHONY_LOGD("promise callback end");
339 }
340 napi_delete_async_work(env, baseContext->work);
341 delete baseContext;
342 baseContext = nullptr;
343 TELEPHONY_LOGD("end");
344 }
345
Handle2ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)346 void NapiUtil::Handle2ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
347 {
348 TELEPHONY_LOGD("Handle2ValueCallback start");
349 if (baseContext == nullptr) {
350 TELEPHONY_LOGI("Handle2ValueCallback serious error baseContext nullptr");
351 ThrowParameterError(env);
352 return;
353 }
354 if (baseContext->callbackRef != nullptr) {
355 TELEPHONY_LOGD("Handle2ValueCallback start normal callback");
356 napi_value recv = CreateUndefined(env);
357 napi_value callbackFunc = nullptr;
358 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
359 napi_value callbackValues[] = {nullptr, nullptr};
360 callbackValues[0] = baseContext->resolved ? CreateUndefined(env) : callbackValue;
361 callbackValues[1] = baseContext->resolved ? callbackValue : CreateUndefined(env);
362 napi_value result = nullptr;
363 NAPI_CALL_RETURN_VOID(
364 env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
365 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
366 TELEPHONY_LOGD("Handle2ValueCallback normal callback end");
367 } else if (baseContext->deferred != nullptr) {
368 TELEPHONY_LOGD("Handle2ValueCallback start promise callback");
369 if (baseContext->resolved) {
370 NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
371 } else {
372 NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
373 }
374 TELEPHONY_LOGD("Handle2ValueCallback promise callback end");
375 }
376 napi_delete_async_work(env, baseContext->work);
377 delete baseContext;
378 baseContext = nullptr;
379 TELEPHONY_LOGD("Handle2ValueCallback end");
380 }
381
DefineEnumClassByName(napi_env env,napi_value exports,std::string_view enumName,size_t arrSize,const napi_property_descriptor * desc)382 void NapiUtil::DefineEnumClassByName(
383 napi_env env, napi_value exports, std::string_view enumName, size_t arrSize, const napi_property_descriptor *desc)
384 {
385 auto construct = [](napi_env env, napi_callback_info info) -> napi_value { return nullptr; };
386 napi_value result = nullptr;
387 napi_status status =
388 napi_define_class(env, enumName.data(), NAPI_AUTO_LENGTH, construct, nullptr, arrSize, desc, &result);
389 if (status != napi_ok) {
390 TELEPHONY_LOGE("DefineEnumClassByName napi_define_class failed ret = %d", status);
391 }
392 status = napi_set_named_property(env, exports, enumName.data(), result);
393 if (status != napi_ok) {
394 TELEPHONY_LOGE("DefineEnumClassByName napi_set_named_property failed ret = %d", status);
395 }
396 }
397
ConverErrorMessageForJs(int32_t errorCode)398 JsError NapiUtil::ConverErrorMessageForJs(int32_t errorCode)
399 {
400 JsError error = {};
401 if (errorCode == TELEPHONY_ERR_SUCCESS) {
402 error.errorCode = JS_ERROR_TELEPHONY_SUCCESS;
403 error.errorMessage = GetErrorMessage(JS_ERROR_TELEPHONY_SUCCESS);
404 return error;
405 }
406
407 if (CreateParameterErrorMessageForJs(errorCode, error.errorCode)) {
408 error.errorMessage = GetErrorMessage(error.errorCode);
409 return error;
410 }
411
412 if (!CreateCommonErrorMessageForJs(errorCode, error.errorCode) &&
413 !CreateCallErrorMessageForJs(errorCode, error.errorCode) &&
414 !CreateDataErrorMessageForJs(errorCode, error.errorCode) &&
415 !CreateNetworkSearchErrorMessageForJs(errorCode, error.errorCode) &&
416 !CreateVcardErrorMessageForJs(errorCode, error.errorCode) &&
417 !CreateSimErrorMessageForJs(errorCode, error.errorCode) &&
418 !CreateSmsErrorMessageForJs(errorCode, error.errorCode) &&
419 !CreateObserverErrorMessageForJs(errorCode, error.errorCode)) {
420 error.errorCode = JS_ERROR_TELEPHONY_UNKNOW_ERROR;
421 TELEPHONY_LOGE("NapiUtil::ConverErrorMessageForJs errorCode is out of range");
422 }
423 error.errorMessage = GetErrorMessage(error.errorCode);
424 TELEPHONY_LOGI("errorCode from %{public}d to %{public}d", errorCode, error.errorCode);
425 return error;
426 }
427
CreateParameterErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)428 bool NapiUtil::CreateParameterErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
429 {
430 bool flag = true;
431 switch (errorCode) {
432 case ERROR_SERVICE_UNAVAILABLE:
433 case ERROR_NATIVE_API_EXECUTE_FAIL:
434 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
435 break;
436 case ERROR_PARAMETER_COUNTS_INVALID:
437 case ERROR_PARAMETER_TYPE_INVALID:
438 case napi_status::napi_generic_failure:
439 case napi_status::napi_invalid_arg:
440 jsErrorCode = JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER;
441 break;
442 case ERROR_SLOT_ID_INVALID:
443 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
444 break;
445 default:
446 flag = false;
447 break;
448 }
449
450 return flag;
451 }
452
CreateNetworkSearchErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)453 bool NapiUtil::CreateNetworkSearchErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
454 {
455 if ((errorCode < CORE_SERVICE_NETWORK_SEARCH_ERR_OFFSET || errorCode >= CORE_SERVICE_CORE_ERR_OFFSET)) {
456 return false;
457 }
458 bool flag = true;
459 switch (errorCode) {
460 case CORE_SERVICE_SEND_CALLBACK_FAILED:
461 case CORE_SERVICE_RADIO_PROTOCOL_TECH_UNKNOWN:
462 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
463 break;
464 default:
465 flag = false;
466 break;
467 }
468
469 return flag;
470 }
471
CreateVcardErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)472 bool NapiUtil::CreateVcardErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
473 {
474 bool flag = true;
475 switch (errorCode) {
476 case TELEPHONY_ERR_VCARD_FILE_INVALID:
477 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
478 break;
479 default:
480 flag = false;
481 break;
482 }
483
484 return flag;
485 }
486
CreateSimErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)487 bool NapiUtil::CreateSimErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
488 {
489 if ((errorCode < CORE_SERVICE_SIM_ERR_OFFSET || errorCode >= CORE_SERVICE_NETWORK_SEARCH_ERR_OFFSET)) {
490 return false;
491 }
492 bool flag = true;
493 switch (errorCode) {
494 case CORE_SERVICE_SIM_CARD_IS_NOT_ACTIVE:
495 jsErrorCode = JS_ERROR_SIM_CARD_IS_NOT_ACTIVE;
496 break;
497 case CORE_ERR_SIM_CARD_LOAD_FAILED:
498 case CORE_ERR_SIM_CARD_UPDATE_FAILED:
499 jsErrorCode = JS_ERROR_SIM_CARD_OPERATION_ERROR;
500 break;
501 case CORE_ERR_OPERATOR_KEY_NOT_EXIT:
502 case CORE_ERR_OPERATOR_CONF_NOT_EXIT:
503 jsErrorCode = JS_ERROR_OPERATOR_CONFIG_ERROR;
504 break;
505 default:
506 flag = false;
507 break;
508 }
509
510 return flag;
511 }
512
CreateSmsErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)513 bool NapiUtil::CreateSmsErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
514 {
515 if ((errorCode < SMS_MMS_ERR_OFFSET || errorCode >= STATE_REGISTRY_ERR_OFFSET)) {
516 return false;
517 }
518 bool flag = true;
519 switch (errorCode) {
520 case TELEPHONY_SMS_MMS_DECODE_DATA_EMPTY:
521 case TELEPHONY_SMS_MMS_UNKNOWN_SIM_MESSAGE_STATUS:
522 case TELEPHONY_SMS_MMS_MESSAGE_LENGTH_OUT_OF_RANGE:
523 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
524 break;
525 default:
526 flag = false;
527 break;
528 }
529
530 return flag;
531 }
532
CreateObserverErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)533 bool NapiUtil::CreateObserverErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
534 {
535 if ((errorCode < STATE_REGISTRY_ERR_OFFSET || errorCode >= NET_MANAGER_ERR_OFFSET)) {
536 return false;
537 }
538 bool flag = true;
539 switch (errorCode) {
540 case TELEPHONY_STATE_REGISTRY_SLODID_ERROR:
541 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
542 break;
543 case TELEPHONY_STATE_REGISTRY_PERMISSION_DENIED:
544 jsErrorCode = JS_ERROR_TELEPHONY_PERMISSION_DENIED;
545 break;
546 case TELEPHONY_STATE_REGISTRY_DATA_NOT_EXIST:
547 case TELEPHONY_STATE_UNREGISTRY_DATA_NOT_EXIST:
548 case TELEPHONY_STATE_REGISTRY_DATA_EXIST:
549 case TELEPHONY_STATE_REGISTRY_NOT_IMPLEMENTED:
550 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
551 break;
552 default:
553 flag = false;
554 break;
555 }
556
557 return flag;
558 }
559
CreateCommonErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)560 bool NapiUtil::CreateCommonErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
561 {
562 if ((errorCode < COMMON_ERR_OFFSET || errorCode >= CALL_ERR_OFFSET)) {
563 return false;
564 }
565 if (CreateCommonArgumentErrorMessageForJs(errorCode, jsErrorCode) ||
566 CreateCommonServiceErrorMessageForJs(errorCode, jsErrorCode) ||
567 CreateCommonSystemErrorMessageForJs(errorCode, jsErrorCode)) {
568 return true;
569 }
570 return false;
571 }
572
CreateCommonArgumentErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)573 bool NapiUtil::CreateCommonArgumentErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
574 {
575 bool flag = true;
576
577 switch (errorCode) {
578 case TELEPHONY_ERR_ARGUMENT_MISMATCH:
579 case TELEPHONY_ERR_ARGUMENT_INVALID:
580 case TELEPHONY_ERR_ARGUMENT_NULL:
581 case TELEPHONY_ERR_SLOTID_INVALID:
582 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
583 break;
584 default:
585 flag = false;
586 break;
587 }
588 return flag;
589 }
590
CreateCommonServiceErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)591 bool NapiUtil::CreateCommonServiceErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
592 {
593 bool flag = true;
594
595 switch (errorCode) {
596 case TELEPHONY_ERR_DESCRIPTOR_MISMATCH:
597 case TELEPHONY_ERR_WRITE_DESCRIPTOR_TOKEN_FAIL:
598 case TELEPHONY_ERR_WRITE_DATA_FAIL:
599 case TELEPHONY_ERR_WRITE_REPLY_FAIL:
600 case TELEPHONY_ERR_READ_DATA_FAIL:
601 case TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL:
602 case TELEPHONY_ERR_REGISTER_CALLBACK_FAIL:
603 case TELEPHONY_ERR_CALLBACK_ALREADY_REGISTERED:
604 case TELEPHONY_ERR_UNINIT:
605 case TELEPHONY_ERR_UNREGISTER_CALLBACK_FAIL:
606 jsErrorCode = JS_ERROR_TELEPHONY_SERVICE_ERROR;
607 break;
608 default:
609 flag = false;
610 break;
611 }
612 return flag;
613 }
614
CreateCommonSystemErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)615 bool NapiUtil::CreateCommonSystemErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
616 {
617 bool flag = true;
618
619 switch (errorCode) {
620 case TELEPHONY_ERR_FAIL:
621 case TELEPHONY_ERR_MEMCPY_FAIL:
622 case TELEPHONY_ERR_MEMSET_FAIL:
623 case TELEPHONY_ERR_STRCPY_FAIL:
624 case TELEPHONY_ERR_LOCAL_PTR_NULL:
625 case TELEPHONY_ERR_SUBSCRIBE_BROADCAST_FAIL:
626 case TELEPHONY_ERR_PUBLISH_BROADCAST_FAIL:
627 case TELEPHONY_ERR_ADD_DEATH_RECIPIENT_FAIL:
628 case TELEPHONY_ERR_STRTOINT_FAIL:
629 case TELEPHONY_ERR_RIL_CMD_FAIL:
630 case TELEPHONY_ERR_DATABASE_WRITE_FAIL:
631 case TELEPHONY_ERR_DATABASE_READ_FAIL:
632 case TELEPHONY_ERR_UNKNOWN_NETWORK_TYPE:
633 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
634 break;
635 case TELEPHONY_ERR_NO_SIM_CARD:
636 jsErrorCode = JS_ERROR_TELEPHONY_NO_SIM_CARD;
637 break;
638 case TELEPHONY_ERR_ILLEGAL_USE_OF_SYSTEM_API:
639 jsErrorCode = JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API;
640 break;
641 case TELEPHONY_ERR_AIRPLANE_MODE_ON:
642 jsErrorCode = JS_ERROR_TELEPHONY_AIRPLANE_MODE_ON;
643 break;
644 case TELEPHONY_ERR_NETWORK_NOT_IN_SERVICE:
645 jsErrorCode = JS_ERROR_TELEPHONY_NETWORK_NOT_IN_SERVICE;
646 break;
647 default:
648 flag = false;
649 break;
650 }
651 return flag;
652 }
653
CreateCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)654 bool NapiUtil::CreateCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
655 {
656 if ((errorCode < CALL_ERR_OFFSET || errorCode >= CELLULAR_DATA_ERR_OFFSET)) {
657 return false;
658 }
659 if (CreateCommonCallErrorMessageForJs(errorCode, jsErrorCode) ||
660 CreateVideoCallErrorMessageForJs(errorCode, jsErrorCode) ||
661 CreateSupplementServiceCallErrorMessageForJs(errorCode, jsErrorCode)) {
662 return true;
663 }
664 return false;
665 }
666
CreateCommonCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)667 bool NapiUtil::CreateCommonCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
668 {
669 bool flag = true;
670
671 switch (errorCode) {
672 case TELEPHONY_CALL_ERR_NUMBER_OUT_OF_RANGE:
673 case TELEPHONY_CALL_ERR_PHONE_NUMBER_EMPTY:
674 case TELEPHONY_CALL_ERR_FORMAT_PHONE_NUMBER_FAILED:
675 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
676 break;
677 case TELEPHONY_CALL_ERR_PARAMETER_OUT_OF_RANGE:
678 case TELEPHONY_CALL_ERR_INVALID_SLOT_ID:
679 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
680 break;
681 case TELEPHONY_CALL_ERR_CONFERENCE_CALL_EXCEED_LIMIT:
682 jsErrorCode = JS_ERROR_TELEPHONY_CONFERENCE_EXCEED_LIMIT;
683 break;
684 case TELEPHONY_CALL_ERR_CONFERENCE_CALL_IS_NOT_ACTIVE:
685 jsErrorCode = JS_ERROR_TELEPHONY_CONFERENCE_CALL_NOT_ACTIVE;
686 break;
687 case TELEPHONY_CALL_ERR_CALL_COUNTS_EXCEED_LIMIT:
688 jsErrorCode = JS_ERROR_TELEPHONY_CALL_COUNTS_EXCEED_LIMIT;
689 break;
690 case TELEPHONY_CALL_ERR_CALL_IS_NOT_ACTIVATED:
691 case TELEPHONY_CALL_ERR_ILLEGAL_CALL_OPERATION:
692 case TELEPHONY_CALL_ERR_AUDIO_SETTING_MUTE_FAILED:
693 case TELEPHONY_CALL_ERR_CALL_IS_NOT_ON_HOLDING:
694 case TELEPHONY_CALL_ERR_PHONE_CALLS_TOO_FEW:
695 case TELEPHONY_CALL_ERR_VIDEO_ILLEGAL_CALL_TYPE:
696 case TELEPHONY_CALL_ERR_CONFERENCE_NOT_EXISTS:
697 case TELEPHONY_CALL_ERR_CONFERENCE_SEPERATE_FAILED:
698 case TELEPHONY_CALL_ERR_EMERGENCY_UNSUPPORT_CONFERENCEABLE:
699 case TELEPHONY_CALL_ERR_VOLTE_NOT_SUPPORT:
700 case TELEPHONY_CALL_ERR_VOLTE_PROVISIONING_DISABLED:
701 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
702 break;
703 case TELEPHONY_CALL_ERR_DIAL_IS_BUSY:
704 jsErrorCode = JS_ERROR_TELEPHONY_DIAL_IS_BUSY;
705 break;
706 default:
707 flag = false;
708 break;
709 }
710 return flag;
711 }
712
CreateVideoCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)713 bool NapiUtil::CreateVideoCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
714 {
715 bool flag = true;
716
717 switch (errorCode) {
718 case TELEPHONY_CALL_ERR_VIDEO_ILLEGAL_MEDIA_TYPE:
719 case TELEPHONY_CALL_ERR_VIDEO_IN_PROGRESS:
720 case TELEPHONY_CALL_ERR_VIDEO_ILLEAGAL_SCENARIO:
721 case TELEPHONY_CALL_ERR_VIDEO_MODE_CHANGE_NOTIFY_FAILED:
722 case TELEPHONY_CALL_ERR_VIDEO_NOT_SUPPORTED:
723 case TELEPHONY_CALL_ERR_SETTING_AUDIO_DEVICE_FAILED:
724 case TELEPHONY_CALL_ERR_VIDEO_INVALID_COORDINATES:
725 case TELEPHONY_CALL_ERR_VIDEO_INVALID_ZOOM:
726 case TELEPHONY_CALL_ERR_VIDEO_INVALID_ROTATION:
727 case TELEPHONY_CALL_ERR_VIDEO_INVALID_CAMERA_ID:
728 case TELEPHONY_CALL_ERR_INVALID_PATH:
729 case TELEPHONY_CALL_ERR_CAMERA_NOT_TURNED_ON:
730 case TELEPHONY_CALL_ERR_INVALID_DIAL_SCENE:
731 case TELEPHONY_CALL_ERR_INVALID_VIDEO_STATE:
732 case TELEPHONY_CALL_ERR_UNKNOW_DIAL_TYPE:
733 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
734 break;
735 default:
736 flag = false;
737 break;
738 }
739 return flag;
740 }
741
CreateSupplementServiceCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)742 bool NapiUtil::CreateSupplementServiceCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
743 {
744 bool flag = true;
745
746 switch (errorCode) {
747 case TELEPHONY_CALL_ERR_INVALID_RESTRICTION_TYPE:
748 case TELEPHONY_CALL_ERR_INVALID_RESTRICTION_MODE:
749 case TELEPHONY_CALL_ERR_INVALID_TRANSFER_TYPE:
750 case TELEPHONY_CALL_ERR_INVALID_TRANSFER_SETTING_TYPE:
751 jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
752 break;
753 case TELEPHONY_CALL_ERR_FUNCTION_NOT_SUPPORTED:
754 jsErrorCode = JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API;
755 break;
756 case TELEPHONY_CALL_ERR_INVALID_TRANSFER_TIME:
757 case TELEPHONY_CALL_ERR_NAPI_INTERFACE_FAILED:
758 case TELEPHONY_CALL_ERR_CALLBACK_ALREADY_EXIST:
759 case TELEPHONY_CALL_ERR_RESOURCE_UNAVAILABLE:
760 jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
761 break;
762 case TELEPHONY_CALL_ERR_UT_NO_CONNECTION:
763 jsErrorCode = JS_ERROR_CALL_UT_NO_CONNECTION;
764 break;
765 default:
766 flag = false;
767 break;
768 }
769 return flag;
770 }
771
CreateDataErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)772 bool NapiUtil::CreateDataErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
773 {
774 if ((errorCode < CELLULAR_DATA_ERR_OFFSET || errorCode >= SMS_MMS_ERR_OFFSET)) {
775 return false;
776 }
777 bool flag = true;
778
779 switch (errorCode) {
780 case TELEPHONY_CELLULAR_DATA_INVALID_PARAM:
781 jsErrorCode = JS_ERROR_CELLULAR_DATA_BASE_ERROR;
782 break;
783 default:
784 flag = false;
785 break;
786 }
787 return flag;
788 }
789
ConverErrorMessageWithPermissionForJs(int32_t errorCode,const std::string & funcName,const std::string & permission)790 JsError NapiUtil::ConverErrorMessageWithPermissionForJs(
791 int32_t errorCode, const std::string &funcName, const std::string &permission)
792 {
793 if (errorCode == TELEPHONY_ERR_PERMISSION_ERR) {
794 JsError error = {};
795 error.errorCode = JS_ERROR_TELEPHONY_PERMISSION_DENIED;
796 error.errorMessage = "BusinessError 201: Permission denied. An attempt was made to " + funcName +
797 " forbidden by permission: " + permission;
798 return error;
799 }
800 return ConverErrorMessageForJs(errorCode);
801 }
802
CreateError(napi_env env,int32_t err,const std::string & msg)803 napi_value NapiUtil::CreateError(napi_env env, int32_t err, const std::string &msg)
804 {
805 napi_value businessError = nullptr;
806 napi_value errorCode = nullptr;
807 NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
808 napi_value errorMessage = nullptr;
809 NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
810 napi_create_error(env, nullptr, errorMessage, &businessError);
811 napi_set_named_property(env, businessError, "code", errorCode);
812 return businessError;
813 }
814
ThrowError(napi_env env,int32_t errorCode,const std::string & message)815 void NapiUtil::ThrowError(napi_env env, int32_t errorCode, const std::string &message)
816 {
817 napi_value error = CreateError(env, errorCode, message);
818 napi_throw(env, error);
819 }
820
ThrowParameterError(napi_env env)821 void NapiUtil::ThrowParameterError(napi_env env)
822 {
823 ThrowError(
824 env, JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER, GetErrorMessage(JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER));
825 }
826 } // namespace Telephony
827 } // namespace OHOS
828