1/* 2 * Copyright (c) 2021-2022 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 "sms_mms_ability.h" 17 18#include "ability_context.h" 19#include "ability_loader.h" 20#include "abs_rdb_predicates.h" 21#include "abs_shared_result_set.h" 22#include "data_storage_errors.h" 23#include "data_storage_log_wrapper.h" 24#include "datashare_ext_ability.h" 25#include "datashare_predicates.h" 26#include "new" 27#include "permission_util.h" 28#include "rdb_errno.h" 29#include "rdb_utils.h" 30#include "sms_mms_data.h" 31#include "telephony_datashare_stub_impl.h" 32#include "uri.h" 33#include "utility" 34 35namespace OHOS { 36using AppExecFwk::Ability; 37using AppExecFwk::AbilityLoader; 38namespace Telephony { 39const int32_t CHANGED_ROWS = 0; 40static const std::map<std::string, MessageUriType> smsMmsUriMap_ = { 41 { "/sms_mms/sms_mms_info", MessageUriType::SMS_MMS }, 42 { "/sms_mms/sms_mms_info/thirty", MessageUriType::THIRTY }, 43 { "/sms_mms/sms_mms_info/max_group", MessageUriType::MAX_GROUP }, 44 { "/sms_mms/sms_mms_info/unread_total", MessageUriType::UNREAD_TOTAL }, 45 { "/sms_mms/mms_protocol", MessageUriType::MMS_PROTOCOL }, 46 { "/sms_mms/sms_subsection", MessageUriType::SMS_SUBSECTION }, 47 { "/sms_mms/mms_part", MessageUriType::MMS_PART }, 48 { "/sms_mms/session", MessageUriType::SESSION }, 49 { "/sms_mms/mms_pdu", MessageUriType::MMS_PDU }, 50}; 51 52SmsMmsAbility::SmsMmsAbility() : DataShareExtAbility() {} 53 54SmsMmsAbility::~SmsMmsAbility() {} 55 56SmsMmsAbility* SmsMmsAbility::Create() 57{ 58 DATA_STORAGE_LOGD("SmsMmsAbility::Create begin."); 59 auto self = new SmsMmsAbility(); 60 self->DoInit(); 61 return self; 62} 63 64void SmsMmsAbility::DoInit() 65{ 66 if (initDatabaseDir && initRdbStore) { 67 DATA_STORAGE_LOGI("DoInit has done"); 68 return; 69 } 70 auto abilityContext = AbilityRuntime::Context::GetApplicationContext(); 71 if (abilityContext == nullptr) { 72 DATA_STORAGE_LOGE("DoInit GetAbilityContext is null"); 73 return; 74 } 75 // switch database dir to el1 for init before unlock 76 abilityContext->SwitchArea(0); 77 std::string path = abilityContext->GetDatabaseDir(); 78 if (!path.empty()) { 79 initDatabaseDir = true; 80 path.append("/"); 81 helper_.UpdateDbPath(path); 82 if (helper_.Init() == NativeRdb::E_OK) { 83 initRdbStore = true; 84 } else { 85 DATA_STORAGE_LOGE("DoInit rdb init failed!"); 86 initRdbStore = false; 87 } 88 } else { 89 DATA_STORAGE_LOGE("DoInit##databaseDir is empty!"); 90 initDatabaseDir = false; 91 } 92} 93 94sptr<IRemoteObject> SmsMmsAbility::OnConnect(const AAFwk::Want &want) 95{ 96 DATA_STORAGE_LOGI("SmsMmsAbility::OnConnect"); 97 Extension::OnConnect(want); 98 sptr<DataShare::TelephonyDataShareStubImpl> remoteObject = 99 new (std::nothrow) DataShare::TelephonyDataShareStubImpl(); 100 if (remoteObject == nullptr) { 101 DATA_STORAGE_LOGE("%{public}s No memory allocated for DataShareStubImpl", __func__); 102 return nullptr; 103 } 104 remoteObject->SetSmsMmsAbility(std::static_pointer_cast<SmsMmsAbility>(shared_from_this())); 105 DATA_STORAGE_LOGI("SmsMmsAbility %{public}s end.", __func__); 106 return remoteObject->AsObject(); 107} 108 109void SmsMmsAbility::OnStart(const AppExecFwk::Want &want) 110{ 111 DATA_STORAGE_LOGI("SmsMmsAbility::OnStart"); 112 Extension::OnStart(want); 113 DoInit(); 114} 115 116int SmsMmsAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value) 117{ 118 if (!PermissionUtil::CheckPermission(Permission::READ_MESSAGES)) { 119 DATA_STORAGE_LOGE("Permission denied!"); 120 return DATA_STORAGE_ERR_PERMISSION_ERR; 121 } 122 if (!IsInitOk()) { 123 return DATA_STORAGE_ERROR; 124 } 125 std::lock_guard<std::mutex> guard(lock_); 126 Uri tempUri = uri; 127 MessageUriType messageUriType = ParseUriType(tempUri); 128 int64_t id = DATA_STORAGE_ERROR; 129 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value); 130 switch (messageUriType) { 131 case MessageUriType::SMS_MMS: { 132 helper_.Insert(id, values, TABLE_SMS_MMS_INFO); 133 break; 134 } 135 case MessageUriType::MMS_PROTOCOL: { 136 helper_.Insert(id, values, TABLE_MMS_PROTOCOL); 137 break; 138 } 139 case MessageUriType::SMS_SUBSECTION: { 140 helper_.Insert(id, values, TABLE_SMS_SUBSECTION); 141 break; 142 } 143 case MessageUriType::MMS_PART: { 144 helper_.Insert(id, values, TABLE_MMS_PART); 145 break; 146 } 147 case MessageUriType::SESSION: { 148 helper_.Insert(id, values, TABLE_SESSION); 149 break; 150 } 151 case MessageUriType::MMS_PDU: { 152 helper_.Insert(id, values, TABLE_MMS_PDU); 153 break; 154 } 155 default: 156 DATA_STORAGE_LOGI("SmsMmsAbility::Insert##uri = %{public}s", uri.ToString().c_str()); 157 break; 158 } 159 return id; 160} 161 162std::shared_ptr<DataShare::DataShareResultSet> SmsMmsAbility::Query( 163 const Uri &uri, const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns, 164 DataShare::DatashareBusinessError &businessError) 165{ 166 if (!PermissionUtil::CheckPermission(Permission::READ_MESSAGES)) { 167 DATA_STORAGE_LOGE("Permission denied!"); 168 return nullptr; 169 } 170 if (!IsInitOk()) { 171 return nullptr; 172 } 173 Uri tempUri = uri; 174 MessageUriType messageUriType = ParseUriType(tempUri); 175 if (messageUriType == MessageUriType::MAX_GROUP || messageUriType == MessageUriType::UNREAD_TOTAL) { 176 return GetResultSet(messageUriType, uri); 177 } 178 NativeRdb::AbsRdbPredicates *absRdbPredicates = GetPredicates(messageUriType, uri); 179 std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult = nullptr; 180 if (absRdbPredicates != nullptr) { 181 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates); 182 auto resultSet = helper_.Query(rdbPredicates, columns); 183 if (resultSet == nullptr) { 184 DATA_STORAGE_LOGE("SmsMmsAbility::Query NativeRdb::ResultSet is null!"); 185 delete absRdbPredicates; 186 absRdbPredicates = nullptr; 187 return nullptr; 188 } 189 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); 190 sharedPtrResult = std::make_shared<DataShare::DataShareResultSet>(queryResultSet); 191 delete absRdbPredicates; 192 absRdbPredicates = nullptr; 193 } else { 194 DATA_STORAGE_LOGE("SmsMmsAbility::Query NativeRdb::AbsRdbPredicates is null!"); 195 } 196 return sharedPtrResult; 197} 198 199int SmsMmsAbility::Update( 200 const Uri &uri, const DataShare::DataSharePredicates &predicates, 201 const DataShare::DataShareValuesBucket &value) 202{ 203 if (!PermissionUtil::CheckPermission(Permission::READ_MESSAGES)) { 204 DATA_STORAGE_LOGE("Permission denied!"); 205 return DATA_STORAGE_ERR_PERMISSION_ERR; 206 } 207 int result = DATA_STORAGE_ERROR; 208 if (!IsInitOk()) { 209 return result; 210 } 211 std::lock_guard<std::mutex> guard(lock_); 212 Uri tempUri = uri; 213 MessageUriType messageUriType = ParseUriType(tempUri); 214 NativeRdb::AbsRdbPredicates *absRdbPredicates = GetPredicates(messageUriType, uri); 215 if (absRdbPredicates != nullptr) { 216 int changedRows = CHANGED_ROWS; 217 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates); 218 OHOS::NativeRdb::ValuesBucket values = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value); 219 result = helper_.Update(changedRows, values, rdbPredicates); 220 delete absRdbPredicates; 221 absRdbPredicates = nullptr; 222 } else { 223 DATA_STORAGE_LOGE("SmsMmsAbility::Update NativeRdb::AbsRdbPredicates is null!"); 224 } 225 return result; 226} 227 228NativeRdb::AbsRdbPredicates *SmsMmsAbility::GetPredicates(MessageUriType messageUriType, const Uri &uri) 229{ 230 NativeRdb::AbsRdbPredicates *absRdbPredicates = nullptr; 231 switch (messageUriType) { 232 case MessageUriType::SMS_MMS: { 233 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SMS_MMS_INFO); 234 return absRdbPredicates; 235 } 236 case MessageUriType::MMS_PROTOCOL: { 237 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PROTOCOL); 238 return absRdbPredicates; 239 } 240 case MessageUriType::SMS_SUBSECTION: { 241 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SMS_SUBSECTION); 242 return absRdbPredicates; 243 } 244 case MessageUriType::MMS_PART: { 245 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PART); 246 return absRdbPredicates; 247 } 248 case MessageUriType::SESSION: { 249 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SESSION); 250 return absRdbPredicates; 251 } 252 case MessageUriType::MMS_PDU: { 253 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PDU); 254 return absRdbPredicates; 255 } 256 default: 257 DATA_STORAGE_LOGD("GetPredicates##uri = %{private}s", uri.ToString().c_str()); 258 return absRdbPredicates; 259 } 260} 261 262std::shared_ptr<DataShare::DataShareResultSet> SmsMmsAbility::GetResultSet( 263 MessageUriType messageUriType, const Uri &uri) 264{ 265 std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult = nullptr; 266 std::shared_ptr<NativeRdb::ResultSet> resultSet = nullptr; 267 switch (messageUriType) { 268 case MessageUriType::MAX_GROUP: { 269 resultSet = helper_.QueryMaxGroupId(); 270 if (resultSet == nullptr) { 271 DATA_STORAGE_LOGE("ResultSet is null!"); 272 return nullptr; 273 } 274 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); 275 sharedPtrResult = std::make_shared<DataShare::DataShareResultSet>(queryResultSet); 276 break; 277 } 278 case MessageUriType::UNREAD_TOTAL: { 279 resultSet = helper_.StatisticsUnRead(); 280 if (resultSet == nullptr) { 281 DATA_STORAGE_LOGE("ResultSet is null!"); 282 return nullptr; 283 } 284 auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); 285 sharedPtrResult = std::make_shared<DataShare::DataShareResultSet>(queryResultSet); 286 break; 287 } 288 default: 289 DATA_STORAGE_LOGI("uri = %{public}s", uri.ToString().c_str()); 290 break; 291 } 292 return sharedPtrResult; 293} 294 295int SmsMmsAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates) 296{ 297 if (!PermissionUtil::CheckPermission(Permission::READ_MESSAGES)) { 298 DATA_STORAGE_LOGE("Permission denied!"); 299 return DATA_STORAGE_ERR_PERMISSION_ERR; 300 } 301 int result = DATA_STORAGE_ERROR; 302 if (!IsInitOk()) { 303 return result; 304 } 305 std::lock_guard<std::mutex> guard(lock_); 306 Uri tempUri = uri; 307 MessageUriType messageUriType = ParseUriType(tempUri); 308 NativeRdb::AbsRdbPredicates *absRdbPredicates = CreateAbsRdbPredicates(messageUriType, result, tempUri); 309 if (absRdbPredicates != nullptr) { 310 NativeRdb::RdbPredicates rdbPredicates = ConvertPredicates(absRdbPredicates->GetTableName(), predicates); 311 int deletedRows = CHANGED_ROWS; 312 result = helper_.Delete(deletedRows, rdbPredicates); 313 delete absRdbPredicates; 314 absRdbPredicates = nullptr; 315 } else if (result == DATA_STORAGE_ERROR) { 316 DATA_STORAGE_LOGE("SmsMmsAbility::Delete NativeRdb::AbsRdbPredicates is null!"); 317 } 318 return result; 319} 320 321NativeRdb::AbsRdbPredicates *SmsMmsAbility::CreateAbsRdbPredicates(MessageUriType messageUriType, int &result, Uri uri) 322{ 323 NativeRdb::AbsRdbPredicates *absRdbPredicates = nullptr; 324 switch (messageUriType) { 325 case MessageUriType::SMS_MMS: { 326 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SMS_MMS_INFO); 327 return absRdbPredicates; 328 } 329 case MessageUriType::THIRTY: { 330 result = helper_.DeleteDataByThirty(); 331 if (result != NativeRdb::E_OK) { 332 DATA_STORAGE_LOGE("SmsMmsAbility::Delete DeleteDataByThirty fail!"); 333 result = static_cast<int>(LoadProFileErrorType::DELETE_THIRTY_DATA_FAIL); 334 } 335 return absRdbPredicates; 336 } 337 case MessageUriType::MMS_PROTOCOL: { 338 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PROTOCOL); 339 return absRdbPredicates; 340 } 341 case MessageUriType::SMS_SUBSECTION: { 342 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SMS_SUBSECTION); 343 return absRdbPredicates; 344 } 345 case MessageUriType::MMS_PART: { 346 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PART); 347 return absRdbPredicates; 348 } 349 case MessageUriType::SESSION: { 350 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_SESSION); 351 return absRdbPredicates; 352 } 353 case MessageUriType::MMS_PDU: { 354 absRdbPredicates = new NativeRdb::AbsRdbPredicates(TABLE_MMS_PDU); 355 return absRdbPredicates; 356 } 357 default: 358 DATA_STORAGE_LOGI("SmsMmsAbility::Delete##uri = %{public}s", uri.ToString().c_str()); 359 return absRdbPredicates; 360 } 361} 362 363bool SmsMmsAbility::IsInitOk() 364{ 365 if (!initDatabaseDir) { 366 DATA_STORAGE_LOGE("SmsMmsAbility::IsInitOk initDatabaseDir failed!"); 367 } else if (!initRdbStore) { 368 DATA_STORAGE_LOGE("SmsMmsAbility::IsInitOk initRdbStore failed!"); 369 } 370 return initDatabaseDir && initRdbStore; 371} 372 373std::string SmsMmsAbility::GetType(const Uri &uri) 374{ 375 DATA_STORAGE_LOGI("SmsMmsAbility::GetType##uri = %{public}s", uri.ToString().c_str()); 376 std::string retval(uri.ToString()); 377 return retval; 378} 379 380int SmsMmsAbility::OpenFile(const Uri &uri, const std::string &mode) 381{ 382 DATA_STORAGE_LOGI("SmsMmsAbility::OpenFile##uri = %{public}s", uri.ToString().c_str()); 383 Uri tempUri = uri; 384 MessageUriType messageUriType = ParseUriType(tempUri); 385 return static_cast<int>(messageUriType); 386} 387 388int SmsMmsAbility::BatchInsert(const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values) 389{ 390 if (!PermissionUtil::CheckPermission(Permission::READ_MESSAGES)) { 391 DATA_STORAGE_LOGE("Permission denied!"); 392 return DATA_STORAGE_ERR_PERMISSION_ERR; 393 } 394 int result = DATA_STORAGE_ERROR; 395 if (!IsInitOk()) { 396 return result; 397 } 398 std::lock_guard<std::mutex> guard(lock_); 399 Uri tempUri = uri; 400 MessageUriType messageUriType = ParseUriType(tempUri); 401 int64_t id = DATA_STORAGE_ERROR; 402 if (messageUriType == MessageUriType::SMS_MMS) { 403 result = helper_.BatchInsertSmsMmsInfo(id, values); 404 } else { 405 DATA_STORAGE_LOGI("SmsMmsAbility::BatchInsert##uri = %{public}s", uri.ToString().c_str()); 406 } 407 return result; 408} 409 410MessageUriType SmsMmsAbility::ParseUriType(Uri &uri) 411{ 412 DATA_STORAGE_LOGD("SmsMmsAbility::ParseUriType start"); 413 MessageUriType messageUriType = MessageUriType::UNKNOW; 414 std::string uriPath = uri.ToString(); 415 if (!uriPath.empty()) { 416 helper_.ReplaceAllStr(uriPath, ":///", "://"); 417 Uri tempUri(uriPath); 418 std::string path = tempUri.GetPath(); 419 if (!path.empty() && !smsMmsUriMap_.empty()) { 420 DATA_STORAGE_LOGD("SmsMmsAbility::ParseUriType##path = %{private}s", path.c_str()); 421 auto it = smsMmsUriMap_.find(path); 422 if (it != smsMmsUriMap_.end()) { 423 messageUriType = it->second; 424 DATA_STORAGE_LOGD("SmsMmsAbility::ParseUriType##messageUriType = %{private}d", messageUriType); 425 } 426 } 427 } 428 return messageUriType; 429} 430 431OHOS::NativeRdb::RdbPredicates SmsMmsAbility::ConvertPredicates( 432 const std::string &tableName, const DataShare::DataSharePredicates &predicates) 433{ 434 OHOS::NativeRdb::RdbPredicates res = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); 435 return res; 436} 437} // namespace Telephony 438} // namespace OHOS 439