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