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