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
35 namespace OHOS {
36 using AppExecFwk::Ability;
37 using AppExecFwk::AbilityLoader;
38 namespace Telephony {
39 const int32_t CHANGED_ROWS = 0;
40 static 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
SmsMmsAbility()52 SmsMmsAbility::SmsMmsAbility() : DataShareExtAbility() {}
53
~SmsMmsAbility()54 SmsMmsAbility::~SmsMmsAbility() {}
55
Create()56 SmsMmsAbility* SmsMmsAbility::Create()
57 {
58 DATA_STORAGE_LOGD("SmsMmsAbility::Create begin.");
59 auto self = new SmsMmsAbility();
60 self->DoInit();
61 return self;
62 }
63
DoInit()64 void 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
OnConnect(const AAFwk::Want & want)94 sptr<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
OnStart(const AppExecFwk::Want & want)109 void SmsMmsAbility::OnStart(const AppExecFwk::Want &want)
110 {
111 DATA_STORAGE_LOGI("SmsMmsAbility::OnStart");
112 Extension::OnStart(want);
113 DoInit();
114 }
115
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)116 int 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
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns,DataShare::DatashareBusinessError & businessError)162 std::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
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)199 int 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
GetPredicates(MessageUriType messageUriType,const Uri & uri)228 NativeRdb::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
GetResultSet(MessageUriType messageUriType,const Uri & uri)262 std::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
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)295 int 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
CreateAbsRdbPredicates(MessageUriType messageUriType,int & result,Uri uri)321 NativeRdb::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
IsInitOk()363 bool 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
GetType(const Uri & uri)373 std::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
OpenFile(const Uri & uri,const std::string & mode)380 int 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
BatchInsert(const Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)388 int 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
ParseUriType(Uri & uri)410 MessageUriType 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
ConvertPredicates(const std::string & tableName,const DataShare::DataSharePredicates & predicates)431 OHOS::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