• 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 "ability_loader.h"
21 #include "common.h"
22 #include "contacts_columns.h"
23 #include "contacts_common_event.h"
24 #include "contacts_datashare_stub_impl.h"
25 #include "datashare_ext_ability_context.h"
26 #include "datashare_predicates.h"
27 #include "file_utils.h"
28 #include "predicates_convert.h"
29 #include "rdb_predicates.h"
30 #include "rdb_utils.h"
31 #include "sql_analyzer.h"
32 #include "uri_utils.h"
33 
34 namespace OHOS {
35 namespace AbilityRuntime {
36 namespace {
37 std::mutex g_mutex;
38 }
39 std::shared_ptr<Contacts::VoiceMailDataBase> VoiceMailAbility::voiceMailDataBase_ = nullptr;
40 std::map<std::string, int> VoiceMailAbility::uriValueMap_ = {
41     {"/com.ohos.voicemailability/calls/voicemail", Contacts::VOICEMAIL},
42     {"/com.ohos.voicemailability/calls/replaying", Contacts::REPLAYING}
43 };
44 
Create()45 VoiceMailAbility* VoiceMailAbility::Create()
46 {
47     return new VoiceMailAbility();
48 }
49 
VoiceMailAbility()50 VoiceMailAbility::VoiceMailAbility() : DataShareExtAbility()
51 {
52 }
53 
~VoiceMailAbility()54 VoiceMailAbility::~VoiceMailAbility()
55 {
56 }
57 
OnConnect(const AAFwk::Want & want)58 sptr<IRemoteObject> VoiceMailAbility::OnConnect(const AAFwk::Want &want)
59 {
60     HILOG_INFO("VoiceMailAbility %{public}s begin.", __func__);
61     Extension::OnConnect(want);
62     sptr<DataShare::ContactsDataShareStubImpl> remoteObject = new (std::nothrow) DataShare::ContactsDataShareStubImpl(
63         std::static_pointer_cast<VoiceMailAbility>(shared_from_this()));
64     if (remoteObject == nullptr) {
65         HILOG_ERROR("%{public}s No memory allocated for DataShareStubImpl", __func__);
66         return nullptr;
67     }
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     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
133     Contacts::SqlAnalyzer sqlAnalyzer;
134     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
135     if (!isOk) {
136         HILOG_ERROR("VoiceMailAbility CheckValuesBucket is error");
137         return Contacts::RDB_EXECUTE_FAIL;
138     }
139     g_mutex.lock();
140     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
141     int rowRet = Contacts::RDB_EXECUTE_FAIL;
142     int ret = voiceMailDataBase_->BeginTransaction();
143     if (!IsBeginTransactionOK(ret, g_mutex)) {
144         g_mutex.unlock();
145         return Contacts::RDB_EXECUTE_FAIL;
146     }
147     rowRet = InsertExecute(uri, valuesBucket);
148     if (rowRet == Contacts::OPERATION_ERROR) {
149         voiceMailDataBase_->RollBack();
150         g_mutex.unlock();
151         return Contacts::OPERATION_ERROR;
152     }
153     ret = voiceMailDataBase_->Commit();
154     if (!IsCommitOK(ret, g_mutex)) {
155         voiceMailDataBase_->RollBack();
156         g_mutex.unlock();
157         return Contacts::RDB_EXECUTE_FAIL;
158     }
159     g_mutex.unlock();
160     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
161     return rowRet;
162 }
163 
UriParse(Uri & uri)164 int VoiceMailAbility::UriParse(Uri &uri)
165 {
166     Contacts::UriUtils uriUtils;
167     int parseCode = uriUtils.UriParse(uri, uriValueMap_);
168     return parseCode;
169 }
170 
InsertExecute(const OHOS::Uri & uri,const OHOS::NativeRdb::ValuesBucket & initialValues)171 int VoiceMailAbility::InsertExecute(const OHOS::Uri &uri, const OHOS::NativeRdb::ValuesBucket &initialValues)
172 {
173     int rowId = Contacts::RDB_EXECUTE_FAIL;
174     OHOS::Uri uriTemp = uri;
175     int code = UriParse(uriTemp);
176     switch (code) {
177         case Contacts::VOICEMAIL:
178             rowId = voiceMailDataBase_->InsertVoiceMail(Contacts::CallsTableName::VOICEMAIL, initialValues);
179             break;
180         case Contacts::REPLAYING:
181             rowId = voiceMailDataBase_->InsertVoiceMail(Contacts::CallsTableName::REPLYING, initialValues);
182             break;
183         default:
184             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
185             break;
186     }
187     return rowId;
188 }
189 
190 /**
191  * @brief VoiceMailAbility BatchInsert database
192  *
193  * @param uri Determine the data table name based on the URI
194  * @param value Insert the data values of the database
195  *
196  * @return BatchInsert database results code
197  */
BatchInsert(const Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)198 int VoiceMailAbility::BatchInsert(const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
199 {
200     unsigned int size = values.size();
201     if (size <= 0) {
202         return Contacts::RDB_EXECUTE_FAIL;
203     }
204     g_mutex.lock();
205     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
206     int ret = voiceMailDataBase_->BeginTransaction();
207     if (!IsBeginTransactionOK(ret, g_mutex)) {
208         g_mutex.unlock();
209         return Contacts::RDB_EXECUTE_FAIL;
210     }
211     int count = 0;
212     for (unsigned int i = 0; i < size; i++) {
213         ++count;
214         DataShare::DataShareValuesBucket rawContactValues = values[i];
215         OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(rawContactValues);
216         int code = InsertExecute(uri, value);
217         if (code == Contacts::OPERATION_ERROR) {
218             voiceMailDataBase_->RollBack();
219             g_mutex.unlock();
220             return code;
221         }
222         if (count % Contacts::BATCH_INSERT_COUNT == 0) {
223             int markRet = voiceMailDataBase_->Commit();
224             int beginRet = voiceMailDataBase_->BeginTransaction();
225             if (!IsCommitOK(markRet, g_mutex) || !IsBeginTransactionOK(beginRet, g_mutex)) {
226                 voiceMailDataBase_->RollBack();
227                 g_mutex.unlock();
228                 return Contacts::RDB_EXECUTE_FAIL;
229             }
230         }
231     }
232     int markRet = voiceMailDataBase_->Commit();
233     if (!IsCommitOK(markRet, g_mutex)) {
234         voiceMailDataBase_->RollBack();
235         g_mutex.unlock();
236         return Contacts::RDB_EXECUTE_FAIL;
237     }
238     g_mutex.unlock();
239     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
240     return Contacts::RDB_EXECUTE_OK;
241 }
242 
243 /**
244  * @brief VoiceMailAbility Update database
245  *
246  * @param uri Determine the data table name based on the URI
247  * @param predicates Update the data value of the condition
248  *
249  * @return Update database results code
250  */
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)251 int VoiceMailAbility::Update(
252     const Uri &uri, const DataShare::DataSharePredicates &predicates, const DataShare::DataShareValuesBucket &value)
253 {
254     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
255     Contacts::SqlAnalyzer sqlAnalyzer;
256     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
257     if (!isOk) {
258         HILOG_ERROR("VoiceMailAbility CheckValuesBucket is error");
259         return Contacts::RDB_EXECUTE_FAIL;
260     }
261     g_mutex.lock();
262     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
263     Contacts::PredicatesConvert predicatesConvert;
264     int ret = Contacts::RDB_EXECUTE_FAIL;
265     OHOS::Uri uriTemp = uri;
266     int code = UriParse(uriTemp);
267     DataShare::DataSharePredicates dataSharePredicates = predicates;
268     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
269     switch (code) {
270         case Contacts::VOICEMAIL:
271             rdbPredicates =
272                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
273             ret = voiceMailDataBase_->UpdateVoiceMail(valuesBucket, rdbPredicates);
274             break;
275         case Contacts::REPLAYING:
276             rdbPredicates =
277                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
278             ret = voiceMailDataBase_->UpdateVoiceMail(valuesBucket, rdbPredicates);
279             break;
280         default:
281             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
282             break;
283     }
284     g_mutex.unlock();
285     DataBaseNotifyChange(Contacts::CONTACT_UPDATE, uri);
286     return ret;
287 }
288 
289 /**
290  * @brief VoiceMailAbility Delete database
291  *
292  * @param uri Determine the data table name based on the URI
293  * @param predicates Delete the data values of the condition
294  *
295  * @return Delete database results code
296  */
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)297 int VoiceMailAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
298 {
299     g_mutex.lock();
300     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
301     Contacts::PredicatesConvert predicatesConvert;
302     int ret = Contacts::RDB_EXECUTE_FAIL;
303     OHOS::Uri uriTemp = uri;
304     int parseCode = UriParse(uriTemp);
305     DataShare::DataSharePredicates dataSharePredicates = predicates;
306     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
307     switch (parseCode) {
308         case Contacts::VOICEMAIL:
309             rdbPredicates =
310                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
311             ret = voiceMailDataBase_->DeleteVoiceMail(rdbPredicates);
312             break;
313         case Contacts::REPLAYING:
314             rdbPredicates =
315                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
316             ret = voiceMailDataBase_->DeleteVoiceMail(rdbPredicates);
317             break;
318         default:
319             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
320             break;
321     }
322     g_mutex.unlock();
323     DataBaseNotifyChange(Contacts::CONTACT_DELETE, uri);
324     return ret;
325 }
326 
327 /**
328  * @brief VoiceMailAbility Query database
329  *
330  * @param uri Determine the data table name based on the URI
331  * @param columns Columns returned by query
332  * @param predicates Query the data values of the condition
333  *
334  * @return Query database results
335  */
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns)336 std::shared_ptr<DataShare::DataShareResultSet> VoiceMailAbility::Query(
337     const Uri &uri, const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns)
338 {
339     HILOG_ERROR("VoiceMailAbility ====>Query start");
340     voiceMailDataBase_ = Contacts::VoiceMailDataBase::GetInstance();
341     Contacts::PredicatesConvert predicatesConvert;
342     OHOS::Uri uriTemp = uri;
343     int parseCode = UriParse(uriTemp);
344     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> result;
345     DataShare::DataSharePredicates dataSharePredicates = predicates;
346     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
347     std::vector<std::string> columnsTemp = columns;
348     bool isUriMatch = true;
349     switch (parseCode) {
350         case Contacts::VOICEMAIL:
351             rdbPredicates =
352                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::VOICEMAIL, dataSharePredicates);
353             result = voiceMailDataBase_->Query(rdbPredicates, columnsTemp);
354             break;
355         case Contacts::REPLAYING:
356             rdbPredicates =
357                 predicatesConvert.ConvertPredicates(Contacts::CallsTableName::REPLYING, dataSharePredicates);
358             result = voiceMailDataBase_->Query(rdbPredicates, columnsTemp);
359             break;
360         default:
361             isUriMatch = false;
362             HILOG_ERROR("VoiceMailAbility ====>no match uri action");
363             break;
364     }
365     if (!isUriMatch) {
366         return nullptr;
367     }
368     auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
369     std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult =
370         std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
371     HILOG_ERROR("VoiceMailAbility ====>Query end");
372     return sharedPtrResult;
373 }
374 
DataBaseNotifyChange(int code,Uri uri)375 void VoiceMailAbility::DataBaseNotifyChange(int code, Uri uri)
376 {
377     Contacts::ContactsCommonEvent::SendCallLogChange(code);
378 }
379 } // namespace AbilityRuntime
380 } // namespace OHOS
381