• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
59 static std::unordered_map<int32_t, const char *> errorMap_ = {
60     { JsErrorCode::JS_ERROR_TELEPHONY_PERMISSION_DENIED, JS_ERROR_TELEPHONY_PERMISSION_DENIED_STRING },
61     { JsErrorCode::JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API, JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API_STRING },
62     { JsErrorCode::JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER, JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER_STRING },
63     { JsErrorCode::JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API, JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API_STRING },
64     { JsErrorCode::JS_ERROR_TELEPHONY_SUCCESS, JS_ERROR_TELEPHONY_SUCCESS_STRING },
65     { JsErrorCode::JS_ERROR_TELEPHONY_ARGUMENT_ERROR, JS_ERROR_TELEPHONY_ARGUMENT_ERROR_STRING },
66     { JsErrorCode::JS_ERROR_TELEPHONY_SERVICE_ERROR, JS_ERROR_TELEPHONY_SERVICE_ERROR_STRING },
67     { JsErrorCode::JS_ERROR_TELEPHONY_SYSTEM_ERROR, JS_ERROR_TELEPHONY_SYSTEM_ERROR_STRING },
68     { JsErrorCode::JS_ERROR_TELEPHONY_NO_SIM_CARD, JS_ERROR_TELEPHONY_NO_SIM_CARD_STRING },
69     { JsErrorCode::JS_ERROR_TELEPHONY_UNKNOW_ERROR, JS_ERROR_TELEPHONY_UNKNOW_ERROR_STRING },
70     { JsErrorCode::JS_ERROR_SIM_BASE_ERROR, JS_ERROR_SIM_BASE_ERROR_STRING },
71     { JsErrorCode::JS_ERROR_SIM_CARD_IS_NOT_ACTIVE, JS_ERROR_SIM_CARD_IS_NOT_ACTIVE_STRING },
72     { JsErrorCode::JS_ERROR_SIM_CARD_OPERATION_ERROR, JS_ERROR_SIM_CARD_OPERATION_ERROR_STRING },
73     { JsErrorCode::JS_ERROR_OPERATOR_CONFIG_ERROR, JS_ERROR_OPERATOR_CONFIG_ERROR_STRING },
74     { JsErrorCode::JS_ERROR_NETWORK_SEARCH_BASE_ERROR, JS_ERROR_NETWORK_SEARCH_BASE_ERROR_STRING },
75     { JsErrorCode::JS_ERROR_CALL_MANAGER_BASE_ERROR, JS_ERROR_CALL_MANAGER_BASE_ERROR_STRING },
76     { JsErrorCode::JS_ERROR_CELLULAR_CALL_CS_BASE_ERROR, JS_ERROR_CELLULAR_CALL_CS_BASE_ERROR_STRING },
77     { JsErrorCode::JS_ERROR_CELLULAR_CALL_IMS_BASE_ERROR, JS_ERROR_CELLULAR_CALL_IMS_BASE_ERROR_STRING },
78     { JsErrorCode::JS_ERROR_CELLULAR_DATA_BASE_ERROR, JS_ERROR_CELLULAR_DATA_BASE_ERROR_STRING },
79     { JsErrorCode::JS_ERROR_SMS_MMS_BASE_ERROR, JS_ERROR_SMS_MMS_BASE_ERROR_STRING },
80     { JsErrorCode::JS_ERROR_STATE_REGISTRY_BASE_ERROR, JS_ERROR_STATE_REGISTRY_BASE_ERROR_STRING },
81     { JsErrorCode::JS_ERROR_TELEPHONY_AIRPLANE_MODE_ON, JS_ERROR_AIRPLANE_MODE_ON_STRING },
82     { JsErrorCode::JS_ERROR_TELEPHONY_NETWORK_NOT_IN_SERVICE, JS_ERROR_NETWORK_NOT_IN_SERVICE }
83 };
84 
GetErrorMessage(int32_t errorCode)85 std::string NapiUtil::GetErrorMessage(int32_t errorCode)
86 {
87     std::string result = "";
88     auto iter = errorMap_.find(errorCode);
89     if (iter == errorMap_.end()) {
90         TELEPHONY_LOGE("NapiUtil::GetErrorMessage return null.");
91         return result;
92     }
93     TELEPHONY_LOGD("NapiUtil::GetErrorMessage errorCode %{public}d, message = %{public}s", errorCode, iter->second);
94     result = iter->second;
95     return result;
96 }
97 
ToUtf8(std::u16string str16)98 std::string NapiUtil::ToUtf8(std::u16string str16)
99 {
100     return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(str16);
101 }
102 
ToUtf16(std::string str)103 std::u16string NapiUtil::ToUtf16(std::string str)
104 {
105     return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(str);
106 }
107 
CreateErrorMessage(napi_env env,const std::string & msg,int32_t errorCode)108 napi_value NapiUtil::CreateErrorMessage(napi_env env, const std::string &msg, int32_t errorCode)
109 {
110     napi_value result = nullptr;
111     napi_value message = nullptr;
112     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.length(), &message));
113     napi_value codeValue = nullptr;
114     NAPI_CALL(env, napi_create_int32(env, errorCode, &codeValue));
115     NAPI_CALL(env, napi_create_object(env, &result));
116     NAPI_CALL(env, napi_set_named_property(env, result, "code", codeValue));
117     NAPI_CALL(env, napi_set_named_property(env, result, "message", message));
118     return result;
119 }
120 
CreateUndefined(napi_env env)121 napi_value NapiUtil::CreateUndefined(napi_env env)
122 {
123     napi_value result = nullptr;
124     NAPI_CALL(env, napi_get_undefined(env, &result));
125     return result;
126 }
127 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)128 bool NapiUtil::MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
129 {
130     napi_valuetype valueType = napi_undefined;
131     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
132     return valueType == targetType;
133 }
134 
MatchParameters(napi_env env,const napi_value parameters[],std::initializer_list<napi_valuetype> valueTypes)135 bool NapiUtil::MatchParameters(
136     napi_env env, const napi_value parameters[], std::initializer_list<napi_valuetype> valueTypes)
137 {
138     if (parameters == nullptr) {
139         return false;
140     }
141     int i = 0;
142     for (auto beg = valueTypes.begin(); beg != valueTypes.end(); ++beg) {
143         if (!MatchValueType(env, parameters[i], *beg)) {
144             return false;
145         }
146         ++i;
147     }
148     return true;
149 }
150 
SetPropertyInt32(napi_env env,napi_value object,const std::string & name,int32_t value)151 void NapiUtil::SetPropertyInt32(napi_env env, napi_value object, const std::string &name, int32_t value)
152 {
153     napi_value propertyValue = nullptr;
154     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, value, &propertyValue));
155     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
156 }
157 
SetPropertyInt64(napi_env env,napi_value object,const std::string & name,int64_t value)158 void NapiUtil::SetPropertyInt64(napi_env env, napi_value object, const std::string &name, int64_t value)
159 {
160     napi_value propertyValue = nullptr;
161     NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, value, &propertyValue));
162     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
163 }
164 
SetPropertyStringUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)165 void NapiUtil::SetPropertyStringUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
166 {
167     napi_value propertyValue = nullptr;
168     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, value.c_str(), value.length(), &propertyValue));
169     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
170 }
171 
SetPropertyBoolean(napi_env env,napi_value object,const std::string & name,bool value)172 void NapiUtil::SetPropertyBoolean(napi_env env, napi_value object, const std::string &name, bool value)
173 {
174     napi_value propertyValue = nullptr;
175     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &propertyValue));
176     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), propertyValue));
177 }
178 
ToInt32Value(napi_env env,int32_t value)179 napi_value NapiUtil::ToInt32Value(napi_env env, int32_t value)
180 {
181     napi_value staticValue = nullptr;
182     NAPI_CALL(env, napi_create_int32(env, value, &staticValue));
183     return staticValue;
184 }
185 
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)186 bool NapiUtil::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
187 {
188     bool hasProperty = false;
189     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
190     return hasProperty;
191 }
192 
HasNamedTypeProperty(napi_env env,napi_value object,napi_valuetype type,const std::string & propertyName)193 bool NapiUtil::HasNamedTypeProperty(
194     napi_env env, napi_value object, napi_valuetype type, const std::string &propertyName)
195 {
196     bool hasProperty = false;
197     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
198     if (hasProperty) {
199         napi_value value = nullptr;
200         NAPI_CALL_BASE(env, napi_get_named_property(env, object, propertyName.data(), &value), false);
201         return MatchValueType(env, value, type);
202     }
203     return false;
204 }
205 
MatchObjectProperty(napi_env env,napi_value object,std::initializer_list<std::pair<std::string,napi_valuetype>> pairList)206 bool NapiUtil::MatchObjectProperty(
207     napi_env env, napi_value object, std::initializer_list<std::pair<std::string, napi_valuetype>> pairList)
208 {
209     if (object == nullptr) {
210         return false;
211     }
212     for (auto beg = pairList.begin(); beg != pairList.end(); ++beg) {
213         if (!HasNamedTypeProperty(env, object, beg->second, beg->first)) {
214             return false;
215         }
216     }
217     return true;
218 }
219 
MatchOptionPropertyType(napi_env env,napi_value object,napi_valuetype type,const std::string & propertyName)220 bool NapiUtil::MatchOptionPropertyType(
221     napi_env env, napi_value object, napi_valuetype type, const std::string &propertyName)
222 {
223     bool hasProperty = false;
224     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty), false);
225     if (hasProperty) {
226         napi_value value = nullptr;
227         NAPI_CALL_BASE(env, napi_get_named_property(env, object, propertyName.data(), &value), false);
228         return MatchValueType(env, value, type);
229     }
230     return true;
231 }
232 
GetStringFromValue(napi_env env,napi_value value)233 std::string NapiUtil::GetStringFromValue(napi_env env, napi_value value)
234 {
235     char msgChars[MAX_TEXT_LENGTH] = {0};
236     size_t msgLength = 0;
237     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, msgChars, MAX_TEXT_LENGTH, &msgLength), "");
238     TELEPHONY_LOGI("msgLength = %{public}zu", msgLength);
239     if (msgLength > 0) {
240         return std::string(msgChars, 0, msgLength);
241     } else {
242         return "";
243     }
244 }
245 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)246 napi_value NapiUtil::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
247 {
248     napi_value value = nullptr;
249     bool hasProperty = false;
250     NAPI_CALL(env, napi_has_named_property(env, object, propertyName.data(), &hasProperty));
251     if (hasProperty) {
252         NAPI_CALL(env, napi_get_named_property(env, object, propertyName.data(), &value));
253     }
254     return value;
255 }
256 
HandleAsyncWork(napi_env env,BaseContext * baseContext,const std::string & workName,napi_async_execute_callback execute,napi_async_complete_callback complete)257 napi_value NapiUtil::HandleAsyncWork(napi_env env, BaseContext *baseContext, const std::string &workName,
258     napi_async_execute_callback execute, napi_async_complete_callback complete)
259 {
260     TELEPHONY_LOGD("workName = %{public}s", workName.c_str());
261     std::unique_ptr<BaseContext> context(baseContext);
262     if (context == nullptr) {
263         ThrowParameterError(env);
264         return nullptr;
265     }
266     napi_value result = nullptr;
267     if (context->callbackRef == nullptr) {
268         NAPI_CALL(env, napi_create_promise(env, &context->deferred, &result));
269     } else {
270         NAPI_CALL(env, napi_get_undefined(env, &result));
271     }
272     napi_value resource = CreateUndefined(env);
273     napi_value resourceName = nullptr;
274     NAPI_CALL(env, napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName));
275     NAPI_CALL(env,
276         napi_create_async_work(env, resource, resourceName, execute, complete, (void *)context.get(), &context->work));
277     napi_status queueWorkStatus = napi_queue_async_work_with_qos(env, context->work, napi_qos_default);
278     if (queueWorkStatus == napi_ok) {
279         context.release();
280     } else {
281         std::string errorCode = std::to_string(queueWorkStatus);
282         std::string errorMessage = "error at napi_queue_async_work_with_qos";
283         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
284     }
285     TELEPHONY_LOGD("NapiUtil HandleAsyncWork end");
286     return result;
287 }
288 
Handle1ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)289 void NapiUtil::Handle1ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
290 {
291     TELEPHONY_LOGD("Handle1ValueCallback start");
292     if (baseContext == nullptr) {
293         TELEPHONY_LOGE("Handle1ValueCallback baseContext is nullptr");
294         NapiUtil::ThrowParameterError(env);
295         return;
296     }
297     if (baseContext->callbackRef != nullptr) {
298         TELEPHONY_LOGI("start normal callback");
299         napi_value recv = CreateUndefined(env);
300         napi_value callbackFunc = nullptr;
301         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
302         napi_value callbackValues[] = {callbackValue};
303         napi_value result = nullptr;
304         NAPI_CALL_RETURN_VOID(
305             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
306         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
307         TELEPHONY_LOGD("normal callback end");
308     } else if (baseContext->deferred != nullptr) {
309         TELEPHONY_LOGI("start promise callback");
310         if (baseContext->resolved) {
311             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
312             TELEPHONY_LOGI("napi_resolve_deferred end");
313         } else {
314             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
315             TELEPHONY_LOGI("napi_reject_deferred end");
316         }
317         TELEPHONY_LOGD("promise callback end");
318     }
319     napi_delete_async_work(env, baseContext->work);
320     delete baseContext;
321     baseContext = nullptr;
322     TELEPHONY_LOGD("end");
323 }
324 
Handle2ValueCallback(napi_env env,BaseContext * baseContext,napi_value callbackValue)325 void NapiUtil::Handle2ValueCallback(napi_env env, BaseContext *baseContext, napi_value callbackValue)
326 {
327     TELEPHONY_LOGD("Handle2ValueCallback start");
328     if (baseContext == nullptr) {
329         TELEPHONY_LOGI("Handle2ValueCallback serious error baseContext nullptr");
330         ThrowParameterError(env);
331         return;
332     }
333     if (baseContext->callbackRef != nullptr) {
334         TELEPHONY_LOGD("Handle2ValueCallback start normal callback");
335         napi_value recv = CreateUndefined(env);
336         napi_value callbackFunc = nullptr;
337         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, baseContext->callbackRef, &callbackFunc));
338         napi_value callbackValues[] = {nullptr, nullptr};
339         callbackValues[0] = baseContext->resolved ? CreateUndefined(env) : callbackValue;
340         callbackValues[1] = baseContext->resolved ? callbackValue : CreateUndefined(env);
341         napi_value result = nullptr;
342         NAPI_CALL_RETURN_VOID(
343             env, napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &result));
344         NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, baseContext->callbackRef));
345         TELEPHONY_LOGD("Handle2ValueCallback normal callback end");
346     } else if (baseContext->deferred != nullptr) {
347         TELEPHONY_LOGD("Handle2ValueCallback start promise callback");
348         if (baseContext->resolved) {
349             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, baseContext->deferred, callbackValue));
350         } else {
351             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, baseContext->deferred, callbackValue));
352         }
353         TELEPHONY_LOGD("Handle2ValueCallback promise callback end");
354     }
355     napi_delete_async_work(env, baseContext->work);
356     delete baseContext;
357     baseContext = nullptr;
358     TELEPHONY_LOGD("Handle2ValueCallback end");
359 }
360 
DefineEnumClassByName(napi_env env,napi_value exports,std::string_view enumName,size_t arrSize,const napi_property_descriptor * desc)361 void NapiUtil::DefineEnumClassByName(
362     napi_env env, napi_value exports, std::string_view enumName, size_t arrSize, const napi_property_descriptor *desc)
363 {
364     auto construct = [](napi_env env, napi_callback_info info) -> napi_value { return nullptr; };
365     napi_value result = nullptr;
366     napi_status status =
367         napi_define_class(env, enumName.data(), NAPI_AUTO_LENGTH, construct, nullptr, arrSize, desc, &result);
368     if (status != napi_ok) {
369         TELEPHONY_LOGE("DefineEnumClassByName napi_define_class failed ret = %d", status);
370     }
371     status = napi_set_named_property(env, exports, enumName.data(), result);
372     if (status != napi_ok) {
373         TELEPHONY_LOGE("DefineEnumClassByName napi_set_named_property failed ret = %d", status);
374     }
375 }
376 
ConverErrorMessageForJs(int32_t errorCode)377 JsError NapiUtil::ConverErrorMessageForJs(int32_t errorCode)
378 {
379     JsError error = {};
380     if (errorCode == TELEPHONY_ERR_SUCCESS) {
381         error.errorCode = JS_ERROR_TELEPHONY_SUCCESS;
382         error.errorMessage = GetErrorMessage(JS_ERROR_TELEPHONY_SUCCESS);
383         return error;
384     }
385 
386     if (CreateParameterErrorMessageForJs(errorCode, error.errorCode)) {
387         error.errorMessage = GetErrorMessage(error.errorCode);
388         return error;
389     }
390 
391     if (!CreateCommonErrorMessageForJs(errorCode, error.errorCode) &&
392         !CreateCallErrorMessageForJs(errorCode, error.errorCode) &&
393         !CreateDataErrorMessageForJs(errorCode, error.errorCode) &&
394         !CreateNetworkSearchErrorMessageForJs(errorCode, error.errorCode) &&
395         !CreateSimErrorMessageForJs(errorCode, error.errorCode) &&
396         !CreateSmsErrorMessageForJs(errorCode, error.errorCode) &&
397         !CreateObserverErrorMessageForJs(errorCode, error.errorCode)) {
398         error.errorCode = JS_ERROR_TELEPHONY_UNKNOW_ERROR;
399         TELEPHONY_LOGE("NapiUtil::ConverErrorMessageForJs errorCode is out of range");
400     }
401     error.errorMessage = GetErrorMessage(error.errorCode);
402     TELEPHONY_LOGI("errorCode from %{public}d to %{public}d", errorCode, error.errorCode);
403     return error;
404 }
405 
CreateParameterErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)406 bool NapiUtil::CreateParameterErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
407 {
408     bool flag = true;
409     switch (errorCode) {
410         case ERROR_SERVICE_UNAVAILABLE:
411         case ERROR_NATIVE_API_EXECUTE_FAIL:
412             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
413             break;
414         case ERROR_PARAMETER_COUNTS_INVALID:
415         case ERROR_PARAMETER_TYPE_INVALID:
416         case napi_status::napi_generic_failure:
417         case napi_status::napi_invalid_arg:
418             jsErrorCode = JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER;
419             break;
420         case ERROR_SLOT_ID_INVALID:
421             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
422             break;
423         default:
424             flag = false;
425             break;
426     }
427 
428     return flag;
429 }
430 
CreateNetworkSearchErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)431 bool NapiUtil::CreateNetworkSearchErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
432 {
433     if ((errorCode < CORE_SERVICE_NETWORK_SEARCH_ERR_OFFSET || errorCode >= CORE_SERVICE_CORE_ERR_OFFSET)) {
434         return false;
435     }
436     bool flag = true;
437     switch (errorCode) {
438         case CORE_SERVICE_SEND_CALLBACK_FAILED:
439         case CORE_SERVICE_RADIO_PROTOCOL_TECH_UNKNOWN:
440             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
441             break;
442         default:
443             flag = false;
444             break;
445     }
446 
447     return flag;
448 }
449 
CreateSimErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)450 bool NapiUtil::CreateSimErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
451 {
452     if ((errorCode < CORE_SERVICE_SIM_ERR_OFFSET || errorCode >= CORE_SERVICE_NETWORK_SEARCH_ERR_OFFSET)) {
453         return false;
454     }
455     bool flag = true;
456     switch (errorCode) {
457         case CORE_SERVICE_SIM_CARD_IS_NOT_ACTIVE:
458             jsErrorCode = JS_ERROR_SIM_CARD_IS_NOT_ACTIVE;
459             break;
460         case CORE_ERR_SIM_CARD_LOAD_FAILED:
461         case CORE_ERR_SIM_CARD_UPDATE_FAILED:
462             jsErrorCode = JS_ERROR_SIM_CARD_OPERATION_ERROR;
463             break;
464         case CORE_ERR_OPERATOR_KEY_NOT_EXIT:
465         case CORE_ERR_OPERATOR_CONF_NOT_EXIT:
466             jsErrorCode = JS_ERROR_OPERATOR_CONFIG_ERROR;
467             break;
468         default:
469             flag = false;
470             break;
471     }
472 
473     return flag;
474 }
475 
CreateSmsErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)476 bool NapiUtil::CreateSmsErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
477 {
478     if ((errorCode < SMS_MMS_ERR_OFFSET || errorCode >= STATE_REGISTRY_ERR_OFFSET)) {
479         return false;
480     }
481     bool flag = true;
482     switch (errorCode) {
483         case SMS_MMS_DECODE_DATA_EMPTY:
484         case SMS_MMS_UNKNOWN_SIM_MESSAGE_STATUS:
485         case SMS_MMS_MESSAGE_LENGTH_OUT_OF_RANGE:
486             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
487             break;
488         default:
489             flag = false;
490             break;
491     }
492 
493     return flag;
494 }
495 
CreateObserverErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)496 bool NapiUtil::CreateObserverErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
497 {
498     if ((errorCode < STATE_REGISTRY_ERR_OFFSET || errorCode >= NET_MANAGER_ERR_OFFSET)) {
499         return false;
500     }
501     bool flag = true;
502     switch (errorCode) {
503         case TELEPHONY_STATE_REGISTRY_SLODID_ERROR:
504             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
505             break;
506         case TELEPHONY_STATE_REGISTRY_PERMISSION_DENIED:
507             jsErrorCode = JS_ERROR_TELEPHONY_PERMISSION_DENIED;
508             break;
509         case TELEPHONY_STATE_REGISTRY_DATA_NOT_EXIST:
510         case TELEPHONY_STATE_UNREGISTRY_DATA_NOT_EXIST:
511         case TELEPHONY_STATE_REGISTRY_DATA_EXIST:
512         case TELEPHONY_STATE_REGISTRY_NOT_IMPLEMENTED:
513             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
514             break;
515         default:
516             flag = false;
517             break;
518     }
519 
520     return flag;
521 }
522 
CreateCommonErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)523 bool NapiUtil::CreateCommonErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
524 {
525     if ((errorCode < COMMON_ERR_OFFSET || errorCode >= CALL_ERR_OFFSET)) {
526         return false;
527     }
528     if (CreateCommonArgumentErrorMessageForJs(errorCode, jsErrorCode) ||
529         CreateCommonServiceErrorMessageForJs(errorCode, jsErrorCode) ||
530         CreateCommonSystemErrorMessageForJs(errorCode, jsErrorCode)) {
531         return true;
532     }
533     return false;
534 }
535 
CreateCommonArgumentErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)536 bool NapiUtil::CreateCommonArgumentErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
537 {
538     bool flag = true;
539 
540     switch (errorCode) {
541         case TELEPHONY_ERR_ARGUMENT_MISMATCH:
542         case TELEPHONY_ERR_ARGUMENT_INVALID:
543         case TELEPHONY_ERR_ARGUMENT_NULL:
544         case TELEPHONY_ERR_SLOTID_INVALID:
545             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
546             break;
547         default:
548             flag = false;
549             break;
550     }
551     return flag;
552 }
553 
CreateCommonServiceErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)554 bool NapiUtil::CreateCommonServiceErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
555 {
556     bool flag = true;
557 
558     switch (errorCode) {
559         case TELEPHONY_ERR_DESCRIPTOR_MISMATCH:
560         case TELEPHONY_ERR_WRITE_DESCRIPTOR_TOKEN_FAIL:
561         case TELEPHONY_ERR_WRITE_DATA_FAIL:
562         case TELEPHONY_ERR_WRITE_REPLY_FAIL:
563         case TELEPHONY_ERR_READ_DATA_FAIL:
564         case TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL:
565         case TELEPHONY_ERR_REGISTER_CALLBACK_FAIL:
566         case TELEPHONY_ERR_CALLBACK_ALREADY_REGISTERED:
567         case TELEPHONY_ERR_UNINIT:
568         case TELEPHONY_ERR_UNREGISTER_CALLBACK_FAIL:
569             jsErrorCode = JS_ERROR_TELEPHONY_SERVICE_ERROR;
570             break;
571         default:
572             flag = false;
573             break;
574     }
575     return flag;
576 }
577 
CreateCommonSystemErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)578 bool NapiUtil::CreateCommonSystemErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
579 {
580     bool flag = true;
581 
582     switch (errorCode) {
583         case TELEPHONY_ERR_FAIL:
584         case TELEPHONY_ERR_MEMCPY_FAIL:
585         case TELEPHONY_ERR_MEMSET_FAIL:
586         case TELEPHONY_ERR_STRCPY_FAIL:
587         case TELEPHONY_ERR_LOCAL_PTR_NULL:
588         case TELEPHONY_ERR_SUBSCRIBE_BROADCAST_FAIL:
589         case TELEPHONY_ERR_PUBLISH_BROADCAST_FAIL:
590         case TELEPHONY_ERR_ADD_DEATH_RECIPIENT_FAIL:
591         case TELEPHONY_ERR_STRTOINT_FAIL:
592         case TELEPHONY_ERR_RIL_CMD_FAIL:
593         case TELEPHONY_ERR_DATABASE_WRITE_FAIL:
594         case TELEPHONY_ERR_DATABASE_READ_FAIL:
595         case TELEPHONY_ERR_UNKNOWN_NETWORK_TYPE:
596             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
597             break;
598         case TELEPHONY_ERR_NO_SIM_CARD:
599             jsErrorCode = JS_ERROR_TELEPHONY_NO_SIM_CARD;
600             break;
601         case TELEPHONY_ERR_ILLEGAL_USE_OF_SYSTEM_API:
602             jsErrorCode = JS_ERROR_ILLEGAL_USE_OF_SYSTEM_API;
603             break;
604         case TELEPHONY_ERR_AIRPLANE_MODE_ON:
605             jsErrorCode = JS_ERROR_TELEPHONY_AIRPLANE_MODE_ON;
606             break;
607         case TELEPHONY_ERR_NETWORK_NOT_IN_SERVICE:
608             jsErrorCode = JS_ERROR_TELEPHONY_NETWORK_NOT_IN_SERVICE;
609             break;
610         default:
611             flag = false;
612             break;
613     }
614     return flag;
615 }
616 
CreateCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)617 bool NapiUtil::CreateCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
618 {
619     if ((errorCode < CALL_ERR_OFFSET || errorCode >= CELLULAR_DATA_ERR_OFFSET)) {
620         return false;
621     }
622     if (CreateCommonCallErrorMessageForJs(errorCode, jsErrorCode) ||
623         CreateVideoCallErrorMessageForJs(errorCode, jsErrorCode) ||
624         CreateSupplementServiceCallErrorMessageForJs(errorCode, jsErrorCode)) {
625         return true;
626     }
627     return false;
628 }
629 
CreateCommonCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)630 bool NapiUtil::CreateCommonCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
631 {
632     bool flag = true;
633 
634     switch (errorCode) {
635         case CALL_ERR_NUMBER_OUT_OF_RANGE:
636         case CALL_ERR_PHONE_NUMBER_EMPTY:
637         case CALL_ERR_FORMAT_PHONE_NUMBER_FAILED:
638             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
639             break;
640         case CALL_ERR_PARAMETER_OUT_OF_RANGE:
641         case CALL_ERR_INVALID_SLOT_ID:
642             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
643             break;
644         case CALL_ERR_CALL_IS_NOT_ACTIVATED:
645         case CALL_ERR_ILLEGAL_CALL_OPERATION:
646         case CALL_ERR_AUDIO_SETTING_MUTE_FAILED:
647         case CALL_ERR_CALL_IS_NOT_ON_HOLDING:
648         case CALL_ERR_PHONE_CALLS_TOO_FEW:
649         case CALL_ERR_VIDEO_ILLEGAL_CALL_TYPE:
650         case CALL_ERR_CONFERENCE_NOT_EXISTS:
651         case CALL_ERR_CONFERENCE_CALL_EXCEED_LIMIT:
652         case CALL_ERR_EMERGENCY_UNSUPPORT_CONFERENCEABLE:
653         case CALL_ERR_VOLTE_NOT_SUPPORT:
654         case CALL_ERR_VOLTE_PROVISIONING_DISABLED:
655         case CALL_ERR_DIAL_IS_BUSY:
656             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
657             break;
658         default:
659             flag = false;
660             break;
661     }
662     return flag;
663 }
664 
CreateVideoCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)665 bool NapiUtil::CreateVideoCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
666 {
667     bool flag = true;
668 
669     switch (errorCode) {
670         case CALL_ERR_VIDEO_ILLEGAL_MEDIA_TYPE:
671         case CALL_ERR_VIDEO_IN_PROGRESS:
672         case CALL_ERR_VIDEO_ILLEAGAL_SCENARIO:
673         case CALL_ERR_VIDEO_MODE_CHANGE_NOTIFY_FAILED:
674         case CALL_ERR_VIDEO_NOT_SUPPORTED:
675         case CALL_ERR_SETTING_AUDIO_DEVICE_FAILED:
676         case CALL_ERR_VIDEO_INVALID_COORDINATES:
677         case CALL_ERR_VIDEO_INVALID_ZOOM:
678         case CALL_ERR_VIDEO_INVALID_ROTATION:
679         case CALL_ERR_VIDEO_INVALID_CAMERA_ID:
680         case CALL_ERR_INVALID_PATH:
681         case CALL_ERR_CAMERA_NOT_TURNED_ON:
682         case CALL_ERR_INVALID_DIAL_SCENE:
683         case CALL_ERR_INVALID_VIDEO_STATE:
684         case CALL_ERR_UNKNOW_DIAL_TYPE:
685             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
686             break;
687         default:
688             flag = false;
689             break;
690     }
691     return flag;
692 }
693 
CreateSupplementServiceCallErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)694 bool NapiUtil::CreateSupplementServiceCallErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
695 {
696     bool flag = true;
697 
698     switch (errorCode) {
699         case CALL_ERR_INVALID_RESTRICTION_TYPE:
700         case CALL_ERR_INVALID_RESTRICTION_MODE:
701         case CALL_ERR_INVALID_TRANSFER_TYPE:
702         case CALL_ERR_INVALID_TRANSFER_SETTING_TYPE:
703             jsErrorCode = JS_ERROR_TELEPHONY_ARGUMENT_ERROR;
704             break;
705         case CALL_ERR_FUNCTION_NOT_SUPPORTED:
706             jsErrorCode = JS_ERROR_DEVICE_NOT_SUPPORT_THIS_API;
707             break;
708         case CALL_ERR_INVALID_TRANSFER_TIME:
709         case CALL_ERR_NAPI_INTERFACE_FAILED:
710         case CALL_ERR_CALLBACK_ALREADY_EXIST:
711         case CALL_ERR_RESOURCE_UNAVAILABLE:
712             jsErrorCode = JS_ERROR_TELEPHONY_SYSTEM_ERROR;
713             break;
714         case CALL_ERR_UT_NO_CONNECTION:
715             jsErrorCode = JS_ERROR_CALL_UT_NO_CONNECTION;
716             break;
717         default:
718             flag = false;
719             break;
720     }
721     return flag;
722 }
723 
CreateDataErrorMessageForJs(int32_t errorCode,JsErrorCode & jsErrorCode)724 bool NapiUtil::CreateDataErrorMessageForJs(int32_t errorCode, JsErrorCode &jsErrorCode)
725 {
726     if ((errorCode < CELLULAR_DATA_ERR_OFFSET || errorCode >= SMS_MMS_ERR_OFFSET)) {
727         return false;
728     }
729     bool flag = true;
730 
731     switch (errorCode) {
732         case CELLULAR_DATA_INVALID_PARAM:
733             jsErrorCode = JS_ERROR_CELLULAR_DATA_BASE_ERROR;
734             break;
735         default:
736             flag = false;
737             break;
738     }
739     return flag;
740 }
741 
ConverErrorMessageWithPermissionForJs(int32_t errorCode,const std::string & funcName,const std::string & permission)742 JsError NapiUtil::ConverErrorMessageWithPermissionForJs(
743     int32_t errorCode, const std::string &funcName, const std::string &permission)
744 {
745     if (errorCode == TELEPHONY_ERR_PERMISSION_ERR) {
746         JsError error = {};
747         error.errorCode = JS_ERROR_TELEPHONY_PERMISSION_DENIED;
748         error.errorMessage = "BusinessError 201: Permission denied. An attempt was made to " + funcName +
749                              " forbidden by permission: " + permission;
750         return error;
751     }
752     return ConverErrorMessageForJs(errorCode);
753 }
754 
CreateError(napi_env env,int32_t err,const std::string & msg)755 napi_value NapiUtil::CreateError(napi_env env, int32_t err, const std::string &msg)
756 {
757     napi_value businessError = nullptr;
758     napi_value errorCode = nullptr;
759     NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
760     napi_value errorMessage = nullptr;
761     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
762     napi_create_error(env, nullptr, errorMessage, &businessError);
763     napi_set_named_property(env, businessError, "code", errorCode);
764     return businessError;
765 }
766 
ThrowError(napi_env env,int32_t errorCode,const std::string & message)767 void NapiUtil::ThrowError(napi_env env, int32_t errorCode, const std::string &message)
768 {
769     napi_value error = CreateError(env, errorCode, message);
770     napi_throw(env, error);
771 }
772 
ThrowParameterError(napi_env env)773 void NapiUtil::ThrowParameterError(napi_env env)
774 {
775     ThrowError(
776         env, JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER, GetErrorMessage(JS_ERROR_TELEPHONY_INVALID_INPUT_PARAMETER));
777 }
778 } // namespace Telephony
779 } // namespace OHOS
780