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