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