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