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