• 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 
26 namespace OHOS {
27 namespace Telephony {
28 class AbsSharedResultSet;
29 static constexpr const char *CALLLOG_URI = "datashare:///com.ohos.calllogability";
30 static constexpr const char *CALL_SUBSECTION = "datashare:///com.ohos.calllogability/calls/calllog";
31 static constexpr const char *CONTACT_URI = "datashare:///com.ohos.contactsdataability";
32 static constexpr const char *CALL_BLOCK = "datashare:///com.ohos.contactsdataability/contacts/contact_blocklist";
33 static constexpr const char *CONTACT_DATA = "datashare:///com.ohos.contactsdataability/contacts/contact_data";
34 static constexpr const char *ISO_COUNTRY_CODE = "CN";
35 static constexpr const char *SETTINGS_DATA_URI =
36     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
37 static constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
38 static constexpr const char *SETTINGS_AIRPLANE_MODE_URI =
39     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=airplane_mode";
40 static constexpr const char *SETTINGS_AIRPLANE_MODE = "settings.telephony.airplanemode";
41 static constexpr const int32_t MAX_WAITIME_TIME = 10;
42 constexpr int32_t E_OK = 0;
43 
CallDataRdbObserver(std::vector<std::string> * phones)44 CallDataRdbObserver::CallDataRdbObserver(std::vector<std::string> *phones)
45 {
46     this->phones = phones;
47 }
48 
~CallDataRdbObserver()49 CallDataRdbObserver::~CallDataRdbObserver() {}
50 
OnChange()51 void CallDataRdbObserver::OnChange()
52 {
53     std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
54     if (callDataPtr == nullptr) {
55         TELEPHONY_LOGE("callDataPtr is nullptr!");
56         return;
57     }
58 
59     DataShare::DataSharePredicates predicates;
60     predicates.NotEqualTo("phone_number", std::string(""));
61     this->phones->clear();
62     callDataPtr->Query(this->phones, predicates);
63 }
64 
CallDataBaseHelper()65 CallDataBaseHelper::CallDataBaseHelper() {}
66 
~CallDataBaseHelper()67 CallDataBaseHelper::~CallDataBaseHelper() {}
68 
CreateDataShareHelper(std::string uri)69 std::shared_ptr<DataShare::DataShareHelper> CallDataBaseHelper::CreateDataShareHelper(std::string uri)
70 {
71     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72     if (saManager == nullptr) {
73         TELEPHONY_LOGE("Get system ability mgr failed.");
74         return nullptr;
75     }
76     auto remoteObj = saManager->GetSystemAbility(TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
77     if (remoteObj == nullptr) {
78         TELEPHONY_LOGE("GetSystemAbility Service Failed.");
79         return nullptr;
80     }
81     if (uri == SETTINGS_DATA_URI) {
82         return DataShare::DataShareHelper::Creator(remoteObj, uri, SETTINGS_DATA_EXT_URI);
83     }
84     return DataShare::DataShareHelper::Creator(remoteObj, uri, "", MAX_WAITIME_TIME);
85 }
86 
RegisterObserver(std::vector<std::string> * phones)87 void CallDataBaseHelper::RegisterObserver(std::vector<std::string> *phones)
88 {
89     callDataRdbObserverPtr_ = new (std::nothrow) CallDataRdbObserver(phones);
90     if (callDataRdbObserverPtr_ == nullptr) {
91         TELEPHONY_LOGE("callDataRdbObserverPtr_ is null");
92         return;
93     }
94     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
95     if (helper == nullptr) {
96         TELEPHONY_LOGE("helper is null");
97         return;
98     }
99     Uri uri(CALL_BLOCK);
100     helper->RegisterObserver(uri, callDataRdbObserverPtr_);
101     helper->Release();
102 }
103 
UnRegisterObserver()104 void CallDataBaseHelper::UnRegisterObserver()
105 {
106     if (callDataRdbObserverPtr_ == nullptr) {
107         TELEPHONY_LOGE("callDataRdbObserverPtr_ is null");
108         return;
109     }
110     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
111     if (helper == nullptr) {
112         TELEPHONY_LOGE("helper_ is null");
113         return;
114     }
115     Uri uri(CALL_BLOCK);
116     helper->UnregisterObserver(uri, callDataRdbObserverPtr_);
117     helper->Release();
118 }
119 
Insert(DataShare::DataShareValuesBucket & values)120 bool CallDataBaseHelper::Insert(DataShare::DataShareValuesBucket &values)
121 {
122     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
123     if (helper == nullptr) {
124         TELEPHONY_LOGE("helper is nullptr!");
125         return false;
126     }
127     Uri uri(CALL_SUBSECTION);
128     bool result = (helper->Insert(uri, values) > 0);
129     helper->Release();
130     return result;
131 }
132 
Query(std::vector<std::string> * phones,DataShare::DataSharePredicates & predicates)133 bool CallDataBaseHelper::Query(std::vector<std::string> *phones, DataShare::DataSharePredicates &predicates)
134 {
135     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
136     if (helper == nullptr) {
137         TELEPHONY_LOGE("helper is nullptr");
138         return false;
139     }
140     Uri uri(CALL_BLOCK);
141     std::vector<std::string> columns;
142     columns.push_back("phone_number");
143     auto resultSet = helper->Query(uri, predicates, columns);
144     if (resultSet == nullptr) {
145         helper->Release();
146         return false;
147     }
148     int32_t resultSetNum = resultSet->GoToFirstRow();
149     while (resultSetNum == 0) {
150         std::string phone;
151         int32_t columnIndex;
152         resultSet->GetColumnIndex("phone_number", columnIndex);
153         int32_t ret = resultSet->GetString(columnIndex, phone);
154         if (ret == 0 && (!phone.empty())) {
155             phones->push_back(phone);
156         }
157         resultSetNum = resultSet->GoToNextRow();
158     }
159     resultSet->Close();
160     helper->Release();
161     TELEPHONY_LOGI("Query end");
162     return true;
163 }
164 
Query(ContactInfo & contactInfo,DataShare::DataSharePredicates & predicates)165 bool CallDataBaseHelper::Query(ContactInfo &contactInfo, DataShare::DataSharePredicates &predicates)
166 {
167     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CONTACT_URI);
168     if (helper == nullptr) {
169         TELEPHONY_LOGE("helper is nullptr");
170         return false;
171     }
172     Uri uri(CONTACT_DATA);
173     std::vector<std::string> columns;
174     auto resultSet = helper->Query(uri, predicates, columns);
175     if (resultSet == nullptr) {
176         TELEPHONY_LOGE("resultSet is nullptr");
177         helper->Release();
178         return false;
179     }
180     int32_t resultSetNum = resultSet->GoToFirstRow();
181     while (resultSetNum == 0) {
182         int32_t columnIndex;
183         resultSet->GetColumnIndex(CALL_DISPLAY_NAME, columnIndex);
184         int32_t ret = resultSet->GetString(columnIndex, contactInfo.name);
185         resultSetNum = resultSet->GoToNextRow();
186     }
187     resultSet->Close();
188     helper->Release();
189     TELEPHONY_LOGI("Query end");
190     return true;
191 }
192 
QueryCallLog(std::map<std::string,int32_t> & phoneNumAndUnreadCountMap,DataShare::DataSharePredicates & predicates)193 bool CallDataBaseHelper::QueryCallLog(
194     std::map<std::string, int32_t> &phoneNumAndUnreadCountMap, DataShare::DataSharePredicates &predicates)
195 {
196     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
197     if (helper == nullptr) {
198         TELEPHONY_LOGE("helper is nullptr!");
199         return false;
200     }
201     Uri uri(CALL_SUBSECTION);
202     std::vector<std::string> columns;
203     columns.push_back(CALL_PHONE_NUMBER);
204     auto resultSet = helper->Query(uri, predicates, columns);
205     if (resultSet == nullptr) {
206         helper->Release();
207         return false;
208     }
209     int32_t operationResult = resultSet->GoToFirstRow();
210     while (operationResult == TELEPHONY_SUCCESS) {
211         std::string phoneNumber = "";
212         int32_t columnIndex = 0;
213         resultSet->GetColumnIndex(CALL_PHONE_NUMBER, columnIndex);
214         operationResult = resultSet->GetString(columnIndex, phoneNumber);
215         if (operationResult == TELEPHONY_SUCCESS && (!phoneNumber.empty())) {
216             auto iter = phoneNumAndUnreadCountMap.find(phoneNumber);
217             if (iter != phoneNumAndUnreadCountMap.end()) {
218                 iter->second++;
219             } else {
220                 phoneNumAndUnreadCountMap.insert(
221                     std::map<std::string, int32_t>::value_type(phoneNumber, CALL_LOG_DEFAULT_COUNT));
222             }
223         }
224         operationResult = resultSet->GoToNextRow();
225     }
226     resultSet->Close();
227     helper->Release();
228     TELEPHONY_LOGI("QueryCallLog end");
229     return true;
230 }
231 
QueryAndDeleteLimitedIds(DataShare::DataSharePredicates & predicates)232 bool CallDataBaseHelper::QueryAndDeleteLimitedIds(DataShare::DataSharePredicates &predicates)
233 {
234     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
235     if (helper == nullptr) {
236         TELEPHONY_LOGE("helper is nullptr!");
237         return false;
238     }
239     Uri uri(CALL_SUBSECTION);
240     std::vector<std::string> columns;
241     columns.push_back(CALL_ID);
242     auto resultSet = helper->Query(uri, predicates, columns);
243     if (resultSet == nullptr) {
244         helper->Release();
245         return false;
246     }
247     int32_t operationResult = resultSet->GoToFirstRow();
248     while (operationResult == TELEPHONY_SUCCESS) {
249         int32_t id = 0;
250         int32_t columnIndex = 0;
251         resultSet->GetColumnIndex(CALL_ID, columnIndex);
252         operationResult = resultSet->GetInt(columnIndex, id);
253         if (operationResult == TELEPHONY_SUCCESS) {
254             TELEPHONY_LOGI("need delete call log id: %{public}d", id);
255             DataShare::DataSharePredicates deletePredicates;
256             deletePredicates.EqualTo(CALL_ID, id);
257             bool result = (helper->Delete(uri, deletePredicates) > 0);
258             TELEPHONY_LOGI("delete result: %{public}d", result);
259         }
260         operationResult = resultSet->GoToNextRow();
261     }
262     resultSet->Close();
263     helper->Release();
264     TELEPHONY_LOGI("QueryAndDeleteLimitedIds end");
265     return true;
266 }
267 
Update(DataShare::DataSharePredicates & predicates,DataShare::DataShareValuesBucket & values)268 bool CallDataBaseHelper::Update(DataShare::DataSharePredicates &predicates, DataShare::DataShareValuesBucket &values)
269 {
270     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
271     if (helper == nullptr) {
272         TELEPHONY_LOGE("helper is nullptr");
273         return true;
274     }
275     Uri uri(CALL_SUBSECTION);
276     bool result = (helper->Update(uri, predicates, values) > 0);
277     helper->Release();
278     return result;
279 }
280 
Delete(DataShare::DataSharePredicates & predicates)281 bool CallDataBaseHelper::Delete(DataShare::DataSharePredicates &predicates)
282 {
283     std::shared_ptr<DataShare::DataShareHelper> helper = CreateDataShareHelper(CALLLOG_URI);
284     if (helper == nullptr) {
285         TELEPHONY_LOGE("helper is nullptr!");
286         return false;
287     }
288     Uri uri(CALL_SUBSECTION);
289     bool result = (helper->Delete(uri, predicates) > 0);
290     TELEPHONY_LOGI("delete result: %{public}d", result);
291     helper->Release();
292     return result;
293 }
294 
QueryIsBlockPhoneNumber(const std::string & phoneNum,bool & result)295 int32_t CallDataBaseHelper::QueryIsBlockPhoneNumber(const std::string &phoneNum, bool &result)
296 {
297     result = false;
298     std::shared_ptr<DataShare::DataShareHelper> callDataHelper = CreateDataShareHelper(CALLLOG_URI);
299     if (callDataHelper == nullptr) {
300         TELEPHONY_LOGE("callDataHelper is nullptr!");
301         return TELEPHONY_ERR_LOCAL_PTR_NULL;
302     }
303     Uri uri(CALL_BLOCK);
304     DataShare::DataSharePredicates predicates;
305     std::vector<std::string> columns;
306     std::string internationalNumber;
307     std::string nationalNumber;
308     int32_t ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToNational(
309         phoneNum, ISO_COUNTRY_CODE, nationalNumber);
310     if (ret != TELEPHONY_SUCCESS) {
311         TELEPHONY_LOGE("Format phone number failed.");
312         nationalNumber = phoneNum;
313     }
314     ret = DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToInternational(
315         phoneNum, ISO_COUNTRY_CODE, internationalNumber);
316     if (ret != TELEPHONY_SUCCESS) {
317         TELEPHONY_LOGE("Format phone number failed.");
318         internationalNumber = phoneNum;
319     }
320     predicates.EqualTo(CALL_PHONE_NUMBER, nationalNumber)->Or()->EqualTo(CALL_PHONE_NUMBER, internationalNumber);
321     auto resultSet = callDataHelper->Query(uri, predicates, columns);
322     if (resultSet == nullptr) {
323         TELEPHONY_LOGE("Query Result Set nullptr Failed.");
324         callDataHelper->Release();
325         return TELEPHONY_ERR_LOCAL_PTR_NULL;
326     }
327     int32_t count = 0;
328     if (resultSet->GetRowCount(count) == E_OK && count != 0) {
329         result = true;
330     }
331     TELEPHONY_LOGI("count: %{public}d", count);
332     resultSet->Close();
333     callDataHelper->Release();
334     return TELEPHONY_SUCCESS;
335 }
336 
GetAirplaneMode(bool & isAirplaneModeOn)337 int32_t CallDataBaseHelper::GetAirplaneMode(bool &isAirplaneModeOn)
338 {
339     std::shared_ptr<DataShare::DataShareHelper> callDataHelper = CreateDataShareHelper(SETTINGS_DATA_URI);
340     if (callDataHelper == nullptr) {
341         TELEPHONY_LOGE("callDataHelper is null");
342         return TELEPHONY_ERR_LOCAL_PTR_NULL;
343     }
344     Uri uri(SETTINGS_AIRPLANE_MODE_URI);
345     std::vector<std::string> columns;
346     DataShare::DataSharePredicates predicates;
347     predicates.EqualTo(SETTING_KEY, SETTINGS_AIRPLANE_MODE);
348     auto result = callDataHelper->Query(uri, predicates, columns);
349     if (result == nullptr) {
350         TELEPHONY_LOGE("CallDataBaseHelper: query error, result is null");
351         callDataHelper->Release();
352         return TELEPHONY_ERR_LOCAL_PTR_NULL;
353     }
354     if (result->GoToFirstRow() != DataShare::E_OK) {
355         TELEPHONY_LOGE("CallDataBaseHelper: query error, go to first row error");
356         result->Close();
357         callDataHelper->Release();
358         return TELEPHONY_ERR_DATABASE_READ_FAIL;
359     }
360     int32_t columnindex = 0;
361     std::string value = "";
362     result->GetColumnIndex(SETTING_VALUE, columnindex);
363     result->GetString(columnindex, value);
364     result->Close();
365     callDataHelper->Release();
366     isAirplaneModeOn = value == "1";
367     TELEPHONY_LOGI("Get airplane mode:%{public}d", isAirplaneModeOn);
368     return TELEPHONY_SUCCESS;
369 }
370 } // namespace Telephony
371 } // namespace OHOS
372