• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "call_data_base_helper.h"
17 
18 #include "ability_context.h"
19 #include "call_manager_errors.h"
20 #include "call_number_utils.h"
21 #include "iservice_registry.h"
22 #include "phonenumbers/phonenumber.pb.h"
23 #include "phonenumberutil.h"
24 #include "telephony_log_wrapper.h"
25 #include "os_account_manager.h"
26 #include "system_ability_definition.h"
27 
28 namespace OHOS {
29 namespace Telephony {
30 class AbsSharedResultSet;
31 static constexpr const char *CALLLOG_URI = "datashare:///com.ohos.calllogability";
32 static constexpr const char *CALL_SUBSECTION = "datashare:///com.ohos.calllogability/calls/calllog";
33 static const std::string CALL_SUBSECTION_SILENCE =
34     "datashareproxy://com.ohos.contactsdataability/calls/calllog?Proxy=true&user=";
35 static constexpr const char *CONTACT_URI = "datashare:///com.ohos.contactsdataability";
36 static constexpr const char *CALL_BLOCK = "datashare:///com.ohos.contactsdataability/contacts/contact_blocklist";
37 static constexpr const char *CONTACT_DATA = "datashare:///com.ohos.contactsdataability/contacts/contact_data";
38 static constexpr const char *ISO_COUNTRY_CODE = "CN";
39 static constexpr const char *SETTINGS_DATA_URI =
40     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
41 static constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
42 static constexpr const char *SETTINGS_AIRPLANE_MODE_URI =
43     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=airplane_mode";
44 static constexpr const char *SETTINGS_AIRPLANE_MODE = "settings.telephony.airplanemode";
45 static constexpr const int32_t MAX_WAITIME_TIME = 10;
46 constexpr int32_t E_OK = 0;
47 
CallDataRdbObserver(std::vector<std::string> * phones)48 CallDataRdbObserver::CallDataRdbObserver(std::vector<std::string> *phones)
49 {
50     if (phones == nullptr) {
51         TELEPHONY_LOGE("phones is nullptr");
52     }
53     this->phones = phones;
54 }
55 
~CallDataRdbObserver()56 CallDataRdbObserver::~CallDataRdbObserver() {}
57 
OnChange()58 void CallDataRdbObserver::OnChange()
59 {
60     std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
61     if (callDataPtr == nullptr) {
62         TELEPHONY_LOGE("callDataPtr is nullptr!");
63         return;
64     }
65 
66     DataShare::DataSharePredicates predicates;
67     predicates.NotEqualTo("phone_number", std::string(""));
68     this->phones->clear();
69     callDataPtr->Query(this->phones, predicates);
70 }
71 
CallDataBaseHelper()72 CallDataBaseHelper::CallDataBaseHelper() {}
73 
~CallDataBaseHelper()74 CallDataBaseHelper::~CallDataBaseHelper() {}
75 
CreateDataShareHelper(std::string uri)76 std::shared_ptr<DataShare::DataShareHelper> CallDataBaseHelper::CreateDataShareHelper(std::string uri)
77 {
78     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
79     if (saManager == nullptr) {
80         TELEPHONY_LOGE("Get system ability mgr failed.");
81         return nullptr;
82     }
83     auto remoteObj = saManager->GetSystemAbility(TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
84     if (remoteObj == nullptr) {
85         TELEPHONY_LOGE("GetSystemAbility Service Failed.");
86         return nullptr;
87     }
88     if (uri == SETTINGS_DATA_URI) {
89         return DataShare::DataShareHelper::Creator(remoteObj, uri, SETTINGS_DATA_EXT_URI);
90     }
91     return DataShare::DataShareHelper::Creator(remoteObj, uri, "", MAX_WAITIME_TIME);
92 }
93 
RegisterObserver(std::vector<std::string> * phones)94 void CallDataBaseHelper::RegisterObserver(std::vector<std::string> *phones)
95 {
96     if (phones == nullptr) {
97         TELEPHONY_LOGE("phones is nullptr");
98         return;
99     }
100     callDataRdbObserverPtr_ = new (std::nothrow) CallDataRdbObserver(phones);
101     if (callDataRdbObserverPtr_ == nullptr) {
102         TELEPHONY_LOGE("callDataRdbObserverPtr_ is null");
103         return;
104     }
105     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
106     if (helper == nullptr) {
107         TELEPHONY_LOGE("helper is null");
108         return;
109     }
110     Uri uri(CALL_BLOCK);
111     helper->RegisterObserver(uri, callDataRdbObserverPtr_);
112     helper->Release();
113 }
114 
UnRegisterObserver()115 void CallDataBaseHelper::UnRegisterObserver()
116 {
117     if (callDataRdbObserverPtr_ == nullptr) {
118         TELEPHONY_LOGE("callDataRdbObserverPtr_ is null");
119         return;
120     }
121     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
122     if (helper == nullptr) {
123         TELEPHONY_LOGE("helper_ is null");
124         return;
125     }
126     Uri uri(CALL_BLOCK);
127     helper->UnregisterObserver(uri, callDataRdbObserverPtr_);
128     helper->Release();
129 }
130 
Insert(DataShare::DataShareValuesBucket & values)131 bool CallDataBaseHelper::Insert(DataShare::DataShareValuesBucket &values)
132 {
133     std::shared_ptr<DataShare::DataShareHelper> helper = nullptr;
134     std::string url;
135     bool result = GetHelperAndUrl(helper, url);
136     if (!result) {
137         TELEPHONY_LOGE("GetHelperAndUrl fail!");
138         return false;
139     }
140 
141     Uri uri(url);
142     result = (helper->Insert(uri, values) > 0);
143     helper->Release();
144     return result;
145 }
146 
Query(std::vector<std::string> * phones,DataShare::DataSharePredicates & predicates)147 bool CallDataBaseHelper::Query(std::vector<std::string> *phones, DataShare::DataSharePredicates &predicates)
148 {
149     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
150     if (helper == nullptr) {
151         TELEPHONY_LOGE("helper is nullptr");
152         return false;
153     }
154     Uri uri(CALL_BLOCK);
155     std::vector<std::string> columns;
156     columns.push_back("phone_number");
157     auto resultSet = helper->Query(uri, predicates, columns);
158     if (resultSet == nullptr) {
159         helper->Release();
160         return false;
161     }
162     int32_t resultSetNum = resultSet->GoToFirstRow();
163     while (resultSetNum == 0) {
164         std::string phone;
165         int32_t columnIndex;
166         resultSet->GetColumnIndex("phone_number", columnIndex);
167         int32_t ret = resultSet->GetString(columnIndex, phone);
168         if (ret == 0 && (!phone.empty())) {
169             phones->push_back(phone);
170         }
171         resultSetNum = resultSet->GoToNextRow();
172     }
173     resultSet->Close();
174     helper->Release();
175     TELEPHONY_LOGI("Query end");
176     return true;
177 }
178 
Query(ContactInfo & contactInfo,DataShare::DataSharePredicates & predicates)179 bool CallDataBaseHelper::Query(ContactInfo &contactInfo, DataShare::DataSharePredicates &predicates)
180 {
181     TELEPHONY_LOGI("QueryCallerInfo use normal query");
182     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
183     if (helper == nullptr) {
184         TELEPHONY_LOGE("helper is nullptr");
185         return false;
186     }
187     Uri uri(CONTACT_DATA);
188     std::vector<std::string> columns;
189     auto resultSet = helper->Query(uri, predicates, columns);
190     if (!CheckResultSet(resultSet)) {
191         TELEPHONY_LOGE("resultSet is null");
192         helper->Release();
193         return false;
194     }
195     if (resultSet->GoToFirstRow() != E_OK) {
196         TELEPHONY_LOGE("GoToFirstRow failed");
197         resultSet->Close();
198         helper->Release();
199         return false;
200     }
201     int32_t columnIndex;
202     std::string ringtonePath = "";
203     resultSet->GetColumnIndex(CALL_DISPLAY_NAME, columnIndex);
204     resultSet->GetString(columnIndex, contactInfo.name);
205     resultSet->GetColumnIndex(PERSONAL_RINGTONE, columnIndex);
206     resultSet->GetString(columnIndex, ringtonePath);
207     uint32_t length = ringtonePath.length() > FILE_PATH_MAX_LEN ? FILE_PATH_MAX_LEN : ringtonePath.length();
208     if (memcpy_s(contactInfo.ringtonePath, FILE_PATH_MAX_LEN, ringtonePath.c_str(), length) != EOK) {
209         TELEPHONY_LOGE("memcpy_s ringtonePath fail!");
210         return false;
211     }
212     TELEPHONY_LOGI("ringtonePath: %{public}s", contactInfo.ringtonePath);
213     resultSet->Close();
214     helper->Release();
215     TELEPHONY_LOGI("Query end, contactName length: %{public}zu", contactInfo.name.length());
216     return true;
217 }
218 
GetHelperAndUrl(std::shared_ptr<DataShare::DataShareHelper> & helper,std::string & url)219 bool CallDataBaseHelper::GetHelperAndUrl(std::shared_ptr<DataShare::DataShareHelper> &helper, std::string &url)
220 {
221     int32_t userId = 0;
222     bool isUserUnlocked = false;
223     AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
224     AccountSA::OsAccountManager::IsOsAccountVerified(userId, isUserUnlocked);
225     TELEPHONY_LOGI("isUserUnlocked: %{public}d", isUserUnlocked);
226     if (!isUserUnlocked) {
227         helper = CreateDataShareHelper(CALL_SUBSECTION_SILENCE + std::to_string(userId));
228         url = CALL_SUBSECTION_SILENCE + std::to_string(userId);
229     } else {
230         helper = CreateDataShareHelper(CALLLOG_URI);
231         url = CALL_SUBSECTION;
232     }
233     if (helper == nullptr) {
234         TELEPHONY_LOGE("helper is nullptr!");
235         return false;
236     }
237     return true;
238 }
239 
QueryCallLog(std::map<std::string,int32_t> & phoneNumAndUnreadCountMap,DataShare::DataSharePredicates & predicates)240 bool CallDataBaseHelper::QueryCallLog(
241     std::map<std::string, int32_t> &phoneNumAndUnreadCountMap, DataShare::DataSharePredicates &predicates)
242 {
243     std::shared_ptr<DataShare::DataShareHelper> helper = nullptr;
244     std::string url;
245     bool result = GetHelperAndUrl(helper, url);
246     if (!result) {
247         TELEPHONY_LOGE("GetHelperAndUrl fail!");
248         return false;
249     }
250 
251     Uri uri(url);
252     std::vector<std::string> columns;
253     columns.push_back(CALL_PHONE_NUMBER);
254     auto resultSet = helper->Query(uri, predicates, columns);
255     if (resultSet == nullptr) {
256         TELEPHONY_LOGE("resultSet is nullptr!");
257         helper->Release();
258         return false;
259     }
260     int32_t operationResult = resultSet->GoToFirstRow();
261     while (operationResult == TELEPHONY_SUCCESS) {
262         std::string phoneNumber = "";
263         int32_t columnIndex = 0;
264         resultSet->GetColumnIndex(CALL_PHONE_NUMBER, columnIndex);
265         operationResult = resultSet->GetString(columnIndex, phoneNumber);
266         if (operationResult == TELEPHONY_SUCCESS && (!phoneNumber.empty())) {
267             auto iter = phoneNumAndUnreadCountMap.find(phoneNumber);
268             if (iter != phoneNumAndUnreadCountMap.end()) {
269                 iter->second++;
270             } else {
271                 phoneNumAndUnreadCountMap.insert(
272                     std::map<std::string, int32_t>::value_type(phoneNumber, CALL_LOG_DEFAULT_COUNT));
273             }
274         }
275         operationResult = resultSet->GoToNextRow();
276     }
277     resultSet->Close();
278     helper->Release();
279     TELEPHONY_LOGI("QueryCallLog end");
280     return true;
281 }
282 
QueryAndDeleteLimitedIds(DataShare::DataSharePredicates & predicates)283 bool CallDataBaseHelper::QueryAndDeleteLimitedIds(DataShare::DataSharePredicates &predicates)
284 {
285     std::shared_ptr<DataShare::DataShareHelper> helper = nullptr;
286     std::string url;
287     bool result = GetHelperAndUrl(helper, url);
288     if (!result) {
289         TELEPHONY_LOGE("GetHelperAndUrl fail!");
290         return false;
291     }
292 
293     Uri uri(url);
294     std::vector<std::string> columns;
295     columns.push_back(CALL_ID);
296     auto resultSet = helper->Query(uri, predicates, columns);
297     if (resultSet == nullptr) {
298         TELEPHONY_LOGE("resultSet is nullptr!");
299         helper->Release();
300         return false;
301     }
302     int32_t operationResult = resultSet->GoToFirstRow();
303     while (operationResult == TELEPHONY_SUCCESS) {
304         int32_t id = 0;
305         int32_t columnIndex = 0;
306         resultSet->GetColumnIndex(CALL_ID, columnIndex);
307         operationResult = resultSet->GetInt(columnIndex, id);
308         if (operationResult == TELEPHONY_SUCCESS) {
309             TELEPHONY_LOGI("need delete call log id: %{public}d", id);
310             DataShare::DataSharePredicates deletePredicates;
311             deletePredicates.EqualTo(CALL_ID, id);
312             result = (helper->Delete(uri, deletePredicates) > 0);
313             TELEPHONY_LOGI("delete result: %{public}d", result);
314         }
315         operationResult = resultSet->GoToNextRow();
316     }
317     resultSet->Close();
318     helper->Release();
319     TELEPHONY_LOGI("QueryAndDeleteLimitedIds end");
320     return true;
321 }
322 
Update(DataShare::DataSharePredicates & predicates,DataShare::DataShareValuesBucket & values)323 bool CallDataBaseHelper::Update(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
324 {
325     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
326     if (helper == nullptr) {
327         TELEPHONY_LOGE("helper is nullptr");
328         return true;
329     }
330     Uri uri(CALL_SUBSECTION);
331     bool result = (helper->Update(uri, predicates, values) > 0);
332     helper->Release();
333     return result;
334 }
335 
Delete(DataShare::DataSharePredicates & predicates)336 bool CallDataBaseHelper::Delete(DataShare::DataSharePredicates &predicates)
337 {
338     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
339     if (helper == nullptr) {
340         TELEPHONY_LOGE("helper is nullptr!");
341         return false;
342     }
343     Uri uri(CALL_SUBSECTION);
344     bool result = (helper->Delete(uri, predicates) > 0);
345     TELEPHONY_LOGI("delete result: %{public}d", result);
346     helper->Release();
347     return result;
348 }
349 
QueryIsBlockPhoneNumber(const std::string & phoneNum,bool & result)350 int32_t CallDataBaseHelper::QueryIsBlockPhoneNumber(const std::string &phoneNum, bool &result)
351 {
352     result = false;
353     std::shared_ptr<DataShare::DataShareHelper> callDataHelper = CreateDataShareHelper(CALLLOG_URI);
354     if (callDataHelper == nullptr) {
355         TELEPHONY_LOGE("callDataHelper is nullptr!");
356         return TELEPHONY_ERR_LOCAL_PTR_NULL;
357     }
358     Uri uri(CALL_BLOCK);
359     DataShare::DataSharePredicates predicates;
360     std::vector<std::string> columns;
361     std::string internationalNumber;
362     std::string nationalNumber;
363     int32_t ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToNational(
364         phoneNum, ISO_COUNTRY_CODE, nationalNumber);
365     if (ret != TELEPHONY_SUCCESS) {
366         TELEPHONY_LOGE("Format phone number failed.");
367         nationalNumber = phoneNum;
368     }
369     ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToInternational(
370         phoneNum, ISO_COUNTRY_CODE, internationalNumber);
371     if (ret != TELEPHONY_SUCCESS) {
372         TELEPHONY_LOGE("Format phone number failed.");
373         internationalNumber = phoneNum;
374     }
375     predicates.EqualTo(CALL_PHONE_NUMBER, nationalNumber)->Or()->EqualTo(CALL_PHONE_NUMBER, internationalNumber);
376     auto resultSet = callDataHelper->Query(uri, predicates, columns);
377     if (resultSet == nullptr) {
378         TELEPHONY_LOGE("Query Result Set nullptr Failed.");
379         callDataHelper->Release();
380         return TELEPHONY_ERR_LOCAL_PTR_NULL;
381     }
382     int32_t count = 0;
383     if (resultSet->GetRowCount(count) == E_OK && count != 0) {
384         result = true;
385     }
386     TELEPHONY_LOGI("count: %{public}d", count);
387     resultSet->Close();
388     callDataHelper->Release();
389     return TELEPHONY_SUCCESS;
390 }
391 
GetAirplaneMode(bool & isAirplaneModeOn)392 int32_t CallDataBaseHelper::GetAirplaneMode(bool &isAirplaneModeOn)
393 {
394     std::shared_ptr<DataShare::DataShareHelper> callDataHelper = CreateDataShareHelper(SETTINGS_DATA_URI);
395     if (callDataHelper == nullptr) {
396         TELEPHONY_LOGE("callDataHelper is null");
397         return TELEPHONY_ERR_LOCAL_PTR_NULL;
398     }
399     Uri uri(SETTINGS_AIRPLANE_MODE_URI);
400     std::vector<std::string> columns;
401     DataShare::DataSharePredicates predicates;
402     predicates.EqualTo(SETTING_KEY, SETTINGS_AIRPLANE_MODE);
403     auto result = callDataHelper->Query(uri, predicates, columns);
404     if (result == nullptr) {
405         TELEPHONY_LOGE("CallDataBaseHelper: query error, result is null");
406         callDataHelper->Release();
407         return TELEPHONY_ERR_LOCAL_PTR_NULL;
408     }
409     if (result->GoToFirstRow() != DataShare::E_OK) {
410         TELEPHONY_LOGE("CallDataBaseHelper: query error, go to first row error");
411         result->Close();
412         callDataHelper->Release();
413         return TELEPHONY_ERR_DATABASE_READ_FAIL;
414     }
415     int32_t columnindex = 0;
416     std::string value = "";
417     result->GetColumnIndex(SETTING_VALUE, columnindex);
418     result->GetString(columnindex, value);
419     result->Close();
420     callDataHelper->Release();
421     isAirplaneModeOn = value == "1";
422     TELEPHONY_LOGI("Get airplane mode:%{public}d", isAirplaneModeOn);
423     return TELEPHONY_SUCCESS;
424 }
425 
CheckResultSet(std::shared_ptr<DataShare::DataShareResultSet> resultSet)426 bool CallDataBaseHelper::CheckResultSet(std::shared_ptr<DataShare::DataShareResultSet> resultSet)
427 {
428     if (resultSet == nullptr) {
429         TELEPHONY_LOGE("resultSet is nullptr");
430         return false;
431     }
432     int rowCount = 0;
433     resultSet->GetRowCount(rowCount);
434     if (rowCount == 0) {
435         TELEPHONY_LOGE("query success, but rowCount is 0");
436         resultSet->Close();
437         return false;
438     }
439     return true;
440 }
441 
442 #ifdef TELEPHONY_CUST_SUPPORT
QueryContactInfoEnhanced(ContactInfo & contactInfo,DataShare::DataSharePredicates & predicates)443 bool CallDataBaseHelper::QueryContactInfoEnhanced(ContactInfo &contactInfo, DataShare::DataSharePredicates &predicates)
444 {
445     TELEPHONY_LOGI("QueryCallerInfo use enhanced query.");
446     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
447     if (helper == nullptr) {
448         TELEPHONY_LOGE("helper is nullptr");
449         return false;
450     }
451     Uri uri(CONTACT_DATA);
452     std::vector<std::string> columns;
453     auto resultSet = helper->Query(uri, predicates, columns);
454     if (!CheckResultSet(resultSet)) {
455         TELEPHONY_LOGE("resultSet is null!");
456         helper->Release();
457         return false;
458     }
459     int resultId = GetCallerIndex(resultSet, contactInfo.number);
460     TELEPHONY_LOGI("index: %{public}d", resultId);
461     if (resultSet->GoToRow(resultId) != E_OK) {
462         TELEPHONY_LOGE("GoToRow failed");
463         resultSet->Close();
464         helper->Release();
465         return false;
466     }
467     int32_t columnIndex;
468     std::string ringtonePath = "";
469     resultSet->GetColumnIndex(CALL_DISPLAY_NAME, columnIndex);
470     resultSet->GetString(columnIndex, contactInfo.name);
471     resultSet->GetColumnIndex(PERSONAL_RINGTONE, columnIndex);
472     resultSet->GetString(columnIndex, ringtonePath);
473     uint32_t length = ringtonePath.length() > FILE_PATH_MAX_LEN ? FILE_PATH_MAX_LEN : ringtonePath.length();
474     if (memcpy_s(contactInfo.ringtonePath, FILE_PATH_MAX_LEN, ringtonePath.c_str(), length) != EOK) {
475         TELEPHONY_LOGE("memcpy_s ringtonePath fail!");
476         return false;
477     }
478     TELEPHONY_LOGI("ringtonePath: %{public}s", contactInfo.ringtonePath);
479     resultSet->Close();
480     helper->Release();
481     TELEPHONY_LOGI("Query end, contactName length: %{public}zu", contactInfo.name.length());
482     return true;
483 }
484 
GetCallerIndex(std::shared_ptr<DataShare::DataShareResultSet> resultSet,std::string phoneNumber)485 int CallDataBaseHelper::GetCallerIndex(std::shared_ptr<DataShare::DataShareResultSet> resultSet,
486     std::string phoneNumber)
487 {
488     void *telephonyHandle = dlopen(TELEPHONY_CUST_SO_PATH.c_str(), RTLD_LAZY);
489     if (telephonyHandle == nullptr) {
490         TELEPHONY_LOGE("telephonyHandle is nullptr");
491         return -1;
492     }
493     typedef int (*GetCallerIndex) (std::shared_ptr<DataShare::DataShareResultSet>, std::string);
494     GetCallerIndex getCallerIndex = reinterpret_cast<GetCallerIndex>(dlsym(telephonyHandle, "GetCallerNumIndex"));
495     if (getCallerIndex == nullptr) {
496         TELEPHONY_LOGE("getCallerIndex is nullptr");
497         dlclose(telephonyHandle);
498         return -1;
499     }
500     int resultId = getCallerIndex(resultSet, phoneNumber);
501     dlclose(telephonyHandle);
502     return resultId;
503 }
504 #endif
505 } // namespace Telephony
506 } // namespace OHOS
507