• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &parameterCount, 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, &parameterCount, 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