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