• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "contacts_data_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 "database_disaster_recovery.h"
27 #include "file_utils.h"
28 #include "hilog_wrapper.h"
29 #include "profile_database.h"
30 #include "rdb_predicates.h"
31 #include "rdb_utils.h"
32 #include "sql_analyzer.h"
33 #include "uri_utils.h"
34 
35 namespace OHOS {
36 namespace AbilityRuntime {
37 namespace {
38 std::mutex g_mutex;
39 }
40 std::shared_ptr<Contacts::ContactsDataBase> ContactsDataAbility::contactDataBase_ = nullptr;
41 std::shared_ptr<Contacts::ProfileDatabase> ContactsDataAbility::profileDataBase_ = nullptr;
42 std::map<std::string, int> ContactsDataAbility::uriValueMap_ = {
43     {"/com.ohos.contactsdataability/contacts/contact", Contacts::CONTACTS_CONTACT},
44     {"/com.ohos.contactsdataability/contacts/deleted_raw_contact", Contacts::CONTACTS_DELETE},
45     {"/com.ohos.contactsdataability/contacts/deleted_raw_contact_record", Contacts::CONTACTS_DELETE_RECORD},
46     {"/com.ohos.contactsdataability/contacts/raw_contact", Contacts::CONTACTS_RAW_CONTACT},
47     {"/com.ohos.contactsdataability/contacts/account", Contacts::ACCOUNT},
48     {"/com.ohos.contactsdataability/contacts/raw_contact/query_merge_list", Contacts::QUERY_MERGE_LIST},
49     {"/com.ohos.contactsdataability/contacts/raw_contact/split_contact", Contacts::SPLIT_CONTACT},
50     {"/com.ohos.contactsdataability/contacts/raw_contact/manual_merge", Contacts::MANUAL_MERGE},
51     {"/com.ohos.contactsdataability/contacts/raw_contact/auto_merge", Contacts::AUTO_MERGE},
52     {"/com.ohos.contactsdataability/contacts/contact_data", Contacts::CONTACTS_CONTACT_DATA},
53     {"/com.ohos.contactsdataability/contacts/contact_type", Contacts::CONTACT_TYPE},
54     {"/com.ohos.contactsdataability/contacts/groups", Contacts::CONTACTS_GROUPS},
55     {"/com.ohos.contactsdataability/contacts/contact_blocklist", Contacts::CONTACTS_BLOCKLIST},
56     {"/com.ohos.contactsdataability/contacts/photo_files", Contacts::CONTACTS_PHOTO_FILES},
57     {"/com.ohos.contactsdataability/contacts/search_contact", Contacts::CONTACTS_SEARCH_CONTACT},
58     {"/com.ohos.contactsdataability/contacts/backup", Contacts::CONTACT_BACKUP},
59     {"/com.ohos.contactsdataability/profile/backup", Contacts::PROFILE_BACKUP},
60     {"/com.ohos.contactsdataability/contacts/recover", Contacts::CONTACT_RECOVER},
61     {"/com.ohos.contactsdataability/profile/recover", Contacts::PROFILE_RECOVER},
62     {"/com.ohos.contactsdataability/profile/contact", Contacts::PROFILE_CONTACT},
63     {"/com.ohos.contactsdataability/profile/raw_contact", Contacts::PROFILE_RAW_CONTACT},
64     {"/com.ohos.contactsdataability/profile/contact_data", Contacts::PROFILE_CONTACT_DATA},
65     {"/com.ohos.contactsdataability/profile/groups", Contacts::PROFILE_GROUPS},
66     {"/com.ohos.contactsdataability/profile/contact_blocklist", Contacts::PROFILE_BLOCKLIST},
67     {"/com.ohos.contactsdataability/profile/photo_files", Contacts::PROFILE_PHOTO_FILES},
68     {"/com.ohos.contactsdataability/profile/search_contact", Contacts::PROFILE_SEARCH_CONTACT},
69     {"/com.ohos.contactsdataability/profile/deleted_raw_contact_record", Contacts::PROFILE_DELETE_RECORD},
70     {"/com.ohos.contactsdataability/profile/deleted_raw_contact", Contacts::PROFILE_DELETE},
71     {"/com.ohos.contactsdataability/profile/contact_type", Contacts::PROFILE_TYPE}
72 };
73 
Create()74 ContactsDataAbility* ContactsDataAbility::Create()
75 {
76     return new ContactsDataAbility();
77 }
78 
ContactsDataAbility()79 ContactsDataAbility::ContactsDataAbility() : DataShareExtAbility()
80 {
81 }
82 
~ContactsDataAbility()83 ContactsDataAbility::~ContactsDataAbility()
84 {
85 }
86 
ContactsDataShareCreator(const std::unique_ptr<Runtime> & runtime)87 static DataShare::DataShareExtAbility *ContactsDataShareCreator(const std::unique_ptr<Runtime> &runtime)
88 {
89     HILOG_INFO("ContactsDataCreator::%{public}s", __func__);
90     return ContactsDataAbility::Create();
91 }
92 
RegisterDataShareCreator()93 __attribute__((constructor)) void RegisterDataShareCreator()
94 {
95     HILOG_INFO("ContactsDataCreator::%{public}s", __func__);
96     DataShare::DataShareExtAbility::SetCreator(ContactsDataShareCreator);
97 }
98 
OnConnect(const AAFwk::Want & want)99 sptr<IRemoteObject> ContactsDataAbility::OnConnect(const AAFwk::Want &want)
100 {
101     HILOG_INFO("ContactsDataAbility %{public}s begin.", __func__);
102     Extension::OnConnect(want);
103     sptr<DataShare::ContactsDataShareStubImpl> remoteObject =
104         new (std::nothrow) DataShare::ContactsDataShareStubImpl();
105     if (remoteObject == nullptr) {
106         HILOG_ERROR("%{public}s No memory allocated for DataShareStubImpl", __func__);
107         return nullptr;
108     }
109     remoteObject->SetContactsDataAbility(std::static_pointer_cast<ContactsDataAbility>(shared_from_this()));
110     HILOG_INFO("ContactsDataAbility %{public}s end.", __func__);
111     return remoteObject->AsObject();
112 }
113 
OnStart(const Want & want)114 void ContactsDataAbility::OnStart(const Want &want)
115 {
116     HILOG_INFO("ContactsDataAbility %{public}s begin.", __func__);
117     Extension::OnStart(want);
118     auto context = AbilityRuntime::Context::GetApplicationContext();
119     if (context != nullptr) {
120         std::string basePath = context->GetDatabaseDir();
121         Contacts::ContactsPath::RDB_PATH = basePath + "/";
122         Contacts::ContactsPath::RDB_BACKUP_PATH = basePath + "/backup/";
123         Contacts::ContactsPath::RDB_EL1_PATH = "/data/storage/el1/database/";
124     }
125 }
126 
127 /**
128  * @brief Check whether BeginTransaction of ContactsDataAbility is empty
129  *
130  * @param code the return number of BeginTransaction
131  * @param mutex transmission parameter : lock
132  *
133  * @return True if BeginTransaction is empty; flase otherwise
134  */
IsBeginTransactionOK(int code,std::mutex & mutex)135 bool ContactsDataAbility::IsBeginTransactionOK(int code, std::mutex &mutex)
136 {
137     mutex.try_lock();
138     if (code != 0) {
139         HILOG_ERROR("IsBeginTransactionOK failed");
140         mutex.unlock();
141         return false;
142     }
143     return true;
144 }
145 
146 /**
147  * @brief Check if ContactsDataAbility Commit is empty
148  *
149  * @param code the return number of Commit
150  * @param mutex transmission parameter : lock
151  *
152  * @return True if ContactsDataAbility Commit is empty; flase otherwise
153  */
IsCommitOK(int code,std::mutex & mutex)154 bool ContactsDataAbility::IsCommitOK(int code, std::mutex &mutex)
155 {
156     mutex.try_lock();
157     if (code != 0) {
158         HILOG_ERROR("IsCommitOK failed");
159         mutex.unlock();
160         return false;
161     }
162     return true;
163 }
164 
165 /**
166  * @brief Insert ContactsDataAbility into the database
167  *
168  * @param uri URI of the data table tobe inserted
169  * @param value Inserted data value of the database
170  *
171  * @return Insert database results code
172  */
Insert(const Uri & uri,const DataShare::DataShareValuesBucket & value)173 int ContactsDataAbility::Insert(const Uri &uri, const DataShare::DataShareValuesBucket &value)
174 {
175     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
176         HILOG_ERROR("Permission denied!");
177         return Contacts::RDB_PERMISSION_ERROR;
178     }
179     HILOG_INFO("ContactsDataAbility Insert start");
180     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
181     Contacts::SqlAnalyzer sqlAnalyzer;
182     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
183     if (!isOk) {
184         HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
185         return Contacts::RDB_EXECUTE_FAIL;
186     }
187     g_mutex.lock();
188     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
189     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
190     OHOS::Uri uriTemp = uri;
191     int code = UriParseAndSwitch(uriTemp);
192     int ret = contactDataBase_->BeginTransaction();
193     if (!IsBeginTransactionOK(ret, g_mutex)) {
194         g_mutex.unlock();
195         return Contacts::RDB_EXECUTE_FAIL;
196     }
197     int resultId = InsertExecute(code, valuesBucket);
198     HILOG_INFO("Insert id = %{public}d", resultId);
199     if (resultId == Contacts::OPERATION_ERROR) {
200         contactDataBase_->RollBack();
201         g_mutex.unlock();
202         return Contacts::OPERATION_ERROR;
203     }
204     ret = contactDataBase_->Commit();
205     if (!IsCommitOK(ret, g_mutex)) {
206         contactDataBase_->RollBack();
207         g_mutex.unlock();
208         return Contacts::RDB_EXECUTE_FAIL;
209     }
210     g_mutex.unlock();
211     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
212     HILOG_INFO("ContactsDataAbility Insert end");
213     return resultId;
214 }
215 
InsertExecute(int & code,const OHOS::NativeRdb::ValuesBucket & value)216 int ContactsDataAbility::InsertExecute(int &code, const OHOS::NativeRdb::ValuesBucket &value)
217 {
218     int rowId = Contacts::RDB_EXECUTE_FAIL;
219     switch (code) {
220         case Contacts::CONTACTS_RAW_CONTACT:
221         case Contacts::PROFILE_RAW_CONTACT:
222             // contact Basic Information
223             rowId = contactDataBase_->InsertRawContact(Contacts::ContactTableName::RAW_CONTACT, value);
224             break;
225         case Contacts::CONTACTS_CONTACT_DATA:
226         case Contacts::PROFILE_CONTACT_DATA:
227             // contact Information add
228             rowId = contactDataBase_->InsertContactData(Contacts::ContactTableName::CONTACT_DATA, value);
229             break;
230         case Contacts::CONTACTS_GROUPS:
231         case Contacts::PROFILE_GROUPS:
232             // insert group
233             rowId = contactDataBase_->InsertGroup(Contacts::ContactTableName::GROUPS, value);
234             break;
235         case Contacts::CONTACTS_BLOCKLIST:
236         case Contacts::PROFILE_BLOCKLIST:
237             // add blocklist
238             rowId = contactDataBase_->InsertBlockList(Contacts::ContactTableName::CONTACT_BLOCKLIST, value);
239             break;
240         default:
241             rowId = Contacts::OPERATION_ERROR;
242             HILOG_INFO("ContactsDataAbility ====>no match uri action");
243             break;
244     }
245     return rowId;
246 }
247 
248 /**
249  * @brief ContactsDataAbility BatchInsert database
250  *
251  * @param uri Determine the data table name based on the URI
252  * @param value Inserted data value of the database
253  *
254  * @return BatchInsert database results code
255  */
BatchInsert(const Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)256 int ContactsDataAbility::BatchInsert(const Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
257 {
258     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
259         HILOG_ERROR("Permission denied!");
260         return Contacts::RDB_PERMISSION_ERROR;
261     }
262     unsigned int size = values.size();
263     if (size < 1) {
264         return Contacts::RDB_EXECUTE_FAIL;
265     }
266     g_mutex.lock();
267     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
268     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
269     OHOS::Uri uriTemp = uri;
270     int code = UriParseAndSwitch(uriTemp);
271     int ret = contactDataBase_->BeginTransaction();
272     if (!IsBeginTransactionOK(ret, g_mutex)) {
273         g_mutex.unlock();
274         return Contacts::RDB_EXECUTE_FAIL;
275     }
276     int count = 0;
277     for (unsigned int i = 0; i < size; i++) {
278         ++count;
279         DataShare::DataShareValuesBucket rawContactValues = values[i];
280         OHOS::NativeRdb::ValuesBucket value = RdbDataShareAdapter::RdbUtils::ToValuesBucket(rawContactValues);
281         int rowRet = InsertExecute(code, value);
282         if (rowRet == Contacts::OPERATION_ERROR) {
283             contactDataBase_->RollBack();
284             g_mutex.unlock();
285             return rowRet;
286         }
287         if (count % Contacts::BATCH_INSERT_COUNT == 0) {
288             int markRet = contactDataBase_->Commit();
289             int beginRet = contactDataBase_->BeginTransaction();
290             if (!IsCommitOK(markRet, g_mutex) || !IsBeginTransactionOK(beginRet, g_mutex)) {
291                 contactDataBase_->RollBack();
292                 g_mutex.unlock();
293                 return Contacts::RDB_EXECUTE_FAIL;
294             }
295         }
296     }
297     int markRet = contactDataBase_->Commit();
298     if (!IsCommitOK(markRet, g_mutex)) {
299         g_mutex.unlock();
300         return Contacts::RDB_EXECUTE_FAIL;
301     }
302     DataBaseNotifyChange(Contacts::CONTACT_INSERT, uri);
303     g_mutex.unlock();
304     return Contacts::OPERATION_OK;
305 }
306 
307 /**
308  * @brief Update ContactsDataAbility in the database
309  *
310  * @param uri URI of the data table to be inserted
311  * @param predicates Conditions for updating data value
312  *
313  * @return Update database results code
314  */
Update(const Uri & uri,const DataShare::DataSharePredicates & predicates,const DataShare::DataShareValuesBucket & value)315 int ContactsDataAbility::Update(
316     const Uri &uri, const DataShare::DataSharePredicates &predicates, const DataShare::DataShareValuesBucket &value)
317 {
318     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
319         HILOG_ERROR("Permission denied!");
320         return Contacts::RDB_PERMISSION_ERROR;
321     }
322     OHOS::NativeRdb::ValuesBucket valuesBucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(value);
323     Contacts::SqlAnalyzer sqlAnalyzer;
324     bool isOk = sqlAnalyzer.CheckValuesBucket(valuesBucket);
325     if (!isOk) {
326         HILOG_ERROR("ContactsDataAbility CheckValuesBucket error");
327         return Contacts::RDB_EXECUTE_FAIL;
328     }
329     g_mutex.lock();
330     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
331     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
332     int retCode = Contacts::RDB_EXECUTE_FAIL;
333     OHOS::Uri uriTemp = uri;
334     int code = UriParseAndSwitch(uriTemp);
335     DataShare::DataSharePredicates dataSharePredicates = predicates;
336     UpdateExecute(retCode, code, valuesBucket, dataSharePredicates);
337     g_mutex.unlock();
338     DataBaseNotifyChange(Contacts::CONTACT_UPDATE, uri);
339     return retCode;
340 }
341 
UpdateExecute(int & retCode,int code,const OHOS::NativeRdb::ValuesBucket & value,DataShare::DataSharePredicates & dataSharePredicates)342 void ContactsDataAbility::UpdateExecute(int &retCode, int code, const OHOS::NativeRdb::ValuesBucket &value,
343     DataShare::DataSharePredicates &dataSharePredicates)
344 {
345     Contacts::PredicatesConvert predicatesConvert;
346     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
347     switch (code) {
348         case Contacts::CONTACTS_CONTACT:
349         case Contacts::PROFILE_CONTACT:
350             break;
351         case Contacts::CONTACTS_RAW_CONTACT:
352         case Contacts::PROFILE_RAW_CONTACT:
353             rdbPredicates =
354                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
355             retCode = contactDataBase_->UpdateRawContact(value, rdbPredicates);
356             break;
357         case Contacts::CONTACTS_CONTACT_DATA:
358         case Contacts::PROFILE_CONTACT_DATA:
359             rdbPredicates =
360                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
361             retCode = contactDataBase_->UpdateContactData(value, rdbPredicates);
362             break;
363         case Contacts::CONTACTS_GROUPS:
364         case Contacts::PROFILE_GROUPS:
365             rdbPredicates =
366                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
367             retCode = contactDataBase_->UpdateGroup(value, rdbPredicates);
368             break;
369         case Contacts::CONTACTS_BLOCKLIST:
370         case Contacts::PROFILE_BLOCKLIST:
371             rdbPredicates = predicatesConvert.ConvertPredicates(
372                 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
373             retCode = contactDataBase_->UpdateBlockList(value, rdbPredicates);
374             break;
375         default:
376             SwitchUpdate(retCode, code, value, dataSharePredicates);
377             break;
378     }
379 }
380 
SwitchUpdate(int & retCode,int & code,const OHOS::NativeRdb::ValuesBucket & value,DataShare::DataSharePredicates & dataSharePredicates)381 void ContactsDataAbility::SwitchUpdate(int &retCode, int &code, const OHOS::NativeRdb::ValuesBucket &value,
382     DataShare::DataSharePredicates &dataSharePredicates)
383 {
384     Contacts::PredicatesConvert predicatesConvert;
385     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
386     switch (code) {
387         case Contacts::SPLIT_CONTACT:
388             retCode = contactDataBase_->Split(dataSharePredicates);
389             break;
390         case Contacts::MANUAL_MERGE:
391             retCode = contactDataBase_->ReContactMerge(dataSharePredicates);
392             break;
393         case Contacts::AUTO_MERGE:
394             retCode = contactDataBase_->ContactMerge();
395             break;
396         case Contacts::CONTACT_BACKUP:
397         case Contacts::PROFILE_BACKUP:
398             retCode = BackUp();
399             break;
400         case Contacts::CONTACT_RECOVER:
401         case Contacts::PROFILE_RECOVER:
402             retCode = Recover(code);
403             break;
404         default:
405             retCode = Contacts::RDB_EXECUTE_FAIL;
406             HILOG_ERROR("ContactsDataAbility ====>no match uri action");
407             break;
408     }
409 }
410 
411 /**
412  * @brief Delete ContactsDataAbility from the database
413  *
414  * @param uri URI for the data table storing ContactsDataAbility
415  * @param predicates Conditions for deleting data values
416  *
417  * @return Delete database results code
418  */
Delete(const Uri & uri,const DataShare::DataSharePredicates & predicates)419 int ContactsDataAbility::Delete(const Uri &uri, const DataShare::DataSharePredicates &predicates)
420 {
421     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::WRITE_CONTACTS)) {
422         HILOG_ERROR("Permission denied!");
423         return Contacts::RDB_PERMISSION_ERROR;
424     }
425     HILOG_INFO("ContactsDataAbility ====>Delete");
426     g_mutex.lock();
427     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
428     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
429     int retCode = Contacts::RDB_EXECUTE_FAIL;
430     OHOS::Uri uriTemp = uri;
431     int code = UriParseAndSwitch(uriTemp);
432     DataShare::DataSharePredicates dataSharePredicates = predicates;
433     DeleteExecute(retCode, code, dataSharePredicates);
434     g_mutex.unlock();
435     DataBaseNotifyChange(Contacts::CONTACT_DELETE, uri);
436     return retCode;
437 }
438 
DeleteExecute(int & retCode,int code,DataShare::DataSharePredicates & dataSharePredicates)439 void ContactsDataAbility::DeleteExecute(
440     int &retCode, int code, DataShare::DataSharePredicates &dataSharePredicates)
441 {
442     Contacts::PredicatesConvert predicatesConvert;
443     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
444     switch (code) {
445         case Contacts::CONTACTS_CONTACT:
446         case Contacts::PROFILE_CONTACT:
447             rdbPredicates =
448                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT, dataSharePredicates);
449             retCode = contactDataBase_->DeleteContact(rdbPredicates);
450             break;
451         case Contacts::CONTACTS_RAW_CONTACT:
452         case Contacts::PROFILE_RAW_CONTACT:
453             rdbPredicates =
454                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::RAW_CONTACT, dataSharePredicates);
455             retCode = contactDataBase_->DeleteRawContact(rdbPredicates);
456             break;
457         case Contacts::CONTACTS_CONTACT_DATA:
458         case Contacts::PROFILE_CONTACT_DATA:
459             rdbPredicates =
460                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_DATA, dataSharePredicates);
461             retCode = contactDataBase_->DeleteContactData(rdbPredicates);
462             break;
463         case Contacts::CONTACTS_GROUPS:
464         case Contacts::PROFILE_GROUPS:
465             rdbPredicates =
466                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::GROUPS, dataSharePredicates);
467             retCode = contactDataBase_->DeleteGroup(rdbPredicates);
468             break;
469         case Contacts::CONTACTS_BLOCKLIST:
470         case Contacts::PROFILE_BLOCKLIST:
471             rdbPredicates = predicatesConvert.ConvertPredicates(
472                 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
473             retCode = contactDataBase_->DeleteBlockList(rdbPredicates);
474             break;
475         case Contacts::CONTACTS_DELETE:
476         case Contacts::PROFILE_DELETE:
477             rdbPredicates =
478                 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_DELETED, dataSharePredicates);
479             retCode = contactDataBase_->CompletelyDelete(rdbPredicates);
480             break;
481         case Contacts::CONTACTS_DELETE_RECORD:
482         case Contacts::PROFILE_DELETE_RECORD:
483             rdbPredicates = predicatesConvert.ConvertPredicates(
484                 Contacts::ContactTableName::DELETE_RAW_CONTACT, dataSharePredicates);
485             retCode = contactDataBase_->DeleteRecord(rdbPredicates);
486             break;
487         default:
488             retCode = Contacts::OPERATION_ERROR;
489             HILOG_ERROR("ContactsDataAbility ====>No matching URI action");
490             break;
491     }
492 }
493 
494 /**
495  * @brief Query contact data in the database
496  *
497  * @param uri URI of the data table that stores the contact data
498  * @param columns Columns where the contact data is located
499  * @param predicates Condition for querying data values
500  *
501  * @return Database query result
502  */
Query(const Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns,DataShare::DatashareBusinessError & businessError)503 std::shared_ptr<DataShare::DataShareResultSet> ContactsDataAbility::Query(const Uri &uri,
504     const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns,
505     DataShare::DatashareBusinessError &businessError)
506 {
507     if (!Telephony::TelephonyPermission::CheckPermission(Telephony::Permission::READ_CONTACTS)) {
508         HILOG_ERROR("Permission denied!");
509         return nullptr;
510     }
511     HILOG_INFO("ContactsDataAbility ====>Query start");
512     g_mutex.lock();
513     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
514     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
515     std::shared_ptr<OHOS::NativeRdb::ResultSet> result;
516     OHOS::Uri uriTemp = uri;
517     int parseCode = UriParseAndSwitch(uriTemp);
518     std::vector<std::string> columnsTemp = columns;
519     DataShare::DataSharePredicates dataSharePredicates = predicates;
520     bool isUriMatch = QueryExecute(result, dataSharePredicates, columnsTemp, parseCode);
521     if (!isUriMatch) {
522         g_mutex.unlock();
523         return nullptr;
524     }
525     if (result == nullptr) {
526         HILOG_ERROR("AbsSharedResultSet result is nullptr in ContactsDataAbility::Query");
527         g_mutex.unlock();
528         return nullptr;
529     }
530     auto queryResultSet = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(result);
531     std::shared_ptr<DataShare::DataShareResultSet> sharedPtrResult =
532         std::make_shared<DataShare::DataShareResultSet>(queryResultSet);
533     g_mutex.unlock();
534     HILOG_INFO("ContactsDataAbility ====>Query end");
535     return sharedPtrResult;
536 }
537 
QueryExecute(std::shared_ptr<OHOS::NativeRdb::ResultSet> & result,DataShare::DataSharePredicates & dataSharePredicates,std::vector<std::string> & columnsTemp,int & parseCode)538 bool ContactsDataAbility::QueryExecute(std::shared_ptr<OHOS::NativeRdb::ResultSet> &result,
539     DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
540     int &parseCode)
541 {
542     Contacts::PredicatesConvert predicatesConvert;
543     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
544     bool isUriMatch = true;
545     switch (parseCode) {
546         case Contacts::CONTACTS_CONTACT:
547         case Contacts::PROFILE_CONTACT:
548             rdbPredicates =
549                 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT, dataSharePredicates);
550             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
551             break;
552         case Contacts::CONTACTS_RAW_CONTACT:
553         case Contacts::PROFILE_RAW_CONTACT:
554             rdbPredicates =
555                 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_RAW_CONTACT, dataSharePredicates);
556             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
557             break;
558         case Contacts::CONTACTS_CONTACT_DATA:
559         case Contacts::PROFILE_CONTACT_DATA:
560             rdbPredicates =
561                 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_CONTACT_DATA, dataSharePredicates);
562             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
563             break;
564         case Contacts::CONTACTS_GROUPS:
565         case Contacts::PROFILE_GROUPS:
566             rdbPredicates = predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_GROUPS, dataSharePredicates);
567             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
568             break;
569         default:
570             isUriMatch = QueryExecuteSwitchSplit(result, dataSharePredicates, columnsTemp, parseCode);
571             break;
572     }
573     return isUriMatch;
574 }
575 
QueryExecuteSwitchSplit(std::shared_ptr<OHOS::NativeRdb::ResultSet> & result,DataShare::DataSharePredicates & dataSharePredicates,std::vector<std::string> & columnsTemp,int & parseCode)576 bool ContactsDataAbility::QueryExecuteSwitchSplit(std::shared_ptr<OHOS::NativeRdb::ResultSet> &result,
577     DataShare::DataSharePredicates &dataSharePredicates, std::vector<std::string> &columnsTemp,
578     int &parseCode)
579 {
580     Contacts::PredicatesConvert predicatesConvert;
581     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
582     bool isUriMatch = true;
583     switch (parseCode) {
584         case Contacts::CONTACTS_BLOCKLIST:
585         case Contacts::PROFILE_BLOCKLIST:
586             rdbPredicates = predicatesConvert.ConvertPredicates(
587                 Contacts::ContactTableName::CONTACT_BLOCKLIST, dataSharePredicates);
588             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
589             break;
590         case Contacts::CONTACTS_DELETE:
591         case Contacts::PROFILE_DELETE:
592             rdbPredicates =
593                 predicatesConvert.ConvertPredicates(Contacts::ViewName::VIEW_DELETED, dataSharePredicates);
594             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
595             break;
596         case Contacts::CONTACTS_SEARCH_CONTACT:
597         case Contacts::PROFILE_SEARCH_CONTACT:
598             rdbPredicates =
599                 predicatesConvert.ConvertPredicates(Contacts::ViewName::SEARCH_CONTACT_VIEW, dataSharePredicates);
600             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
601             break;
602         case Contacts::QUERY_MERGE_LIST:
603             result = contactDataBase_->SelectCandidate();
604             break;
605         case Contacts::CONTACT_TYPE:
606         case Contacts::PROFILE_TYPE:
607             rdbPredicates =
608                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::CONTACT_TYPE, dataSharePredicates);
609             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
610             break;
611         case Contacts::ACCOUNT:
612             rdbPredicates =
613                 predicatesConvert.ConvertPredicates(Contacts::ContactTableName::ACCOUNT, dataSharePredicates);
614             result = contactDataBase_->Query(rdbPredicates, columnsTemp);
615             break;
616         default:
617             isUriMatch = false;
618             HILOG_ERROR("ContactsDataAbility ====>no matching uri action");
619             break;
620     }
621     return isUriMatch;
622 }
623 
UriParseAndSwitch(Uri & uri)624 int ContactsDataAbility::UriParseAndSwitch(Uri &uri)
625 {
626     Contacts::UriUtils uriUtils;
627     int parseCode = uriUtils.UriParse(uri, uriValueMap_);
628     if (parseCode != Contacts::OPERATION_ERROR) {
629         SwitchProfile(uri);
630     }
631     return parseCode;
632 }
633 
SwitchProfile(Uri & uri)634 void ContactsDataAbility::SwitchProfile(Uri &uri)
635 {
636     std::vector<std::string> pathVector;
637     uri.GetPathSegments(pathVector);
638     if (pathVector.size() > 1 && pathVector[1].find("profile") == std::string::npos) {
639         contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
640         contactDataBase_->store_ = contactDataBase_->contactStore_;
641     } else {
642         profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
643         contactDataBase_->store_ = profileDataBase_->store_;
644     }
645 }
646 
BackUp()647 int ContactsDataAbility::BackUp()
648 {
649     std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
650         OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
651     int retCode = instance->SQLiteCheckDb();
652     if (retCode == 0) {
653         retCode = instance->BackDatabase();
654     }
655     return retCode;
656 }
657 
Recover(int & code)658 int ContactsDataAbility::Recover(int &code)
659 {
660     std::string name = Contacts::PROFILE_DATABASE_NAME;
661     if (code == Contacts::CONTACT_RECOVER) {
662         name = Contacts::CONTACT_DATABASE_NAME;
663     }
664     std::shared_ptr<OHOS::Contacts::DataBaseDisasterRecovery> instance =
665         OHOS::Contacts::DataBaseDisasterRecovery::GetInstance();
666     int retCode = instance->RecoveryDatabase(name);
667     contactDataBase_ = Contacts::ContactsDataBase::GetInstance();
668     profileDataBase_ = Contacts::ProfileDatabase::GetInstance();
669     return retCode;
670 }
671 
DataBaseNotifyChange(int code,Uri uri)672 void ContactsDataAbility::DataBaseNotifyChange(int code, Uri uri)
673 {
674     Contacts::ContactsCommonEvent::SendContactChange(code);
675 }
676 } // namespace AbilityRuntime
677 } // namespace OHOS