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