• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "voicemail_ability.h"
17 
18 #include <mutex>
19 
20 #include "common.h"
21 #include "contacts_columns.h"
22 #include "contacts_common_event.h"
23 #include "contacts_datashare_stub_impl.h"
24 #include "datashare_ext_ability_context.h"
25 #include "datashare_predicates.h"
26 #include "file_utils.h"
27 #include "predicates_convert.h"
28 #include "rdb_predicates.h"
29 #include "rdb_utils.h"
30 #include "sql_analyzer.h"
31 #include "uri_utils.h"
32 
33 namespace OHOS {
34 namespace AbilityRuntime {
35 namespace {
36 std::mutex g_mutex;
37 }
38 std::shared_ptr<Contacts::VoiceMailDataBase> VoiceMailAbility::voiceMailDataBase_ = nullptr;
39 std::map<std::string, int> VoiceMailAbility::uriValueMap_ = {
40     {"/com.ohos.voicemailability/calls/voicemail", Contacts::VOICEMAIL},
41     {"/com.ohos.voicemailability/calls/replaying", Contacts::REPLAYING}
42 };
43 
Create()44 VoiceMailAbility* VoiceMailAbility::Create()
45 {
46     return new VoiceMailAbility();
47 }
48 
VoiceMailAbility()49 VoiceMailAbility::VoiceMailAbility() : DataShareExtAbility()
50 {
51 }
52 
~VoiceMailAbility()53 VoiceMailAbility::~VoiceMailAbility()
54 {
55 }
56 
OnConnect(const AAFwk::Want & want)57 sptr<IRemoteObject> VoiceMailAbility::OnConnect(const AAFwk::Want &want)
58 {
59     HILOG_INFO("VoiceMailAbility %{public}s begin.", __func__);
60     Extension::OnConnect(want);
61     sptr<DataShare::ContactsDataShareStubImpl> remoteObject =
62         new (std::nothrow) DataShare::ContactsDataShareStubImpl();
63     if (remoteObject == nullptr) {
64         HILOG_ERROR("%{public}s No memory allocated for DataShareStubImpl", __func__);
65         return nullptr;
66     }
67     remoteObject->SetVoiceMailAbility(std::static_pointer_cast<VoiceMailAbility>(shared_from_this()));
68     HILOG_INFO("VoiceMailAbility %{public}s end.", __func__);
69     return remoteObject->AsObject();
70 }
71 
OnStart(const Want & want)72 void VoiceMailAbility::OnStart(const Want &want)
73 {
74     HILOG_INFO("VoiceMailAbility %{public}s begin.", __func__);
75     Extension::OnStart(want);
76     auto context = AbilityRuntime::Context::GetApplicationContext();
77     if (context != nullptr) {
78         std::string basePath = context->GetDatabaseDir();
79         Contacts::ContactsPath::RDB_PATH = basePath + "/";
80         Contacts::ContactsPath::RDB_BACKUP_PATH = basePath + "/backup/";
81     }
82 }
83 
84 /**
85  * @brief VoiceMailAbility BeginTransaction emptiness problems
86  *
87  * @param code the return number of BeginTransaction
88  * @param mutex transmission parameter : lock
89  *
90  * @return BeginTransaction emptiness true or false
91  */
IsBeginTransactionOK(int code,std::mutex & mutex)92 bool VoiceMailAbility::IsBeginTransactionOK(int code, std::mutex &mutex)
93 {
94     mutex.try_lock();
95     if (code != 0) {
96         HILOG_ERROR("IsBeginTransactionOK fail");
97         mutex.unlock();
98         return false;
99     }
100     return true;
101 }
102 
103 /**
104  * @brief VoiceMailAbility Commit emptiness problems
105  *
106  * @param code the return number of Commit
107  * @param mutex transmission parameter : lock
108  *
109  * @return Commit emptiness true or false
110  */
IsCommitOK(int code,std::mutex & mutex)111 bool VoiceMailAbility::IsCommitOK(int code, std::mutex &mutex)
112 {
113     mutex.try_lock();
114     if (code != 0) {
115         HILOG_ERROR("IsCommitOK fail");
116         mutex.unlock();
117         return false;
118     }
119     return true;
120 }
121 
122 /**
123  * @brief VoiceMailAbility Insert database
124  *
125  * @param uri Determine the data table name based on the URI
126  * @param value Insert the data value of the database
127  *
128  * @return Insert database results code
129  */
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)130 int VoiceMailAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
131 {
132     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::OHOS_PERMISSION_MANAGE_VOICEMAIL)) {
133         HILOG_ERROR("Permission denied!");
134         return Contacts::RDB_PERMISSION_ERROR;
135     }
136     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
137     Contacts::SqlAnalyzer sqlAnalyzer;
138     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
139     if (!isOk) {
140         HILOG_ERROR("VoiceMailAbility CheckValuesBucket is error");
141         return Contacts::RDB_EXECUTE_FAIL;
142     }
143     g_mutex.lock();
144     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
145     int ret = voiceMailDataBase_->BeginTransaction();
146     if (!IsBeginTransactionOK(ret, g_mutex)) {
147         g_mutex.unlock();
148         return Contacts::RDB_EXECUTE_FAIL;
149     }
150     int rowRet = InsertExecute(uri, valuesBucket);
151     if (rowRet == Contacts::OPERATION_ERROR) {
152         voiceMailDataBase_->RollBack();
153         g_mutex.unlock();
154         return Contacts::OPERATION_ERROR;
155     }
156     ret = voiceMailDataBase_->Commit();
157     if (!IsCommitOK(ret, g_mutex)) {
158         voiceMailDataBase_->RollBack();
159         g_mutex.unlock();
160         return Contacts::RDB_EXECUTE_FAIL;
161     }
162     g_mutex.unlock();
163     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
164     return rowRet;
165 }
166 
UriParse(Uri & uri)167 int VoiceMailAbility::UriParse(Uri &uri)
168 {
169     Contacts::UriUtils uriUtils;
170     int parseCode = uriUtils.UriParse(uri, uriValueMap_);
171     return parseCode;
172 }
173 
InsertExecute(const OHOS::Uri & uri,const OHOS::NativeRdb::ValuesBucket & initialValues)174 int VoiceMailAbility::InsertExecute(const OHOS::Uri &uri, const OHOS::NativeRdb::ValuesBucket &initialValues)
175 {
176     int rowId = Contacts::RDB_EXECUTE_FAIL;
177     OHOS::Uri uriTemp = uri;
178     int code = UriParse(uriTemp);
179     switch (code) {
180         case Contacts::VOICEMAIL:
181             rowId = voiceMailDataBase_->InsertVoiceMail(Contacts::CallsTableName::VOICEMAIL, initialValues);
182             break;
183         case Contacts::REPLAYING:
184             rowId = voiceMailDataBase_->InsertVoiceMail(Contacts::CallsTableName::REPLYING, initialValues);
185             break;
186         default:
187             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
188             break;
189     }
190     return rowId;
191 }
192 
193 /**
194  * @brief VoiceMailAbility BatchInsert database
195  *
196  * @param uri Determine the data table name based on the URI
197  * @param value Insert the data values of the database
198  *
199  * @return BatchInsert database results code
200  */
BatchInsert(const Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)201 int VoiceMailAbility::BatchInsert(const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
202 {
203     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::OHOS_PERMISSION_MANAGE_VOICEMAIL)) {
204         HILOG_ERROR("Permission denied!");
205         return Contacts::RDB_PERMISSION_ERROR;
206     }
207     unsigned int size = values.size();
208     if (size < 1) {
209         return Contacts::RDB_EXECUTE_FAIL;
210     }
211     g_mutex.lock();
212     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
213     int ret = voiceMailDataBase_->BeginTransaction();
214     if (!IsBeginTransactionOK(ret, g_mutex)) {
215         g_mutex.unlock();
216         return Contacts::RDB_EXECUTE_FAIL;
217     }
218     int count = 0;
219     for (unsigned int i = 0; i < size; i++) {
220         ++count;
221         DataShare::DataShareValuesBucket rawContactValues = values[i];
222         OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(rawContactValues);
223         int code = InsertExecute(uri, value);
224         if (code == Contacts::OPERATION_ERROR) {
225             voiceMailDataBase_->RollBack();
226             g_mutex.unlock();
227             return code;
228         }
229         if (count % Contacts::BATCH_INSERT_COUNT == 0) {
230             int markRet = voiceMailDataBase_->Commit();
231             int beginRet = voiceMailDataBase_->BeginTransaction();
232             if (!IsCommitOK(markRet, g_mutex) || !IsBeginTransactionOK(beginRet, g_mutex)) {
233                 voiceMailDataBase_->RollBack();
234                 g_mutex.unlock();
235                 return Contacts::RDB_EXECUTE_FAIL;
236             }
237         }
238     }
239     int markRet = voiceMailDataBase_->Commit();
240     if (!IsCommitOK(markRet, g_mutex)) {
241         voiceMailDataBase_->RollBack();
242         g_mutex.unlock();
243         return Contacts::RDB_EXECUTE_FAIL;
244     }
245     g_mutex.unlock();
246     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
247     return Contacts::RDB_EXECUTE_OK;
248 }
249 
250 /**
251  * @brief VoiceMailAbility Update database
252  *
253  * @param uri Determine the data table name based on the URI
254  * @param predicates Update the data value of the condition
255  *
256  * @return Update database results code
257  */
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)258 int VoiceMailAbility::Update(
259     const Uri &uri, const DataShare::DataSharePredicates &predicates, const DataShare::DataShareValuesBucket &value)
260 {
261     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::OHOS_PERMISSION_MANAGE_VOICEMAIL)) {
262         HILOG_ERROR("Permission denied!");
263         return Contacts::RDB_PERMISSION_ERROR;
264     }
265     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
266     Contacts::SqlAnalyzer sqlAnalyzer;
267     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
268     if (!isOk) {
269         HILOG_ERROR("VoiceMailAbility CheckValuesBucket is error");
270         return Contacts::RDB_EXECUTE_FAIL;
271     }
272     g_mutex.lock();
273     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
274     Contacts::PredicatesConvert predicatesConvert;
275     int ret = Contacts::RDB_EXECUTE_FAIL;
276     OHOS::Uri uriTemp = uri;
277     int code = UriParse(uriTemp);
278     DataShare::DataSharePredicates dataSharePredicates = predicates;
279     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
280     switch (code) {
281         case Contacts::VOICEMAIL:
282             rdbPredicates =
283                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
284             ret = voiceMailDataBase_->UpdateVoiceMail(valuesBucket, rdbPredicates);
285             break;
286         case Contacts::REPLAYING:
287             rdbPredicates =
288                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
289             ret = voiceMailDataBase_->UpdateVoiceMail(valuesBucket, rdbPredicates);
290             break;
291         default:
292             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
293             break;
294     }
295     g_mutex.unlock();
296     DataBaseNotifyChange(Contacts::CONTACT_UPDATE, uri);
297     return ret;
298 }
299 
300 /**
301  * @brief VoiceMailAbility Delete database
302  *
303  * @param uri Determine the data table name based on the URI
304  * @param predicates Delete the data values of the condition
305  *
306  * @return Delete database results code
307  */
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)308 int VoiceMailAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
309 {
310     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::OHOS_PERMISSION_MANAGE_VOICEMAIL)) {
311         HILOG_ERROR("Permission denied!");
312         return Contacts::RDB_PERMISSION_ERROR;
313     }
314     g_mutex.lock();
315     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
316     Contacts::PredicatesConvert predicatesConvert;
317     int ret = Contacts::RDB_EXECUTE_FAIL;
318     OHOS::Uri uriTemp = uri;
319     int parseCode = UriParse(uriTemp);
320     DataShare::DataSharePredicates dataSharePredicates = predicates;
321     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
322     switch (parseCode) {
323         case Contacts::VOICEMAIL:
324             rdbPredicates =
325                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
326             ret = voiceMailDataBase_->DeleteVoiceMail(rdbPredicates);
327             break;
328         case Contacts::REPLAYING:
329             rdbPredicates =
330                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
331             ret = voiceMailDataBase_->DeleteVoiceMail(rdbPredicates);
332             break;
333         default:
334             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
335             break;
336     }
337     g_mutex.unlock();
338     DataBaseNotifyChange(Contacts::CONTACT_DELETE, uri);
339     return ret;
340 }
341 
342 /**
343  * @brief VoiceMailAbility Query database
344  *
345  * @param uri Determine the data table name based on the URI
346  * @param columns Columns returned by query
347  * @param predicates Query the data values of the condition
348  *
349  * @return Query database results
350  */
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns,DataShare::DatashareBusinessError & businessError)351 std::shared_ptr<DataShare::DataShareResultSet> VoiceMailAbility::Query(const Uri &uri,
352     const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns,
353     DataShare::DatashareBusinessError &businessError)
354 {
355     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::OHOS_PERMISSION_MANAGE_VOICEMAIL)) {
356         HILOG_ERROR("Permission denied!");
357         return nullptr;
358     }
359     HILOG_ERROR("VoiceMailAbility ====>Query start");
360     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
361     Contacts::PredicatesConvert predicatesConvert;
362     OHOS::Uri uriTemp = uri;
363     int parseCode = UriParse(uriTemp);
364     std::shared_ptr<OHOS::NativeRdb::ResultSet> result;
365     DataShare::DataSharePredicates dataSharePredicates = predicates;
366     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
367     std::vector<std::string> columnsTemp = columns;
368     bool isUriMatch = true;
369     switch (parseCode) {
370         case Contacts::VOICEMAIL:
371             rdbPredicates =
372                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
373             result = voiceMailDataBase_->Query(rdbPredicates, columnsTemp);
374             break;
375         case Contacts::REPLAYING:
376             rdbPredicates =
377                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
378             result = voiceMailDataBase_->Query(rdbPredicates, columnsTemp);
379             break;
380         default:
381             isUriMatch = false;
382             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
383             break;
384     }
385     if (!isUriMatch) {
386         return nullptr;
387     }
388     if (result == nullptr) {
389         HILOG_ERROR("AbsSharedResultSet is nullptr");
390         return nullptr;
391     }
392     auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
393     std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult =
394         std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
395     HILOG_ERROR("VoiceMailAbility ====>Query end");
396     return sharedPtrResult;
397 }
398 
DataBaseNotifyChange(int code,Uri uri)399 void VoiceMailAbility::DataBaseNotifyChange(int code, Uri uri)
400 {
401     Contacts::ContactsCommonEvent::SendCallLogChange(code);
402 }
403 } // namespace AbilityRuntime
404 } // namespace OHOS
405