* Copyright (C) 2021-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sms_persist_helper.h"
#include <sstream>
#include "ability_manager_interface.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "parameter.h"
#include "phonenumbers/phonenumber.pb.h"
#include "resource_manager.h"
#include "string_utils.h"
#include "system_ability.h"
#include "system_ability_definition.h"
#include "telephony_errors.h"
#include "telephony_log_wrapper.h"
namespace OHOS {
namespace Telephony {
constexpr static uint8_t SMS_TYPE_CDMA = 2;
const std::string SMS_URI = "datashare:///com.ohos.smsmmsability";
const std::string SMS_SUBSECTION = "datashare:///com.ohos.smsmmsability/sms_mms/sms_subsection";
const std::string SMS_MMS_INFO = "datashare:///com.ohos.smsmmsability/sms_mms/sms_mms_info";
const std::string SMS_SESSION = "datashare:///com.ohos.smsmmsability/sms_mms/session";
const std::string CONTACT_URI = "datashare:///com.ohos.contactsdataability";
const std::string CONTACT_BLOCK = "datashare:///com.ohos.contactsdataability/contacts/contact_blocklist";
const std::string CONTACT_DATA = "datashare:///com.ohos.contactsdataability/contacts/contact_data";
const std::string RAW_CONTACT = "datashare:///com.ohos.contactsdataability/contacts/raw_contact";
const std::string ISO_COUNTRY_CODE = "CN";
const std::string PHONE_NUMBER = "phone_number";
const std::string DETAIL_INFO = "detail_info";
const std::string TYPE_ID = "type_id";
std::string g_id = "id";
const std::string RAW_CONTACT_ID = "raw_contact_id";
const std::string CONTACTED_COUNT = "contacted_count";
const std::string LASTEST_CONTACTED_TIME = "lastest_contacted_time";
constexpr static uint8_t TYPE_ID_VALUE = 5;
const std::string PREFIX = "+86";
const std::string NUMBER_START_STR = "192";
constexpr uint32_t EVENT_RELEASE_DATA_SHARE_HELPER = 10000;
constexpr int64_t RELEASE_DATA_SHARE_HELPER_TIMEOUT = 5000;
static std::shared_ptr<AppExecFwk::EventRunner> smsPersistHelperEventRunner_ =
AppExecFwk::EventRunner::Create("SmsPersistHelper");
SmsPersistHelper::SmsPersistHelper() : AppExecFwk::EventHandler(smsPersistHelperEventRunner_) {}
SmsPersistHelper::~SmsPersistHelper() {}
std::shared_ptr<DataShare::DataShareHelper> SmsPersistHelper::CreateSmsHelper()
{
std::lock_guard<ffrt::mutex> lock(mutex_);
RemoveEvent(EVENT_RELEASE_DATA_SHARE_HELPER);
SendEvent(EVENT_RELEASE_DATA_SHARE_HELPER, 0, RELEASE_DATA_SHARE_HELPER_TIMEOUT);
if (smsDataShareHelper_ == nullptr) {
smsDataShareHelper_ = CreateDataShareHelper(SMS_URI);
}
return smsDataShareHelper_;
}
std::shared_ptr<DataShare::DataShareHelper> SmsPersistHelper::CreateDataShareHelper(const std::string &uri)
{
auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (saManager == nullptr) {
TELEPHONY_LOGE(" Get system ability mgr failed.");
return nullptr;
}
auto remoteObj = saManager->GetSystemAbility(TELEPHONY_SMS_MMS_SYS_ABILITY_ID);
if (remoteObj == nullptr) {
TELEPHONY_LOGE("GetSystemAbility Service Failed.");
return nullptr;
}
return DataShare::DataShareHelper::Creator(remoteObj, uri);
}
bool SmsPersistHelper::Insert(DataShare::DataShareValuesBucket &values, int32_t &dataBaseId)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_SUBSECTION);
int ret = helper->Insert(uri, values);
dataBaseId = ret;
TELEPHONY_LOGI("Insert result: %{public}d.", ret);
return ret >= 0 ? true : false;
}
bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(tableUri);
int ret = helper->Insert(uri, values);
TELEPHONY_LOGI("Insert result: %{public}d.", ret);
return ret >= 0 ? true : false;
}
bool SmsPersistHelper::Insert(std::string tableUri, DataShare::DataShareValuesBucket &values, int32_t &id)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(tableUri);
int ret = helper->Insert(uri, values);
id = ret;
TELEPHONY_LOGI("Insert result: %{public}d.", ret);
return ret >= 0;
}
bool SmsPersistHelper::IsSameFormatPhoneNumber(const std::string &phoneNum, const std::string &telephone,
i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat format)
{
std::string formatPhoneNum;
std::string formatTelephone;
FormatSmsNumber(phoneNum, ISO_COUNTRY_CODE, format, formatPhoneNum);
FormatSmsNumber(telephone, ISO_COUNTRY_CODE, format, formatTelephone);
return formatPhoneNum == formatTelephone;
}
bool SmsPersistHelper::QueryOneSessionByPhoneNum(DataShare::DataSharePredicates &predicates,
uint16_t &sessionId, uint16_t &messageCount, const std::string &phoneNum)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_SESSION);
std::vector<std::string> columns;
auto resultSet = helper->Query(uri, predicates, columns);
if (resultSet == nullptr) {
TELEPHONY_LOGE("Query Result Set nullptr Failed.");
return false;
}
int32_t result = resultSet->GoToFirstRow();
int32_t columnInt;
std::string columnString;
int columnIndex;
std::string telephone = "";
while (result == DataShare::E_OK) {
resultSet->GetColumnIndex("telephone", columnIndex);
if (resultSet->GetString(columnIndex, columnString) == 0) {
telephone = columnString;
}
if (!IsSameFormatPhoneNumber(phoneNum, telephone,
i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL) && !IsSameFormatPhoneNumber(phoneNum,
telephone, i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::E164)) {
TELEPHONY_LOGI("QueryOneSessionByPhoneNum not same format phone number");
result = resultSet->GoToNextRow();
continue;
}
resultSet->GetColumnIndex("id", columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
sessionId = static_cast<uint16_t>(columnInt);
}
resultSet->GetColumnIndex("message_count", columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
messageCount = static_cast<uint16_t>(columnInt);
resultSet->Close();
return true;
}
break;
}
resultSet->Close();
return false;
}
bool SmsPersistHelper::UpdateSms(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_MMS_INFO);
int ret = helper->Update(uri, predicates, values);
TELEPHONY_LOGI("UpdateSms result: %{public}d.", ret);
return ret >= 0;
}
bool SmsPersistHelper::QuerySmsMmsForId(DataShare::DataSharePredicates &predicates, int32_t &dataBaseId)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_MMS_INFO);
std::vector<std::string> columns;
auto resultSet = helper->Query(uri, predicates, columns);
if (resultSet == nullptr) {
TELEPHONY_LOGE("Query Result Set nullptr Failed.");
return false;
}
resultSet->GoToFirstRow();
int32_t columnInt;
int columnIndex;
resultSet->GetColumnIndex(SmsMmsInfo::MSG_ID, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
dataBaseId = columnInt;
}
resultSet->Close();
return true;
}
bool SmsPersistHelper::Update(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_SESSION);
int ret = helper->Update(uri, predicates, values);
TELEPHONY_LOGI("Update result: %{public}d.", ret);
return ret >= 0 ? true : false;
}
bool SmsPersistHelper::Query(DataShare::DataSharePredicates &predicates, std::vector<SmsReceiveIndexer> &indexers)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_SUBSECTION);
std::vector<std::string> columns;
auto resultSet = helper->Query(uri, predicates, columns);
if (resultSet == nullptr) {
TELEPHONY_LOGE("Query Result Set nullptr Failed.");
return false;
}
int resultSetNum = resultSet->GoToFirstRow();
TELEPHONY_LOGE("resultSetNum is %{public}d before cycle", resultSetNum);
while (resultSetNum == 0) {
SmsReceiveIndexer indexer;
ResultSetConvertToIndexer(indexer, resultSet);
indexers.push_back(indexer);
resultSetNum = resultSet->GoToNextRow();
TELEPHONY_LOGE("resultSetNum is %{public}d in cycle", resultSetNum);
}
resultSet->Close();
return true;
}
bool SmsPersistHelper::QueryMaxGroupId(DataShare::DataSharePredicates &predicates, uint16_t &maxGroupId)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_MMS_INFO);
std::vector<std::string> columns;
auto resultSet = helper->Query(uri, predicates, columns);
if (resultSet == nullptr) {
TELEPHONY_LOGE("Query Result Set nullptr Failed.");
return false;
}
int32_t columnInt;
int columnIndex;
resultSet->GoToLastRow();
resultSet->GetColumnIndex(SmsMmsInfo::GROUP_ID, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
maxGroupId = columnInt;
}
resultSet->Close();
return true;
}
bool SmsPersistHelper::Delete(DataShare::DataSharePredicates &predicates)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper();
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(SMS_SUBSECTION);
int ret = helper->Delete(uri, predicates);
TELEPHONY_LOGI("Delete result: %{public}d.", ret);
return ret >= 0 ? true : false;
}
bool SmsPersistHelper::QueryBlockPhoneNumber(const std::string &phoneNum)
{
bool result = false;
if (phoneNum.empty()) {
return result;
}
return result;
}
int32_t SmsPersistHelper::FormatSmsNumber(const std::string &num, std::string countryCode,
const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
{
if (num.empty()) {
TELEPHONY_LOGE("num is nullptr!");
return TELEPHONY_ERR_ARGUMENT_INVALID;
}
i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
if (phoneUtils == nullptr) {
TELEPHONY_LOGE("phoneUtils is nullptr");
return TELEPHONY_ERR_LOCAL_PTR_NULL;
}
transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
i18n::phonenumbers::PhoneNumber parseResult;
phoneUtils->Parse(num, countryCode, &parseResult);
if (phoneUtils->IsValidNumber(parseResult)) {
phoneUtils->Format(parseResult, formatInfo, &formatNum);
} else {
std::string numTemp = "";
numTemp.assign(num);
CbnFormat(numTemp, formatInfo, formatNum);
}
if (formatNum.empty() || formatNum == "0") {
return TELEPHONY_ERROR;
}
TrimSpace(formatNum);
return TELEPHONY_SUCCESS;
}
void SmsPersistHelper::CbnFormat(std::string &numTemp,
const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNum)
{
TELEPHONY_LOGD("into CbnFormat");
uint8_t minLength = 3;
if (numTemp.size() < minLength) {
TELEPHONY_LOGD("Phonenumber is too short");
return;
}
if (numTemp.substr(0, NUMBER_START_STR.size()) == NUMBER_START_STR ||
numTemp.substr(PREFIX.size(), NUMBER_START_STR.size()) == NUMBER_START_STR) {
if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL) {
if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
numTemp.erase(0, PREFIX.size());
formatNum.assign(numTemp);
return;
}
formatNum.assign(numTemp);
return;
}
if (formatInfo == i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL) {
if (numTemp.substr(0, PREFIX.size()) == PREFIX) {
formatNum.assign(numTemp);
return;
}
formatNum.assign(PREFIX + numTemp);
}
}
}
void SmsPersistHelper::TrimSpace(std::string &num)
{
std::string word;
std::stringstream streamNum(num);
std::string store;
while (streamNum >> word) {
store += word;
}
num = store;
}
bool SmsPersistHelper::UpdateContact(const std::string &address)
{
bool result = false;
if (address.empty()) {
TELEPHONY_LOGE("address empty");
return result;
}
int32_t rawCountId = 0;
int32_t contactedCount = 0;
bool ret = QueryContactedCount(address, rawCountId, contactedCount);
if (!ret) {
TELEPHONY_LOGE("get contacted count fail");
return result;
}
TELEPHONY_LOGI("rawCountId:%{public}d, contactedCount:%{public}d", rawCountId, contactedCount);
std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
std::time_t timep;
int64_t currentTime = time(&timep);
Uri uri(RAW_CONTACT);
DataShare::DataSharePredicates predicates;
predicates.EqualTo(g_id, rawCountId);
DataShare::DataShareValuesBucket bucket;
bucket.Put(CONTACTED_COUNT, contactedCount + 1);
bucket.Put(LASTEST_CONTACTED_TIME, std::to_string(currentTime));
auto updateValue = helper->Update(uri, predicates, bucket);
TELEPHONY_LOGI("updateValue:%{public}d", updateValue);
helper->Release();
return updateValue >= 0 ? true : false;
}
bool SmsPersistHelper::QueryContactedCount(const std::string &address, int32_t &rawCountId, int32_t &contactedCount)
{
bool ret = QueryRawContactId(address, rawCountId);
if (!ret) {
TELEPHONY_LOGE("no sms address in contact");
return ret;
}
std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(RAW_CONTACT);
std::vector<std::string> columns;
DataShare::DataSharePredicates predicates;
predicates.EqualTo(g_id, rawCountId);
auto resultSet = helper->Query(uri, predicates, columns);
bool result = false;
if (resultSet == nullptr) {
TELEPHONY_LOGE("result set nullptr.");
helper->Release();
return result;
}
int32_t count = 0;
if (resultSet->GetRowCount(count) == 0 && count != 0) {
resultSet->GoToFirstRow();
int columnIndex;
resultSet->GetColumnIndex(CONTACTED_COUNT, columnIndex);
if (resultSet->GetInt(columnIndex, contactedCount) == 0) {
result = true;
}
}
resultSet->Close();
helper->Release();
return result;
}
bool SmsPersistHelper::QueryRawContactId(const std::string &address, int32_t &rawCountId)
{
std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
if (helper == nullptr) {
TELEPHONY_LOGE("Create Data Ability Helper nullptr Failed.");
return false;
}
Uri uri(CONTACT_DATA);
std::vector<std::string> columns;
DataShare::DataSharePredicates predicates;
std::string nationalNum;
std::string internationalNum;
int32_t ret = FormatSmsNumber(
address, ISO_COUNTRY_CODE, i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL, nationalNum);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("Phone Number format Failed.");
nationalNum = address;
}
ret = FormatSmsNumber(address, ISO_COUNTRY_CODE,
i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL, internationalNum);
if (ret != TELEPHONY_SUCCESS) {
TELEPHONY_LOGE("Phone Number format Failed.");
internationalNum = address;
}
predicates.EqualTo(DETAIL_INFO, nationalNum)->Or()->EqualTo(DETAIL_INFO, internationalNum);
predicates.EqualTo(TYPE_ID, TYPE_ID_VALUE);
auto resultSet = helper->Query(uri, predicates, columns);
bool result = false;
if (resultSet == nullptr) {
TELEPHONY_LOGE("result set nullptr.");
helper->Release();
return result;
}
int32_t count = 0;
if (resultSet->GetRowCount(count) == 0 && count != 0) {
resultSet->GoToFirstRow();
int columnIndex;
resultSet->GetColumnIndex(RAW_CONTACT_ID, columnIndex);
if (resultSet->GetInt(columnIndex, rawCountId) == 0) {
result = true;
}
}
resultSet->Close();
helper->Release();
return result;
}
bool SmsPersistHelper::QueryParamBoolean(const std::string key, bool defValue)
{
const int PARAM_SIZE = 64;
char paramOutBuff[PARAM_SIZE] = { 0 };
std::string defStrValue = defValue ? "1" : "0";
std::string paramValue(defStrValue);
int retLen = GetParameter(key.c_str(), defStrValue.c_str(), paramOutBuff, PARAM_SIZE);
if (retLen > 0) {
paramOutBuff[retLen] = '\0';
paramValue.assign(paramOutBuff, retLen);
}
TELEPHONY_LOGI("QueryParamBoolean: %{public}zu : %{public}s", paramValue.size(), paramValue.c_str());
if ((paramValue == std::string("1")) || (paramValue == std::string("y")) || (paramValue == std::string("yes")) ||
(paramValue == std::string("on")) || (paramValue == std::string("true"))) {
return true;
} else if ((paramValue == std::string("0")) || (paramValue == std::string("n")) ||
(paramValue == std::string("no")) || (paramValue == std::string("off")) ||
(paramValue == std::string("false"))) {
return false;
}
return defValue;
}
void SmsPersistHelper::ConvertIntToIndexer(
SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
int32_t columnInt;
int columnIndex;
resultSet->GetColumnIndex(SmsSubsection::FORMAT, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetIsCdma(columnInt == SMS_TYPE_CDMA);
}
resultSet->GetColumnIndex(SmsSubsection::SMS_SUBSECTION_ID, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetMsgRefId(columnInt);
}
resultSet->GetColumnIndex(SmsSubsection::SIZE, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetMsgCount(columnInt);
}
resultSet->GetColumnIndex(SmsSubsection::SUBSECTION_INDEX, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetMsgSeqId(columnInt);
}
resultSet->GetColumnIndex(SmsSubsection::DEST_PORT, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetDestPort(columnInt);
}
resultSet->GetColumnIndex(SmsSubsection::ID, columnIndex);
if (resultSet->GetInt(columnIndex, columnInt) == 0) {
info.SetDataBaseId(columnInt);
}
}
void SmsPersistHelper::ConvertStringToIndexer(
SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
int columnIndex;
std::string columnValue;
resultSet->GetColumnIndex(SmsSubsection::RECEIVER_NUMBER, columnIndex);
if (resultSet->GetString(columnIndex, columnValue) == 0) {
info.SetVisibleAddress(columnValue);
}
resultSet->GetColumnIndex(SmsSubsection::SENDER_NUMBER, columnIndex);
if (resultSet->GetString(columnIndex, columnValue) == 0) {
info.SetOriginatingAddress(columnValue);
}
resultSet->GetColumnIndex(SmsSubsection::START_TIME, columnIndex);
if (resultSet->GetString(columnIndex, columnValue) == 0) {
std::istringstream str(columnValue);
int64_t columnValueInt64 = 0;
str >> columnValueInt64;
info.SetTimestamp(columnValueInt64);
}
resultSet->GetColumnIndex(SmsSubsection::END_TIME, columnIndex);
if (resultSet->GetString(columnIndex, columnValue) == 0) {
std::istringstream str(columnValue);
int64_t columnValueInt64 = 0;
str >> columnValueInt64;
info.SetTimestamp(columnValueInt64);
}
resultSet->GetColumnIndex(SmsSubsection::REW_PUD, columnIndex);
if (resultSet->GetString(columnIndex, columnValue) == 0) {
info.SetPdu(StringUtils::HexToByteVector(columnValue));
}
}
void SmsPersistHelper::ResultSetConvertToIndexer(
SmsReceiveIndexer &info, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
{
ConvertIntToIndexer(info, resultSet);
ConvertStringToIndexer(info, resultSet);
}
void SmsPersistHelper::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
{
if (event->GetInnerEventId() == EVENT_RELEASE_DATA_SHARE_HELPER) {
ReleaseDataShareHelper();
}
}
void SmsPersistHelper::ReleaseDataShareHelper()
{
std::lock_guard<ffrt::mutex> lock(mutex_);
if (smsDataShareHelper_ != nullptr) {
smsDataShareHelper_->Release();
}
smsDataShareHelper_ = nullptr;
}
}
}