1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "napi_send_recv_mms.h"
16
17 #include <chrono>
18
19 #include "ability.h"
20 #include "napi_base_context.h"
21 #include "napi_mms_pdu.h"
22 #include "napi_mms_pdu_helper.h"
23 #include "sms_constants_utils.h"
24 #include "telephony_permission.h"
25
26
27 namespace OHOS {
28 namespace Telephony {
29 namespace {
30 const std::string SMS_PROFILE_URI = "datashare:///com.ohos.smsmmsability";
31 static const int32_t DEFAULT_REF_COUNT = 1;
32 const bool STORE_MMS_PDU_TO_FILE = false;
33 const int32_t ARGS_ONE = 1;
34 std::shared_ptr<DataShare::DataShareHelper> g_datashareHelper = nullptr;
35 constexpr static uint32_t WAIT_PDN_TOGGLE_TIME = 3000;
36 } // namespace
37 std::mutex NapiSendRecvMms::downloadCtx_;
38 std::mutex NapiSendRecvMms::countCtx_;
39 int32_t NapiSendRecvMms::reqCount_ = 0;
40 bool NapiSendRecvMms::waitFlag = false;
41
GetDataShareHelper(napi_env env,napi_callback_info info)42 std::shared_ptr<OHOS::DataShare::DataShareHelper> GetDataShareHelper(napi_env env, napi_callback_info info)
43 {
44 size_t argc = ARGS_ONE;
45 napi_value argv[ARGS_ONE] = { 0 };
46 napi_value thisVar = nullptr;
47 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
48
49 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = nullptr;
50 bool isStageMode = false;
51 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, argv[0], isStageMode);
52 if (status != napi_ok || !isStageMode) {
53 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
54 if (ability == nullptr) {
55 TELEPHONY_LOGE("Failed to get native ability instance");
56 return nullptr;
57 }
58 auto context = ability->GetContext();
59 if (context == nullptr) {
60 TELEPHONY_LOGE("Failed to get native context instance");
61 return nullptr;
62 }
63 dataShareHelper = DataShare::DataShareHelper::Creator(context->GetToken(), SMS_PROFILE_URI);
64 } else {
65 auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
66 if (context == nullptr) {
67 TELEPHONY_LOGE("Failed to get native stage context instance");
68 return nullptr;
69 }
70 dataShareHelper = DataShare::DataShareHelper::Creator(context->GetToken(), SMS_PROFILE_URI);
71 }
72 return dataShareHelper;
73 }
74
GetMmsPduFromFile(const std::string & fileName,std::string & mmsPdu)75 bool GetMmsPduFromFile(const std::string &fileName, std::string &mmsPdu)
76 {
77 char realPath[PATH_MAX] = { 0 };
78 if (fileName.empty() || realpath(fileName.c_str(), realPath) == nullptr) {
79 TELEPHONY_LOGE("path or realPath is nullptr");
80 return false;
81 }
82
83 FILE *pFile = fopen(realPath, "rb");
84 if (pFile == nullptr) {
85 TELEPHONY_LOGE("openFile Error");
86 return false;
87 }
88
89 (void)fseek(pFile, 0, SEEK_END);
90 long fileLen = ftell(pFile);
91 if (fileLen <= 0 || fileLen > static_cast<long>(MMS_PDU_MAX_SIZE)) {
92 (void)fclose(pFile);
93 TELEPHONY_LOGE("fileLen Over Max Error");
94 return false;
95 }
96
97 std::unique_ptr<char[]> pduBuffer = std::make_unique<char[]>(fileLen);
98 if (!pduBuffer) {
99 (void)fclose(pFile);
100 TELEPHONY_LOGE("make unique pduBuffer nullptr Error");
101 return false;
102 }
103 (void)fseek(pFile, 0, SEEK_SET);
104 int32_t totolLength = static_cast<int32_t>(fread(pduBuffer.get(), 1, MMS_PDU_MAX_SIZE, pFile));
105 TELEPHONY_LOGI("fread totolLength%{private}d", totolLength);
106
107 long i = 0;
108 while (i < fileLen) {
109 mmsPdu += pduBuffer[i];
110 i++;
111 }
112 (void)fclose(pFile);
113 return true;
114 }
115
StoreSendMmsPduToDataBase(std::shared_ptr<NapiMmsPduHelper> helper)116 void StoreSendMmsPduToDataBase(std::shared_ptr<NapiMmsPduHelper> helper) __attribute__((no_sanitize("cfi")))
117 {
118 if (!helper) {
119 TELEPHONY_LOGE("mmsPduHelper is null");
120 return;
121 }
122 std::shared_ptr<NAPIMmsPdu> mmsPduObj = std::make_shared<NAPIMmsPdu>();
123 if (mmsPduObj == nullptr) {
124 TELEPHONY_LOGE("mmsPduObj nullptr");
125 helper->NotifyAll();
126 return;
127 }
128 std::string mmsPdu;
129 if (!GetMmsPduFromFile(helper->GetPduFileName(), mmsPdu)) {
130 TELEPHONY_LOGE("get mmsPdu fail");
131 helper->NotifyAll();
132 return;
133 }
134 mmsPduObj->InsertMmsPdu(*helper, mmsPdu);
135 }
136
UpdateTimeStamp(int64_t & timeStamp,MmsContext & context)137 void UpdateTimeStamp(int64_t &timeStamp, MmsContext &context)
138 {
139 context.timeStamp = timeStamp;
140 }
141
NativeSendMms(napi_env env,void * data)142 void NativeSendMms(napi_env env, void *data)
143 {
144 auto asyncContext = static_cast<MmsContext *>(data);
145 if (asyncContext == nullptr) {
146 TELEPHONY_LOGE("asyncContext nullptr");
147 return;
148 }
149 if (!TelephonyPermission::CheckCallerIsSystemApp()) {
150 TELEPHONY_LOGE("Non-system applications use system APIs!");
151 asyncContext->errorCode = TELEPHONY_ERR_ILLEGAL_USE_OF_SYSTEM_API;
152 return;
153 }
154 if (!STORE_MMS_PDU_TO_FILE) {
155 std::string pduFileName = NapiUtil::ToUtf8(asyncContext->data);
156 if (pduFileName.empty()) {
157 asyncContext->errorCode = TELEPHONY_ERR_ARGUMENT_INVALID;
158 asyncContext->resolved = false;
159 TELEPHONY_LOGE("pduFileName empty");
160 return;
161 }
162 if (g_datashareHelper == nullptr) {
163 asyncContext->errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
164 asyncContext->resolved = false;
165 TELEPHONY_LOGE("g_datashareHelper is nullptr");
166 return;
167 }
168 std::shared_ptr<NapiMmsPduHelper> helper = std::make_shared<NapiMmsPduHelper>();
169 helper->SetDataShareHelper(g_datashareHelper);
170 helper->SetPduFileName(pduFileName);
171 if (!helper->Run(StoreSendMmsPduToDataBase, helper)) {
172 TELEPHONY_LOGE("StoreMmsPdu fail");
173 asyncContext->errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
174 asyncContext->resolved = false;
175 return;
176 }
177 asyncContext->data = NapiUtil::ToUtf16(helper->GetDbUrl());
178 }
179 asyncContext->errorCode =
180 Singleton<SmsServiceManagerClient>::GetInstance().SendMms(asyncContext->slotId, asyncContext->mmsc,
181 asyncContext->data, asyncContext->mmsConfig.userAgent,
182 asyncContext->mmsConfig.userAgentProfile, asyncContext->timeStamp);
183 if (asyncContext->errorCode == TELEPHONY_ERR_SUCCESS) {
184 asyncContext->resolved = true;
185 } else {
186 asyncContext->resolved = false;
187 }
188 TELEPHONY_LOGI("NativeSendMms end resolved = %{public}d", asyncContext->resolved);
189 }
190
SendMmsCallback(napi_env env,napi_status status,void * data)191 void SendMmsCallback(napi_env env, napi_status status, void *data)
192 {
193 auto context = static_cast<MmsContext *>(data);
194 if (context == nullptr) {
195 TELEPHONY_LOGE("SendMmsCallback context nullptr");
196 return;
197 }
198 napi_value callbackValue = nullptr;
199 if (context->resolved) {
200 napi_get_undefined(env, &callbackValue);
201 } else {
202 JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
203 context->errorCode, "sendMms", "ohos.permission.SEND_MESSAGES");
204 callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
205 }
206 NapiUtil::Handle1ValueCallback(env, context, callbackValue);
207 }
208
MatchMmsParameters(napi_env env,napi_value parameters[],size_t parameterCount)209 bool MatchMmsParameters(napi_env env, napi_value parameters[], size_t parameterCount)
210 {
211 bool typeMatch = false;
212 switch (parameterCount) {
213 case TWO_PARAMETERS: {
214 typeMatch = NapiUtil::MatchParameters(env, parameters, { napi_object, napi_object });
215 break;
216 }
217 case THREE_PARAMETERS: {
218 typeMatch = NapiUtil::MatchParameters(env, parameters, { napi_object, napi_object, napi_function });
219 break;
220 }
221 default: {
222 break;
223 }
224 }
225 if (typeMatch) {
226 return NapiUtil::MatchObjectProperty(env, parameters[1],
227 {
228 { "slotId", napi_number },
229 { "mmsc", napi_string },
230 { "data", napi_string },
231 { "mmsConfig", napi_object },
232 });
233 }
234 return false;
235 }
236
GetMmsValueLength(napi_env env,napi_value param)237 static bool GetMmsValueLength(napi_env env, napi_value param)
238 {
239 size_t len = 0;
240 napi_status status = napi_get_value_string_utf8(env, param, nullptr, 0, &len);
241 if (status != napi_ok) {
242 TELEPHONY_LOGE("Get length failed");
243 return false;
244 }
245 return (len > 0) && (len < BUFF_LENGTH);
246 }
247
GetMmsNameProperty(napi_env env,napi_value param,MmsContext & context)248 static void GetMmsNameProperty(napi_env env, napi_value param, MmsContext &context)
249 {
250 napi_value slotIdValue = NapiUtil::GetNamedProperty(env, param, "slotId");
251 if (slotIdValue != nullptr) {
252 napi_get_value_int32(env, slotIdValue, &(context.slotId));
253 }
254 napi_value mmscValue = NapiUtil::GetNamedProperty(env, param, "mmsc");
255 if (mmscValue != nullptr && GetMmsValueLength(env, mmscValue)) {
256 char strChars[NORMAL_STRING_SIZE] = { 0 };
257 size_t strLength = 0;
258 napi_get_value_string_utf8(env, mmscValue, strChars, BUFF_LENGTH, &strLength);
259 std::string str8(strChars, strLength);
260 context.mmsc = NapiUtil::ToUtf16(str8);
261 }
262 napi_value dataValue = NapiUtil::GetNamedProperty(env, param, "data");
263 if (dataValue != nullptr && GetMmsValueLength(env, dataValue)) {
264 char strChars[NORMAL_STRING_SIZE] = { 0 };
265 size_t strLength = 0;
266 napi_get_value_string_utf8(env, dataValue, strChars, BUFF_LENGTH, &strLength);
267 std::string str8(strChars, strLength);
268 context.data = NapiUtil::ToUtf16(str8);
269 }
270 napi_value configValue = NapiUtil::GetNamedProperty(env, param, "mmsConfig");
271 if (configValue != nullptr) {
272 napi_value uaValue = NapiUtil::GetNamedProperty(env, configValue, "userAgent");
273 if (uaValue != nullptr && GetMmsValueLength(env, uaValue)) {
274 char strChars[NORMAL_STRING_SIZE] = { 0 };
275 size_t strLength = 0;
276 napi_get_value_string_utf8(env, uaValue, strChars, BUFF_LENGTH, &strLength);
277 std::string str8(strChars, strLength);
278 context.mmsConfig.userAgent = NapiUtil::ToUtf16(str8);
279 }
280 napi_value uaprofValue = NapiUtil::GetNamedProperty(env, configValue, "userAgentProfile");
281 if (uaprofValue != nullptr && GetMmsValueLength(env, uaprofValue)) {
282 char strChars[NORMAL_STRING_SIZE] = { 0 };
283 size_t strLength = 0;
284 napi_get_value_string_utf8(env, uaprofValue, strChars, BUFF_LENGTH, &strLength);
285 std::string str8(strChars, strLength);
286 context.mmsConfig.userAgentProfile = NapiUtil::ToUtf16(str8);
287 }
288 }
289 }
290
SendMms(napi_env env,napi_callback_info info)291 napi_value NapiSendRecvMms::SendMms(napi_env env, napi_callback_info info)
292 {
293 size_t parameterCount = THREE_PARAMETERS;
294 napi_value parameters[THREE_PARAMETERS] = { 0 };
295 napi_value thisVar = nullptr;
296 void *data = nullptr;
297 int64_t timeStamp =
298 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
299 .count();
300 napi_get_cb_info(env, info, ¶meterCount, parameters, &thisVar, &data);
301 if (!MatchMmsParameters(env, parameters, parameterCount)) {
302 TELEPHONY_LOGE("parameter matching failed.");
303 NapiUtil::ThrowParameterError(env);
304 return nullptr;
305 }
306 auto context = std::make_unique<MmsContext>().release();
307 if (context == nullptr) {
308 TELEPHONY_LOGE("MmsContext is nullptr.");
309 NapiUtil::ThrowParameterError(env);
310 return nullptr;
311 }
312 if (!STORE_MMS_PDU_TO_FILE) {
313 g_datashareHelper = GetDataShareHelper(env, info);
314 }
315 GetMmsNameProperty(env, parameters[1], *context);
316 if (parameterCount == THREE_PARAMETERS) {
317 napi_create_reference(env, parameters[PARAMETERS_INDEX_TWO], DEFAULT_REF_COUNT, &context->callbackRef);
318 }
319 UpdateTimeStamp(timeStamp, *context);
320 napi_value result = NapiUtil::HandleAsyncWork(env, context, "SendMms", NativeSendMms, SendMmsCallback);
321 return result;
322 }
323
WriteBufferToFile(const std::unique_ptr<char[]> & buff,uint32_t len,const std::string & strPathName)324 bool WriteBufferToFile(const std::unique_ptr<char[]> &buff, uint32_t len, const std::string &strPathName)
325 {
326 if (buff == nullptr) {
327 TELEPHONY_LOGE("buff nullptr");
328 return false;
329 }
330
331 char realPath[PATH_MAX] = { 0 };
332 if (strPathName.empty() || realpath(strPathName.c_str(), realPath) == nullptr) {
333 TELEPHONY_LOGE("path or realPath is nullptr");
334 return false;
335 }
336
337 FILE *pFile = fopen(realPath, "wb");
338 if (pFile == nullptr) {
339 TELEPHONY_LOGE("openFile Error");
340 return false;
341 }
342 uint32_t fileLen = fwrite(buff.get(), len, 1, pFile);
343 (void)fclose(pFile);
344 if (fileLen > 0) {
345 TELEPHONY_LOGI("write mms buffer to file success");
346 return true;
347 } else {
348 TELEPHONY_LOGI("write mms buffer to file error");
349 return false;
350 }
351 }
352
StoreMmsPduToFile(const std::string & fileName,const std::string & mmsPdu)353 bool StoreMmsPduToFile(const std::string &fileName, const std::string &mmsPdu)
354 {
355 uint32_t len = static_cast<uint32_t>(mmsPdu.size());
356 if (len > MMS_PDU_MAX_SIZE || len == 0) {
357 TELEPHONY_LOGE("MMS pdu length invalid");
358 return false;
359 }
360
361 std::unique_ptr<char[]> resultResponse = std::make_unique<char[]>(len);
362 if (memset_s(resultResponse.get(), len, 0x00, len) != EOK) {
363 TELEPHONY_LOGE("memset_s err");
364 return false;
365 }
366 if (memcpy_s(resultResponse.get(), len, &mmsPdu[0], len) != EOK) {
367 TELEPHONY_LOGE("memcpy_s error");
368 return false;
369 }
370
371 TELEPHONY_LOGI("len:%{public}d", len);
372 if (!WriteBufferToFile(std::move(resultResponse), len, fileName)) {
373 TELEPHONY_LOGE("write to file error");
374 return false;
375 }
376 return true;
377 }
378
GetMmsPduFromDataBase(std::shared_ptr<NapiMmsPduHelper> helper)379 void GetMmsPduFromDataBase(std::shared_ptr<NapiMmsPduHelper> helper) __attribute__((no_sanitize("cfi")))
380 {
381 if (!helper) {
382 TELEPHONY_LOGE("mmsPduHelper is null");
383 return;
384 }
385 NAPIMmsPdu mmsPduObj;
386 std::string mmsPdu = mmsPduObj.GetMmsPdu(*helper);
387 if (mmsPdu.empty()) {
388 TELEPHONY_LOGE("from dataBase empty");
389 return;
390 }
391
392 mmsPduObj.DeleteMmsPdu(*helper);
393 if (!StoreMmsPduToFile(helper->GetStoreFileName(), mmsPdu)) {
394 TELEPHONY_LOGE("store mmsPdu fail");
395 }
396 helper->NotifyAll();
397 }
398
DownloadExceptionCase(MmsContext & context,std::shared_ptr<OHOS::DataShare::DataShareHelper> g_datashareHelper)399 static bool DownloadExceptionCase(
400 MmsContext &context, std::shared_ptr<OHOS::DataShare::DataShareHelper> g_datashareHelper)
401 {
402 if (!TelephonyPermission::CheckCallerIsSystemApp()) {
403 TELEPHONY_LOGE("Non-system applications use system APIs!");
404 context.errorCode = TELEPHONY_ERR_ILLEGAL_USE_OF_SYSTEM_API;
405 context.resolved = false;
406 return false;
407 }
408 if (g_datashareHelper == nullptr) {
409 TELEPHONY_LOGE("g_datashareHelper is nullptr");
410 context.errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
411 context.resolved = false;
412 return false;
413 }
414 std::string fileName = NapiUtil::ToUtf8(context.data);
415 char realPath[PATH_MAX] = { 0 };
416 if (fileName.empty() || realpath(fileName.c_str(), realPath) == nullptr) {
417 TELEPHONY_LOGE("path or realPath is nullptr");
418 context.errorCode = TELEPHONY_ERR_ARGUMENT_INVALID;
419 context.resolved = false;
420 return false;
421 }
422 FILE *pFile = fopen(realPath, "wb");
423 if (pFile == nullptr) {
424 TELEPHONY_LOGE("openFile Error");
425 context.errorCode = TELEPHONY_ERR_ARGUMENT_INVALID;
426 context.resolved = false;
427 return false;
428 }
429 (void)fclose(pFile);
430 return true;
431 }
432
UpdateReqCount()433 void UpdateReqCount()
434 {
435 std::unique_lock<std::mutex> lck(NapiSendRecvMms::countCtx_);
436 NapiSendRecvMms::reqCount_++;
437 TELEPHONY_LOGI("reqCount_:%{public}d", NapiSendRecvMms::reqCount_);
438 }
439
DecreaseReqCount()440 void DecreaseReqCount()
441 {
442 NapiSendRecvMms::reqCount_--;
443 if (NapiSendRecvMms::reqCount_ > 0) {
444 NapiSendRecvMms::waitFlag = true;
445 } else {
446 NapiSendRecvMms::waitFlag = false;
447 }
448 }
449
NativeDownloadMms(napi_env env,void * data)450 void NativeDownloadMms(napi_env env, void *data)
451 {
452 auto asyncContext = static_cast<MmsContext *>(data);
453 if (asyncContext == nullptr) {
454 TELEPHONY_LOGE("asyncContext nullptr");
455 return;
456 }
457 if (!DownloadExceptionCase(*asyncContext, g_datashareHelper)) {
458 TELEPHONY_LOGE("Exception case");
459 return;
460 }
461
462 TELEPHONY_LOGI("native download mms");
463 UpdateReqCount();
464 std::unique_lock<std::mutex> lck(NapiSendRecvMms::downloadCtx_);
465 if (NapiSendRecvMms::waitFlag) {
466 TELEPHONY_LOGI("down multiple mms at once wait");
467 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_PDN_TOGGLE_TIME));
468 }
469 std::u16string dbUrls;
470 asyncContext->errorCode =
471 Singleton<SmsServiceManagerClient>::GetInstance().DownloadMms(asyncContext->slotId, asyncContext->mmsc,
472 dbUrls, asyncContext->mmsConfig.userAgent, asyncContext->mmsConfig.userAgentProfile);
473 TELEPHONY_LOGI("NativeDownloadMms dbUrls:%{public}s", NapiUtil::ToUtf8(dbUrls).c_str());
474 if (asyncContext->errorCode == TELEPHONY_ERR_SUCCESS) {
475 asyncContext->resolved = true;
476 if (!STORE_MMS_PDU_TO_FILE) {
477 std::shared_ptr<NapiMmsPduHelper> helper = std::make_shared<NapiMmsPduHelper>();
478 helper->SetDataShareHelper(g_datashareHelper);
479 helper->SetDbUrl(NapiUtil::ToUtf8(dbUrls));
480 helper->SetStoreFileName(NapiUtil::ToUtf8(asyncContext->data));
481 if (!helper->Run(GetMmsPduFromDataBase, helper)) {
482 TELEPHONY_LOGE("StoreMmsPdu fail");
483 asyncContext->errorCode = TELEPHONY_ERR_LOCAL_PTR_NULL;
484 asyncContext->resolved = false;
485 return;
486 }
487 }
488 } else {
489 asyncContext->resolved = false;
490 }
491 DecreaseReqCount();
492 TELEPHONY_LOGI("NativeDownloadMms end resolved = %{public}d", asyncContext->resolved);
493 }
494
DownloadMmsCallback(napi_env env,napi_status status,void * data)495 void DownloadMmsCallback(napi_env env, napi_status status, void *data)
496 {
497 auto context = static_cast<MmsContext *>(data);
498 if (context == nullptr) {
499 TELEPHONY_LOGE("SendMmsCallback context nullptr");
500 return;
501 }
502 napi_value callbackValue = nullptr;
503 if (context->resolved) {
504 napi_get_undefined(env, &callbackValue);
505 } else {
506 JsError error = NapiUtil::ConverErrorMessageWithPermissionForJs(
507 context->errorCode, "downloadMms", "ohos.permission.RECEIVE_MMS");
508 callbackValue = NapiUtil::CreateErrorMessage(env, error.errorMessage, error.errorCode);
509 }
510 NapiUtil::Handle1ValueCallback(env, context, callbackValue);
511 }
512
DownloadMms(napi_env env,napi_callback_info info)513 napi_value NapiSendRecvMms::DownloadMms(napi_env env, napi_callback_info info)
514 {
515 size_t parameterCount = THREE_PARAMETERS;
516 napi_value parameters[THREE_PARAMETERS] = { 0 };
517 napi_value thisVar = nullptr;
518 void *data = nullptr;
519
520 napi_get_cb_info(env, info, ¶meterCount, parameters, &thisVar, &data);
521 if (!MatchMmsParameters(env, parameters, parameterCount)) {
522 TELEPHONY_LOGE("DownloadMms parameter matching failed.");
523 NapiUtil::ThrowParameterError(env);
524 return nullptr;
525 }
526 auto context = std::make_unique<MmsContext>().release();
527 if (context == nullptr) {
528 TELEPHONY_LOGE("DownloadMms MmsContext is nullptr.");
529 NapiUtil::ThrowParameterError(env);
530 return nullptr;
531 }
532 if (!STORE_MMS_PDU_TO_FILE) {
533 g_datashareHelper = GetDataShareHelper(env, info);
534 }
535 GetMmsNameProperty(env, parameters[1], *context);
536 if (parameterCount == THREE_PARAMETERS) {
537 napi_create_reference(env, parameters[PARAMETERS_INDEX_TWO], DEFAULT_REF_COUNT, &context->callbackRef);
538 }
539 napi_value result = NapiUtil::HandleAsyncWork(env, context, "DownloadMms", NativeDownloadMms, DownloadMmsCallback);
540 return result;
541 }
542 } // namespace Telephony
543 } // namespace OHOS
544