• 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_cellular_data.h"
17 
18 #include <memory>
19 
20 #include "cellular_data_client.h"
21 #include "cellular_data_types.h"
22 #include "cstddef"
23 #include "iosfwd"
24 #include "js_native_api.h"
25 #include "js_native_api_types.h"
26 #include "napi/native_common.h"
27 #include "napi_cellular_data_types.h"
28 #include "napi_util.h"
29 #include "node_api.h"
30 #include "string"
31 #include "telephony_log_wrapper.h"
32 #include "telephony_napi_common_error.h"
33 
34 namespace OHOS {
35 namespace Telephony {
36 static constexpr int32_t DEFAULT_REF_COUNT = 1;
37 static constexpr const char *SET_TELEPHONY_STATE = "ohos.permission.SET_TELEPHONY_STATE";
38 static constexpr const char *GET_NETWORK_INFO = "ohos.permission.GET_NETWORK_INFO";
39 
IsCellularDataManagerInited()40 static bool IsCellularDataManagerInited()
41 {
42     return CellularDataClient::GetInstance().IsConnect();
43 }
44 
IsValidSlotId(int32_t slotId)45 static inline bool IsValidSlotId(int32_t slotId)
46 {
47     return ((slotId >= DEFAULT_SIM_SLOT_ID) && (slotId < SIM_SLOT_COUNT));
48 }
49 
MatchCellularDataParameters(napi_env env,const napi_value parameters[],const size_t parameterCount)50 static bool MatchCellularDataParameters(napi_env env, const napi_value parameters[], const size_t parameterCount)
51 {
52     switch (parameterCount) {
53         case 0:
54             return true;
55         case 1:
56             return NapiUtil::MatchParameters(env, parameters, {napi_function});
57         default:
58             return false;
59     }
60 }
61 
MatchEnableCellularDataRoamingParameters(napi_env env,const napi_value parameters[],const size_t parameterCount)62 static bool MatchEnableCellularDataRoamingParameters(
63     napi_env env, const napi_value parameters[], const size_t parameterCount)
64 {
65     const size_t paramLimitOne = 1;
66     const size_t paramLimitTwo = 2;
67     switch (parameterCount) {
68         case paramLimitOne:
69             return NapiUtil::MatchParameters(env, parameters, {napi_number});
70         case paramLimitTwo:
71             return NapiUtil::MatchParameters(env, parameters, {napi_number, napi_function});
72         default:
73             return false;
74     }
75 }
76 
WrapCellularDataType(const int32_t cellularDataType)77 static int32_t WrapCellularDataType(const int32_t cellularDataType)
78 {
79     switch (cellularDataType) {
80         case static_cast<int32_t>(DataConnectionStatus::DATA_STATE_DISCONNECTED): {
81             return static_cast<int32_t>(DataConnectionState::DATA_STATE_DISCONNECTED);
82         }
83         case static_cast<int32_t>(DataConnectionStatus::DATA_STATE_CONNECTING): {
84             return static_cast<int32_t>(DataConnectionState::DATA_STATE_CONNECTING);
85         }
86         case static_cast<int32_t>(DataConnectionStatus::DATA_STATE_CONNECTED): {
87             return static_cast<int32_t>(DataConnectionState::DATA_STATE_CONNECTED);
88         }
89         case static_cast<int32_t>(DataConnectionStatus::DATA_STATE_SUSPENDED): {
90             return static_cast<int32_t>(DataConnectionState::DATA_STATE_SUSPENDED);
91         }
92         default: {
93             return static_cast<int32_t>(DataConnectionState::DATA_STATE_UNKNOWN);
94         }
95     }
96 }
97 
WrapGetCellularDataFlowTypeType(const int32_t cellularDataType)98 static int32_t WrapGetCellularDataFlowTypeType(const int32_t cellularDataType)
99 {
100     switch (cellularDataType) {
101         case static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_NONE): {
102             return static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_NONE);
103         }
104         case static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_DOWN): {
105             return static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_DOWN);
106         }
107         case static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_UP): {
108             return static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP);
109         }
110         case static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_UP_DOWN): {
111             return static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP_DOWN);
112         }
113         case static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_DORMANT): {
114             return static_cast<int32_t>(CellDataFlowType::DATA_FLOW_TYPE_DORMANT);
115         }
116         default: {
117             return static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_NONE);
118         }
119     }
120 }
121 
NativeGetCellularDataState(napi_env env,void * data)122 static void NativeGetCellularDataState(napi_env env, void *data)
123 {
124     auto asyncContext = static_cast<AsyncContext *>(data);
125     if (asyncContext == nullptr) {
126         return;
127     }
128     if (IsCellularDataManagerInited()) {
129         int32_t dataState = CellularDataClient::GetInstance().GetCellularDataState();
130         asyncContext->resolved = true;
131         asyncContext->result = WrapCellularDataType(dataState);
132     } else {
133         asyncContext->resolved = false;
134         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
135     }
136 }
137 
GetCellularDataStateCallback(napi_env env,napi_status status,void * data)138 static void GetCellularDataStateCallback(napi_env env, napi_status status, void *data)
139 {
140     auto context = static_cast<AsyncContext *>(data);
141     if (context == nullptr) {
142         return;
143     }
144     std::unique_ptr<AsyncContext> asyncContext(context);
145     napi_value callbackValue = nullptr;
146     if (asyncContext->resolved) {
147         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncContext->result, &callbackValue));
148     } else {
149         if (asyncContext->errorCode == ERROR_SERVICE_UNAVAILABLE) {
150             callbackValue =
151                 NapiUtil::CreateErrorMessage(env, "cellular data service unavailable", ERROR_SERVICE_UNAVAILABLE);
152         } else {
153             callbackValue = NapiUtil::CreateErrorMessage(env, "unkonwn error");
154         }
155     }
156     NapiUtil::Handle2ValueCallback(env, asyncContext.release(), callbackValue);
157 }
158 
GetCellularDataState(napi_env env,napi_callback_info info)159 static napi_value GetCellularDataState(napi_env env, napi_callback_info info)
160 {
161     size_t parameterCount = 1;
162     napi_value parameters[1];
163     napi_value thisVar = nullptr;
164     void *data = nullptr;
165     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
166     NAPI_ASSERT(env, MatchCellularDataParameters(env, parameters, parameterCount), "type mismatch");
167     auto asyncContext = std::make_unique<AsyncContext>();
168     if (asyncContext == nullptr) {
169         std::string errorCode = std::to_string(napi_generic_failure);
170         std::string errorMessage = "error at baseContext is nullptr";
171         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
172         return nullptr;
173     }
174     if (parameterCount == 1) {
175         NAPI_CALL(env, napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &asyncContext->callbackRef));
176     }
177     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "GetCellularDataState",
178         NativeGetCellularDataState, GetCellularDataStateCallback);
179 }
180 
NativeIsCellularDataEnabled(napi_env env,void * data)181 static void NativeIsCellularDataEnabled(napi_env env, void *data)
182 {
183     auto asyncContext = static_cast<AsyncContext *>(data);
184     if (asyncContext == nullptr) {
185         NapiUtil::ThrowParameterError(env);
186         return;
187     }
188     if (IsCellularDataManagerInited()) {
189         bool enabled = false;
190         asyncContext->errorCode = CellularDataClient::GetInstance().IsCellularDataEnabled(enabled);
191         if (asyncContext->errorCode == TELEPHONY_SUCCESS) {
192             asyncContext->resolved = true;
193         }
194         asyncContext->result = enabled;
195     } else {
196         asyncContext->resolved = false;
197         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
198     }
199 }
200 
IsCellularDataEnabledCallback(napi_env env,napi_status status,void * data)201 static void IsCellularDataEnabledCallback(napi_env env, napi_status status, void *data)
202 {
203     auto context = static_cast<AsyncContext *>(data);
204     if (context == nullptr) {
205         return;
206     }
207     std::unique_ptr<AsyncContext> asyncContext(context);
208     napi_value callbackValue = nullptr;
209     if (asyncContext->resolved) {
210         napi_status status = napi_get_boolean(env,
211             asyncContext->result == static_cast<int32_t>(DataSwitchCode::CELLULAR_DATA_ENABLED), &callbackValue);
212         NAPI_CALL_RETURN_VOID(env, status);
213     } else {
214         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
215             asyncContext->errorCode, "IsCellularDataEnabled", GET_NETWORK_INFO);
216         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
217     }
218     NapiUtil::Handle2ValueCallback(env, asyncContext.release(), callbackValue);
219 }
220 
IsCellularDataEnabled(napi_env env,napi_callback_info info)221 static napi_value IsCellularDataEnabled(napi_env env, napi_callback_info info)
222 {
223     size_t parameterCount = 1;
224     napi_value parameters[1];
225     napi_value thisVar = nullptr;
226     void *data = nullptr;
227     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
228     if (!MatchCellularDataParameters(env, parameters, parameterCount)) {
229         TELEPHONY_LOGE("IsCellularDataEnabled MatchCellularDataParameters failed.");
230         NapiUtil::ThrowParameterError(env);
231         return nullptr;
232     }
233     auto asyncContext = std::make_unique<AsyncContext>();
234     if (asyncContext == nullptr) {
235         TELEPHONY_LOGE("IsCellularDataEnabled asyncContext is nullptr.");
236         NapiUtil::ThrowParameterError(env);
237         return nullptr;
238     }
239     if (parameterCount == 1) {
240         NAPI_CALL(env, napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &(asyncContext->callbackRef)));
241     }
242     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "IsCellularDataEnabled",
243         NativeIsCellularDataEnabled, IsCellularDataEnabledCallback);
244 }
245 
NativeEnableCellularData(napi_env env,void * data)246 static void NativeEnableCellularData(napi_env env, void *data)
247 {
248     auto asyncContext = static_cast<AsyncContext *>(data);
249     if (asyncContext == nullptr) {
250         NapiUtil::ThrowParameterError(env);
251         return;
252     }
253     if (IsCellularDataManagerInited()) {
254         asyncContext->result = CellularDataClient::GetInstance().EnableCellularData(true);
255         if (asyncContext->result == TELEPHONY_ERR_SUCCESS) {
256             asyncContext->resolved = true;
257         } else {
258             asyncContext->resolved = false;
259             asyncContext->errorCode = asyncContext->result;
260         }
261     } else {
262         asyncContext->resolved = false;
263         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
264     }
265 }
266 
EnableCellularDataCallback(napi_env env,napi_status status,void * data)267 static void EnableCellularDataCallback(napi_env env, napi_status status, void *data)
268 {
269     auto context = static_cast<AsyncContext *>(data);
270     if (context == nullptr) {
271         NapiUtil::ThrowParameterError(env);
272         return;
273     }
274     std::unique_ptr<AsyncContext> asyncContext(context);
275     napi_value callbackValue = nullptr;
276     if (asyncContext->resolved) {
277         callbackValue = NapiUtil::CreateUndefined(env);
278     } else {
279         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
280             asyncContext->errorCode, "enableCellularData", SET_TELEPHONY_STATE);
281         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
282     }
283     NapiUtil::Handle1ValueCallback(env, asyncContext.release(), callbackValue);
284     TELEPHONY_LOGI("EnableCellularDataCallback end");
285 }
286 
DisableCellularDataCallback(napi_env env,napi_status status,void * data)287 static void DisableCellularDataCallback(napi_env env, napi_status status, void *data)
288 {
289     auto context = static_cast<AsyncContext *>(data);
290     if (context == nullptr) {
291         NapiUtil::ThrowParameterError(env);
292         return;
293     }
294     std::unique_ptr<AsyncContext> asyncContext(context);
295     napi_value callbackValue = nullptr;
296     if (asyncContext->resolved) {
297         callbackValue = NapiUtil::CreateUndefined(env);
298     } else {
299         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
300             asyncContext->errorCode, "disableCellularData", SET_TELEPHONY_STATE);
301         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
302     }
303     NapiUtil::Handle1ValueCallback(env, asyncContext.release(), callbackValue);
304     TELEPHONY_LOGI("DisableCellularDataCallback end");
305 }
306 
EnableCellularDataRoamingCallback(napi_env env,napi_status status,void * data)307 static void EnableCellularDataRoamingCallback(napi_env env, napi_status status, void *data)
308 {
309     auto context = static_cast<AsyncContext *>(data);
310     if (context == nullptr) {
311         NapiUtil::ThrowParameterError(env);
312         return;
313     }
314     std::unique_ptr<AsyncContext> asyncContext(context);
315     napi_value callbackValue = nullptr;
316     if (asyncContext->resolved) {
317         callbackValue = NapiUtil::CreateUndefined(env);
318     } else {
319         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
320             asyncContext->errorCode, "enableCellularDataRoaming", SET_TELEPHONY_STATE);
321         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
322     }
323     NapiUtil::Handle1ValueCallback(env, asyncContext.release(), callbackValue);
324     TELEPHONY_LOGI("EnableCellularDataRoamingCallback end");
325 }
326 
DisableCellularDataRoamingCallback(napi_env env,napi_status status,void * data)327 static void DisableCellularDataRoamingCallback(napi_env env, napi_status status, void *data)
328 {
329     auto context = static_cast<AsyncContext *>(data);
330     if (context == nullptr) {
331         NapiUtil::ThrowParameterError(env);
332         return;
333     }
334     std::unique_ptr<AsyncContext> asyncContext(context);
335     napi_value callbackValue = nullptr;
336     if (asyncContext->resolved) {
337         callbackValue = NapiUtil::CreateUndefined(env);
338     } else {
339         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
340             asyncContext->errorCode, "disableCellularDataRoaming", SET_TELEPHONY_STATE);
341         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
342     }
343     NapiUtil::Handle1ValueCallback(env, asyncContext.release(), callbackValue);
344     TELEPHONY_LOGI("DisableCellularDataRoamingCallback end");
345 }
346 
EnableCellularData(napi_env env,napi_callback_info info)347 static napi_value EnableCellularData(napi_env env, napi_callback_info info)
348 {
349     size_t parameterCount = 1;
350     napi_value parameters[1];
351     napi_value thisVar = nullptr;
352     void *data = nullptr;
353     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
354     if (!MatchCellularDataParameters(env, parameters, parameterCount)) {
355         NapiUtil::ThrowParameterError(env);
356         return nullptr;
357     }
358     auto asyncContext = std::make_unique<AsyncContext>();
359     if (asyncContext == nullptr) {
360         NapiUtil::ThrowParameterError(env);
361         return nullptr;
362     }
363     if (parameterCount == 1) {
364         NAPI_CALL(env, napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &(asyncContext->callbackRef)));
365     }
366     return NapiUtil::HandleAsyncWork(
367         env, asyncContext.release(), "EnableCellularData", NativeEnableCellularData, EnableCellularDataCallback);
368 }
369 
NativeDisableCellularData(napi_env env,void * data)370 static void NativeDisableCellularData(napi_env env, void *data)
371 {
372     auto asyncContext = static_cast<AsyncContext *>(data);
373     if (asyncContext == nullptr) {
374         NapiUtil::ThrowParameterError(env);
375         return;
376     }
377     if (IsCellularDataManagerInited()) {
378         asyncContext->result = CellularDataClient::GetInstance().EnableCellularData(false);
379         if (asyncContext->result == TELEPHONY_ERR_SUCCESS) {
380             asyncContext->resolved = true;
381         } else {
382             asyncContext->resolved = false;
383             asyncContext->errorCode = asyncContext->result;
384         }
385     } else {
386         asyncContext->resolved = false;
387         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
388     }
389 }
390 
DisableCellularData(napi_env env,napi_callback_info info)391 static napi_value DisableCellularData(napi_env env, napi_callback_info info)
392 {
393     size_t parameterCount = 1;
394     napi_value parameters[1];
395     napi_value thisVar = nullptr;
396     void *data = nullptr;
397     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
398     if (!MatchCellularDataParameters(env, parameters, parameterCount)) {
399         NapiUtil::ThrowParameterError(env);
400         return nullptr;
401     }
402     auto asyncContext = std::make_unique<AsyncContext>();
403     if (asyncContext == nullptr) {
404         NapiUtil::ThrowParameterError(env);
405         return nullptr;
406     }
407     if (parameterCount == 1) {
408         NAPI_CALL(env, napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &(asyncContext->callbackRef)));
409     }
410     return NapiUtil::HandleAsyncWork(
411         env, asyncContext.release(), "DisableCellularData", NativeDisableCellularData, DisableCellularDataCallback);
412 }
413 
NativeEnableCellularDataRoaming(napi_env env,void * data)414 static void NativeEnableCellularDataRoaming(napi_env env, void *data)
415 {
416     auto asyncContext = static_cast<AsyncContext *>(data);
417     if (asyncContext == nullptr) {
418         NapiUtil::ThrowParameterError(env);
419         return;
420     }
421     if (!IsValidSlotId(asyncContext->slotId)) {
422         TELEPHONY_LOGE("NativeEnableCellularDataRoaming slotId is invalid");
423         asyncContext->errorCode = ERROR_SLOT_ID_INVALID;
424         return;
425     }
426     if (IsCellularDataManagerInited()) {
427         asyncContext->result = CellularDataClient::GetInstance().EnableCellularDataRoaming(asyncContext->slotId, true);
428         if (asyncContext->result == TELEPHONY_ERR_SUCCESS) {
429             asyncContext->resolved = true;
430         } else {
431             asyncContext->resolved = false;
432             asyncContext->errorCode = asyncContext->result;
433         }
434     } else {
435         asyncContext->resolved = false;
436         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
437     }
438     TELEPHONY_LOGI("NativeEnableCellularDataRoaming end");
439 }
440 
EnableCellularDataRoaming(napi_env env,napi_callback_info info)441 static napi_value EnableCellularDataRoaming(napi_env env, napi_callback_info info)
442 {
443     const size_t paramLimitTwo = 2;
444     size_t parameterCount = paramLimitTwo;
445     napi_value parameters[paramLimitTwo] = { 0 };
446     napi_value thisVar = nullptr;
447     void *data = nullptr;
448     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
449     if (!MatchEnableCellularDataRoamingParameters(env, parameters, parameterCount)) {
450         NapiUtil::ThrowParameterError(env);
451         return nullptr;
452     }
453     auto asyncContext = std::make_unique<AsyncContext>();
454     if (asyncContext == nullptr) {
455         NapiUtil::ThrowParameterError(env);
456         return nullptr;
457     }
458     NAPI_CALL(env, napi_get_value_int32(env, parameters[0], &asyncContext->slotId));
459     if (parameterCount == paramLimitTwo) {
460         NAPI_CALL(env, napi_create_reference(env, parameters[1], DEFAULT_REF_COUNT, &asyncContext->callbackRef));
461     }
462     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "EnableCellularDataRoaming",
463         NativeEnableCellularDataRoaming, EnableCellularDataRoamingCallback);
464 }
465 
NativeDisableCellularDataRoaming(napi_env env,void * data)466 static void NativeDisableCellularDataRoaming(napi_env env, void *data)
467 {
468     auto asyncContext = static_cast<AsyncContext *>(data);
469     if (asyncContext == nullptr) {
470         NapiUtil::ThrowParameterError(env);
471         return;
472     }
473     if (!IsValidSlotId(asyncContext->slotId)) {
474         TELEPHONY_LOGE("NativeDisableCellularDataRoaming slotId is invalid");
475         asyncContext->errorCode = ERROR_SLOT_ID_INVALID;
476         return;
477     }
478     if (IsCellularDataManagerInited()) {
479         asyncContext->result = CellularDataClient::GetInstance().EnableCellularDataRoaming(asyncContext->slotId, false);
480         if (asyncContext->result == TELEPHONY_ERR_SUCCESS) {
481             asyncContext->resolved = true;
482         } else {
483             asyncContext->resolved = false;
484             asyncContext->errorCode = asyncContext->result;
485         }
486     } else {
487         asyncContext->resolved = false;
488         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
489     }
490 }
491 
DisableCellularDataRoaming(napi_env env,napi_callback_info info)492 static napi_value DisableCellularDataRoaming(napi_env env, napi_callback_info info)
493 {
494     const size_t paramLimitTwo = 2;
495     size_t parameterCount = paramLimitTwo;
496     napi_value parameters[paramLimitTwo] = { 0 };
497     napi_value thisVar = nullptr;
498     void *data = nullptr;
499     NAPI_CALL(env, napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data));
500     if (!MatchEnableCellularDataRoamingParameters(env, parameters, parameterCount)) {
501         NapiUtil::ThrowParameterError(env);
502         return nullptr;
503     }
504     auto asyncContext = std::make_unique<AsyncContext>();
505     if (asyncContext == nullptr) {
506         NapiUtil::ThrowParameterError(env);
507         return nullptr;
508     }
509     NAPI_CALL(env, napi_get_value_int32(env, parameters[0], &asyncContext->slotId));
510     if (parameterCount == paramLimitTwo) {
511         NAPI_CALL(env, napi_create_reference(env, parameters[1], DEFAULT_REF_COUNT, &asyncContext->callbackRef));
512     }
513     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "DisableCellularDataRoaming",
514         NativeDisableCellularDataRoaming, DisableCellularDataRoamingCallback);
515 }
516 
NativeIsCellularDataRoamingEnabled(napi_env env,void * data)517 static void NativeIsCellularDataRoamingEnabled(napi_env env, void *data)
518 {
519     auto asyncContext = static_cast<AsyncContext *>(data);
520     if (asyncContext == nullptr) {
521         NapiUtil::ThrowParameterError(env);
522         return;
523     }
524     if (!IsValidSlotId(asyncContext->slotId)) {
525         TELEPHONY_LOGE("NativeIsCellularDataRoamingEnabled slotId is invalid");
526         asyncContext->errorCode = ERROR_SLOT_ID_INVALID;
527         return;
528     }
529     if (IsCellularDataManagerInited()) {
530         auto &dataManager = CellularDataClient::GetInstance();
531         bool enabled = false;
532         asyncContext->errorCode = dataManager.IsCellularDataRoamingEnabled(asyncContext->slotId, enabled);
533         if (asyncContext->errorCode == TELEPHONY_SUCCESS) {
534             asyncContext->resolved = true;
535         }
536         asyncContext->result = enabled;
537     } else {
538         asyncContext->resolved = false;
539         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
540     }
541 }
542 
IsCellularDataRoamingEnabledCallback(napi_env env,napi_status status,void * data)543 static void IsCellularDataRoamingEnabledCallback(napi_env env, napi_status status, void *data)
544 {
545     auto context = static_cast<AsyncContext *>(data);
546     if (context == nullptr) {
547         return;
548     }
549     std::unique_ptr<AsyncContext> asyncContext(context);
550     napi_value callbackValue = nullptr;
551     if (asyncContext->resolved) {
552         napi_status status = napi_get_boolean(env,
553             asyncContext->result == static_cast<int32_t>(RoamingSwitchCode::CELLULAR_DATA_ROAMING_ENABLED),
554             &callbackValue);
555         NAPI_CALL_RETURN_VOID(env, status);
556     } else {
557         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
558             asyncContext->errorCode, "isCellularDataRoamingEnabled", GET_NETWORK_INFO);
559         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
560     }
561     NapiUtil::Handle2ValueCallback(env, asyncContext.release(), callbackValue);
562 }
563 
IsCellularDataRoamingEnabled(napi_env env,napi_callback_info info)564 static napi_value IsCellularDataRoamingEnabled(napi_env env, napi_callback_info info)
565 {
566     const size_t paramLimitTwo = 2;
567     size_t parameterCount = paramLimitTwo;
568     napi_value parameters[paramLimitTwo] = {0};
569     napi_value thisVar = nullptr;
570     void *data = nullptr;
571     napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data);
572     if (!MatchEnableCellularDataRoamingParameters(env, parameters, parameterCount)) {
573         TELEPHONY_LOGE("IsCellularDataRoamingEnabled MatchEnableCellularDataRoamingParameters failed.");
574         NapiUtil::ThrowParameterError(env);
575         return nullptr;
576     }
577     auto asyncContext = std::make_unique<AsyncContext>();
578     if (asyncContext == nullptr) {
579         TELEPHONY_LOGE("IsCellularDataRoamingEnabled asyncContext is nullptr.");
580         NapiUtil::ThrowParameterError(env);
581         return nullptr;
582     }
583     napi_get_value_int32(env, parameters[0], &asyncContext->slotId);
584     if (parameterCount == paramLimitTwo) {
585         napi_create_reference(env, parameters[1], DEFAULT_REF_COUNT, &asyncContext->callbackRef);
586     }
587     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "IsCellularDataRoamingEnabled",
588         NativeIsCellularDataRoamingEnabled, IsCellularDataRoamingEnabledCallback);
589 }
590 
MatchGetDefaultCellularDataSlotIdParameters(napi_env env,const napi_value parameters[],const size_t parameterCount)591 static bool MatchGetDefaultCellularDataSlotIdParameters(
592     napi_env env, const napi_value parameters[], const size_t parameterCount)
593 {
594     switch (parameterCount) {
595         case 0:
596             return true;
597         case 1:
598             return NapiUtil::MatchParameters(env, parameters, {napi_function});
599         default:
600             return false;
601     }
602 }
603 
NativeGetDefaultCellularDataSlotId(napi_env env,void * data)604 static void NativeGetDefaultCellularDataSlotId(napi_env env, void *data)
605 {
606     auto context = static_cast<AsyncContext *>(data);
607     if (context == nullptr) {
608         return;
609     }
610     int32_t result = CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
611     if (IsValidSlotId(result) || result == DEFAULT_SIM_SLOT_ID_REMOVE) {
612         context->slotId = result;
613         context->resolved = true;
614     } else {
615         context->resolved = false;
616         context->errorCode = ERROR_NATIVE_API_EXECUTE_FAIL;
617     }
618 }
619 
GetDefaultCellularDataSlotIdCallback(napi_env env,napi_status status,void * data)620 static void GetDefaultCellularDataSlotIdCallback(napi_env env, napi_status status, void *data)
621 {
622     auto asyncContext = static_cast<AsyncContext *>(data);
623     if (asyncContext == nullptr) {
624         return;
625     }
626     napi_value callbackValue = nullptr;
627     if (asyncContext->resolved) {
628         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncContext->slotId, &callbackValue));
629     } else {
630         if (asyncContext->errorCode == ERROR_NATIVE_API_EXECUTE_FAIL) {
631             callbackValue = NapiUtil::CreateErrorMessage(
632                 env, "GetDefaultCellularDataSlotId api execute failed", ERROR_NATIVE_API_EXECUTE_FAIL);
633         } else {
634             callbackValue = NapiUtil::CreateErrorMessage(env, "get default cellular data slotId failed");
635         }
636     }
637     NapiUtil::Handle2ValueCallback(env, asyncContext, callbackValue);
638 }
639 
GetDefaultCellularDataSlotId(napi_env env,napi_callback_info info)640 static napi_value GetDefaultCellularDataSlotId(napi_env env, napi_callback_info info)
641 {
642     size_t parameterCount = 1;
643     napi_value parameters[] = {nullptr};
644     napi_value thisVar = nullptr;
645     void *data = nullptr;
646     napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data);
647     NAPI_ASSERT(env, MatchGetDefaultCellularDataSlotIdParameters(env, parameters, parameterCount), "type mismatch");
648     auto asyncContext = std::make_unique<AsyncContext>();
649     if (asyncContext == nullptr) {
650         std::string errorCode = std::to_string(napi_generic_failure);
651         std::string errorMessage = "error at baseContext is nullptr";
652         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
653         return nullptr;
654     }
655     if (parameterCount == 1) {
656         napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &asyncContext->callbackRef);
657     }
658     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "GetDefaultCellularDataSlotId",
659         NativeGetDefaultCellularDataSlotId, GetDefaultCellularDataSlotIdCallback);
660 }
661 
GetDefaultCellularDataSlotIdSync(napi_env env,napi_callback_info info)662 static napi_value GetDefaultCellularDataSlotIdSync(napi_env env, napi_callback_info info)
663 {
664     size_t parameterCount = 1;
665     napi_value parameters[] = {nullptr};
666     napi_value thisVar = nullptr;
667     void *data = nullptr;
668     int32_t slotId = -1;
669     napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data);
670     if (parameterCount == 0) {
671         slotId = CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
672     }
673     napi_value value = nullptr;
674     NAPI_CALL(env, napi_create_int32(env, slotId, &value));
675     return value;
676 }
677 
NativeSetDefaultCellularDataSlotId(napi_env env,void * data)678 static void NativeSetDefaultCellularDataSlotId(napi_env env, void *data)
679 {
680     auto asyncContext = static_cast<AsyncContext *>(data);
681     if (asyncContext == nullptr) {
682         NapiUtil::ThrowParameterError(env);
683         return;
684     }
685     if (!IsValidSlotId(asyncContext->slotId) && (asyncContext->slotId != DEFAULT_SIM_SLOT_ID_REMOVE)) {
686         TELEPHONY_LOGE("NativeSetDefaultCellularDataSlotId slotId is invalid");
687         asyncContext->errorCode = ERROR_SLOT_ID_INVALID;
688         return;
689     }
690     if (IsCellularDataManagerInited()) {
691         asyncContext->errorCode = CellularDataClient::GetInstance().SetDefaultCellularDataSlotId(asyncContext->slotId);
692         if (asyncContext->errorCode == TELEPHONY_ERR_SUCCESS) {
693             asyncContext->resolved = true;
694         } else {
695             asyncContext->resolved = false;
696         }
697     } else {
698         asyncContext->resolved = false;
699         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
700     }
701 }
702 
SetDefaultCellularDataSlotIdCallback(napi_env env,napi_status status,void * data)703 static void SetDefaultCellularDataSlotIdCallback(napi_env env, napi_status status, void *data)
704 {
705     auto asyncContext = static_cast<AsyncContext *>(data);
706     if (asyncContext == nullptr) {
707         NapiUtil::ThrowParameterError(env);
708         return;
709     }
710     napi_value callbackValue = nullptr;
711     if (asyncContext->resolved) {
712         callbackValue = NapiUtil::CreateUndefined(env);
713     } else {
714         JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
715             asyncContext->errorCode, "setDefaultCellularDataSlotId", SET_TELEPHONY_STATE);
716         callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
717     }
718     NapiUtil::Handle1ValueCallback(env, asyncContext, callbackValue);
719 }
720 
SetDefaultCellularDataSlotId(napi_env env,napi_callback_info info)721 static napi_value SetDefaultCellularDataSlotId(napi_env env, napi_callback_info info)
722 {
723     const size_t paramLimitTwo = 2;
724     size_t parameterCount = paramLimitTwo;
725     napi_value parameters[] = { nullptr, nullptr };
726     napi_value thisVar = nullptr;
727     void *data = nullptr;
728     napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data);
729     if (!MatchEnableCellularDataRoamingParameters(env, parameters, parameterCount)) {
730         NapiUtil::ThrowParameterError(env);
731         return nullptr;
732     }
733     auto asyncContext = std::make_unique<AsyncContext>();
734     if (asyncContext == nullptr) {
735         NapiUtil::ThrowParameterError(env);
736         return nullptr;
737     }
738     napi_get_value_int32(env, parameters[0], &asyncContext->slotId);
739     if (parameterCount == paramLimitTwo) {
740         napi_create_reference(env, parameters[1], DEFAULT_REF_COUNT, &asyncContext->callbackRef);
741     }
742     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "SetDefaultCellularDataSlotId",
743         NativeSetDefaultCellularDataSlotId, SetDefaultCellularDataSlotIdCallback);
744 }
745 
NativeGetCellularDataFlowType(napi_env env,void * data)746 void NativeGetCellularDataFlowType(napi_env env, void *data)
747 {
748     auto asyncContext = static_cast<AsyncContext *>(data);
749     if (asyncContext == nullptr) {
750         return;
751     }
752     if (IsCellularDataManagerInited()) {
753         int32_t dataState = CellularDataClient::GetInstance().GetCellularDataFlowType();
754         TELEPHONY_LOGI("dataState = %{public}d", dataState);
755         asyncContext->resolved = true;
756         asyncContext->result = WrapGetCellularDataFlowTypeType(dataState);
757     } else {
758         asyncContext->resolved = false;
759         asyncContext->errorCode = ERROR_SERVICE_UNAVAILABLE;
760     }
761 }
762 
GetCellularDataFlowTypeCallback(napi_env env,napi_status status,void * data)763 void GetCellularDataFlowTypeCallback(napi_env env, napi_status status, void *data)
764 {
765     auto context = static_cast<AsyncContext *>(data);
766     if (context == nullptr) {
767         return;
768     }
769     std::unique_ptr<AsyncContext> asyncContext(context);
770     napi_value callbackValue = nullptr;
771     if (asyncContext->resolved) {
772         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncContext->result, &callbackValue));
773     } else {
774         if (asyncContext->errorCode == ERROR_SERVICE_UNAVAILABLE) {
775             callbackValue =
776                 NapiUtil::CreateErrorMessage(env, "cellular data service unavailable", ERROR_SERVICE_UNAVAILABLE);
777         } else {
778             callbackValue = NapiUtil::CreateErrorMessage(env, "unkonwn error");
779         }
780     }
781     NapiUtil::Handle2ValueCallback(env, asyncContext.release(), callbackValue);
782     TELEPHONY_LOGI("GetCellularDataFlowTypeCallback end");
783 }
784 
GetCellularDataFlowType(napi_env env,napi_callback_info info)785 static napi_value GetCellularDataFlowType(napi_env env, napi_callback_info info)
786 {
787     size_t parameterCount = 1;
788     napi_value parameters[] = {nullptr};
789     napi_value thisVar = nullptr;
790     void *data = nullptr;
791     napi_get_cb_info(env, info, &parameterCount, parameters, &thisVar, &data);
792     NAPI_ASSERT(env, MatchGetDefaultCellularDataSlotIdParameters(env, parameters, parameterCount), "type mismatch");
793     auto asyncContext = std::make_unique<AsyncContext>();
794     if (asyncContext == nullptr) {
795         std::string errorCode = std::to_string(napi_generic_failure);
796         std::string errorMessage = "error at baseContext is nullptr";
797         NAPI_CALL(env, napi_throw_error(env, errorCode.c_str(), errorMessage.c_str()));
798         return nullptr;
799     }
800     if (parameterCount == 1) {
801         napi_create_reference(env, parameters[0], DEFAULT_REF_COUNT, &asyncContext->callbackRef);
802     }
803     return NapiUtil::HandleAsyncWork(env, asyncContext.release(), "GetCellularDataFlowType",
804         NativeGetCellularDataFlowType, GetCellularDataFlowTypeCallback);
805 }
806 
CreateEnumConstructor(napi_env env,napi_callback_info info)807 static napi_value CreateEnumConstructor(napi_env env, napi_callback_info info)
808 {
809     napi_value thisArg = nullptr;
810     void *data = nullptr;
811     napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
812     napi_value global = nullptr;
813     napi_get_global(env, &global);
814     return thisArg;
815 }
816 
InitEnumDataConnectState(napi_env env,napi_value exports)817 static napi_value InitEnumDataConnectState(napi_env env, napi_value exports)
818 {
819     napi_property_descriptor desc[] = {
820         DECLARE_NAPI_STATIC_PROPERTY(
821             "DATA_STATE_UNKNOWN", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_UNKNOWN))),
822         DECLARE_NAPI_STATIC_PROPERTY(
823             "DATA_STATE_DISCONNECTED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_DISCONNECTED))),
824         DECLARE_NAPI_STATIC_PROPERTY(
825             "DATA_STATE_CONNECTING", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_CONNECTING))),
826         DECLARE_NAPI_STATIC_PROPERTY(
827             "DATA_STATE_CONNECTED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_CONNECTED))),
828         DECLARE_NAPI_STATIC_PROPERTY(
829             "DATA_STATE_SUSPENDED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_SUSPENDED))),
830     };
831     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
832     return exports;
833 }
834 
CreateDataConnectState(napi_env env,napi_value exports)835 static napi_value CreateDataConnectState(napi_env env, napi_value exports)
836 {
837     napi_property_descriptor desc[] = {
838         DECLARE_NAPI_STATIC_PROPERTY(
839             "DATA_STATE_UNKNOWN", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_UNKNOWN))),
840         DECLARE_NAPI_STATIC_PROPERTY(
841             "DATA_STATE_DISCONNECTED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_DISCONNECTED))),
842         DECLARE_NAPI_STATIC_PROPERTY(
843             "DATA_STATE_CONNECTING", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_CONNECTING))),
844         DECLARE_NAPI_STATIC_PROPERTY(
845             "DATA_STATE_CONNECTED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_CONNECTED))),
846         DECLARE_NAPI_STATIC_PROPERTY(
847             "DATA_STATE_SUSPENDED", NapiUtil::ToInt32Value(env, static_cast<int32_t>(DATA_STATE_SUSPENDED))),
848 
849     };
850     napi_value result = nullptr;
851     napi_define_class(env, "DataConnectState", NAPI_AUTO_LENGTH, CreateEnumConstructor, nullptr,
852         sizeof(desc) / sizeof(*desc), desc, &result);
853     napi_set_named_property(env, exports, "DataConnectState", result);
854     return exports;
855 }
856 
InitEnumDataFlowType(napi_env env,napi_value exports)857 static napi_value InitEnumDataFlowType(napi_env env, napi_value exports)
858 {
859     napi_property_descriptor desc[] = {
860         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_NONE",
861             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_NONE))),
862         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_DOWN",
863             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_DOWN))),
864         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_UP",
865             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP))),
866         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_UP_DOWN",
867             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP_DOWN))),
868         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_DORMANT",
869             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_DORMANT))),
870     };
871     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
872     return exports;
873 }
874 
CreateDataFlowType(napi_env env,napi_value exports)875 static napi_value CreateDataFlowType(napi_env env, napi_value exports)
876 {
877     napi_property_descriptor desc[] = {
878         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_NONE",
879             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_NONE))),
880         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_DOWN",
881             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_DOWN))),
882         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_UP",
883             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP))),
884         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_UP_DOWN",
885             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_UP_DOWN))),
886         DECLARE_NAPI_STATIC_PROPERTY("DATA_FLOW_TYPE_DORMANT",
887             NapiUtil::ToInt32Value(env, static_cast<int32_t>(DataFlowType::DATA_FLOW_TYPE_DORMANT))),
888     };
889     napi_value result = nullptr;
890     napi_define_class(env, "DataFlowType", NAPI_AUTO_LENGTH, CreateEnumConstructor, nullptr,
891         sizeof(desc) / sizeof(*desc), desc, &result);
892     napi_set_named_property(env, exports, "DataFlowType", result);
893     return exports;
894 }
895 
896 EXTERN_C_START
RegistCellularData(napi_env env,napi_value exports)897 napi_value RegistCellularData(napi_env env, napi_value exports)
898 {
899     auto cellularDataPoxy = CellularDataClient::GetInstance().GetProxy();
900     napi_property_descriptor desc[] = {
901         DECLARE_NAPI_FUNCTION("getCellularDataState", GetCellularDataState),
902         DECLARE_NAPI_FUNCTION("isCellularDataEnabled", IsCellularDataEnabled),
903         DECLARE_NAPI_FUNCTION("enableCellularData", EnableCellularData),
904         DECLARE_NAPI_FUNCTION("disableCellularData", DisableCellularData),
905         DECLARE_NAPI_FUNCTION("enableCellularDataRoaming", EnableCellularDataRoaming),
906         DECLARE_NAPI_FUNCTION("disableCellularDataRoaming", DisableCellularDataRoaming),
907         DECLARE_NAPI_FUNCTION("isCellularDataRoamingEnabled", IsCellularDataRoamingEnabled),
908         DECLARE_NAPI_FUNCTION("getDefaultCellularDataSlotId", GetDefaultCellularDataSlotId),
909         DECLARE_NAPI_FUNCTION("getDefaultCellularDataSlotIdSync", GetDefaultCellularDataSlotIdSync),
910         DECLARE_NAPI_FUNCTION("setDefaultCellularDataSlotId", SetDefaultCellularDataSlotId),
911         DECLARE_NAPI_FUNCTION("getCellularDataFlowType", GetCellularDataFlowType),
912     };
913     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
914     CreateDataConnectState(env, exports);
915     InitEnumDataConnectState(env, exports);
916     CreateDataFlowType(env, exports);
917     InitEnumDataFlowType(env, exports);
918     return exports;
919 }
920 EXTERN_C_END
921 
922 static napi_module _cellularDataModule = {
923     .nm_version = 1,
924     .nm_flags = 0,
925     .nm_filename = nullptr,
926     .nm_register_func = RegistCellularData,
927     .nm_modname = "telephony.data",
928     .nm_priv = nullptr,
929     .reserved = {nullptr},
930 };
931 
RegisterCellularDataModule(void)932 extern "C" __attribute__((constructor)) void RegisterCellularDataModule(void)
933 {
934     napi_module_register(&_cellularDataModule);
935 }
936 } // namespace Telephony
937 } // namespace OHOS
938