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_number_utils.h"
17
18 #include <regex>
19
20 #include "asyoutypeformatter.h"
21 #include "call_ability_report_proxy.h"
22 #include "call_manager_errors.h"
23 #include "call_voice_assistant_manager.h"
24 #include "cellular_call_connection.h"
25 #include "cellular_data_client.h"
26 #include "core_service_client.h"
27 #include "number_identity_data_base_helper.h"
28 #include "parameters.h"
29 #include "phonenumbers/phonenumber.pb.h"
30 #include "telephony_log_wrapper.h"
31 #include "telephony_types.h"
32
33 namespace OHOS {
34 namespace Telephony {
CallNumberUtils()35 CallNumberUtils::CallNumberUtils() {}
36
~CallNumberUtils()37 CallNumberUtils::~CallNumberUtils() {}
38
FormatPhoneNumber(const std::string & phoneNumber,const std::string & countryCode,std::string & formatNumber)39 int32_t CallNumberUtils::FormatPhoneNumber(
40 const std::string &phoneNumber, const std::string &countryCode, std::string &formatNumber)
41 {
42 if (phoneNumber.empty()) {
43 TELEPHONY_LOGE("phoneNumber is nullptr!");
44 return TELEPHONY_ERR_ARGUMENT_INVALID;
45 }
46 if (phoneNumber.front() == '#' || phoneNumber.front() == '*') {
47 formatNumber = phoneNumber;
48 return TELEPHONY_SUCCESS;
49 }
50 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
51 if (phoneUtils == nullptr) {
52 TELEPHONY_LOGE("phoneUtils is nullptr");
53 return TELEPHONY_ERR_LOCAL_PTR_NULL;
54 }
55 std::string tmpCode = countryCode;
56 transform(tmpCode.begin(), tmpCode.end(), tmpCode.begin(), ::toupper);
57 i18n::phonenumbers::PhoneNumber parseResult;
58 phoneUtils->ParseAndKeepRawInput(phoneNumber, tmpCode, &parseResult);
59 phoneUtils->FormatInOriginalFormat(parseResult, tmpCode, &formatNumber);
60 if (formatNumber.empty() || formatNumber == "0") {
61 formatNumber = "";
62 }
63 return TELEPHONY_SUCCESS;
64 }
65
FormatPhoneNumberToE164(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)66 int32_t CallNumberUtils::FormatPhoneNumberToE164(
67 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
68 {
69 return FormatNumberBase(phoneNumber, countryCode, i18n::phonenumbers::PhoneNumberUtil::E164, formatNumber);
70 }
71
FormatPhoneNumberToNational(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)72 int32_t CallNumberUtils::FormatPhoneNumberToNational(
73 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
74 {
75 int32_t ret = FormatNumberBase(phoneNumber, countryCode,
76 i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::NATIONAL, formatNumber);
77 ProcessSpace(formatNumber);
78 return ret;
79 }
80
FormatPhoneNumberToInternational(const std::string phoneNumber,const std::string countryCode,std::string & formatNumber)81 int32_t CallNumberUtils::FormatPhoneNumberToInternational(
82 const std::string phoneNumber, const std::string countryCode, std::string &formatNumber)
83 {
84 int32_t ret = FormatNumberBase(phoneNumber, countryCode,
85 i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL, formatNumber);
86 ProcessSpace(formatNumber);
87 return ret;
88 }
89
FormatNumberBase(const std::string phoneNumber,std::string countryCode,const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo,std::string & formatNumber)90 int32_t CallNumberUtils::FormatNumberBase(const std::string phoneNumber, std::string countryCode,
91 const i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat formatInfo, std::string &formatNumber)
92 {
93 if (phoneNumber.empty()) {
94 TELEPHONY_LOGE("phoneNumber is nullptr!");
95 return TELEPHONY_ERR_ARGUMENT_INVALID;
96 }
97 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
98 if (phoneUtils == nullptr) {
99 TELEPHONY_LOGE("phoneUtils is nullptr");
100 return TELEPHONY_ERR_LOCAL_PTR_NULL;
101 }
102 transform(countryCode.begin(), countryCode.end(), countryCode.begin(), ::toupper);
103 i18n::phonenumbers::PhoneNumber parseResult;
104 phoneUtils->Parse(phoneNumber, countryCode, &parseResult);
105 if (phoneUtils->IsValidNumber(parseResult) || HasBCPhoneNumber(phoneNumber)) {
106 phoneUtils->Format(parseResult, formatInfo, &formatNumber);
107 }
108 return TELEPHONY_SUCCESS;
109 }
110
FormatPhoneNumberAsYouType(const std::string & phoneNumber,const std::string & countryCode,std::string & formatNumber)111 int32_t CallNumberUtils::FormatPhoneNumberAsYouType(
112 const std::string &phoneNumber, const std::string &countryCode, std::string &formatNumber)
113 {
114 if (phoneNumber.empty()) {
115 TELEPHONY_LOGE("phoneNumber is nullptr!");
116 return TELEPHONY_ERR_ARGUMENT_INVALID;
117 }
118 if (phoneNumber.front() == '#' || phoneNumber.front() == '*') {
119 formatNumber = phoneNumber;
120 return TELEPHONY_SUCCESS;
121 }
122 i18n::phonenumbers::PhoneNumberUtil *phoneUtils = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
123 if (phoneUtils == nullptr) {
124 TELEPHONY_LOGE("phoneUtils is nullptr");
125 return TELEPHONY_ERR_LOCAL_PTR_NULL;
126 }
127 std::string tmpCode = countryCode;
128 transform(tmpCode.begin(), tmpCode.end(), tmpCode.begin(), ::toupper);
129 std::unique_ptr<i18n::phonenumbers::AsYouTypeFormatter> formatter(phoneUtils->GetAsYouTypeFormatter(tmpCode));
130 if (formatter == nullptr) {
131 TELEPHONY_LOGE("formatter is nullptr");
132 return TELEPHONY_ERR_LOCAL_PTR_NULL;
133 }
134 formatter->Clear();
135 std::string result;
136 for (size_t i = 0; i < phoneNumber.length(); i++) {
137 char c = phoneNumber.at(i);
138 formatNumber = formatter->InputDigit(c, &result);
139 }
140 if (formatNumber.empty() || formatNumber == "0") {
141 formatNumber = "";
142 }
143 return TELEPHONY_SUCCESS;
144 }
145
ProcessSpace(std::string & number)146 void CallNumberUtils::ProcessSpace(std::string &number)
147 {
148 std::string word;
149 std::stringstream streamNum(number);
150 std::string store;
151 while (streamNum >> word) {
152 store += word;
153 }
154 number = store;
155 }
156
CheckNumberIsEmergency(const std::string & phoneNumber,const int32_t slotId,bool & enabled)157 int32_t CallNumberUtils::CheckNumberIsEmergency(const std::string &phoneNumber, const int32_t slotId, bool &enabled)
158 {
159 return DelayedSingleton<CellularCallConnection>::GetInstance()->IsEmergencyPhoneNumber(
160 phoneNumber, slotId, enabled);
161 }
162
IsCarrierVtConfig(const int32_t slotId,bool & enabled)163 int32_t CallNumberUtils::IsCarrierVtConfig(const int32_t slotId, bool &enabled)
164 {
165 return DelayedSingleton<CellularCallConnection>::GetInstance()->GetCarrierVtConfig(
166 slotId, enabled);
167 }
168
IsValidSlotId(int32_t slotId) const169 bool CallNumberUtils::IsValidSlotId(int32_t slotId) const
170 {
171 if (SIM_SLOT_COUNT == HAS_A_SLOT) {
172 return slotId == SIM_SLOT_0;
173 }
174 if (SIM_SLOT_COUNT == HAS_TWO_SLOT) {
175 if (slotId == SIM_SLOT_0 || slotId == SIM_SLOT_1) {
176 return true;
177 }
178 }
179 return false;
180 }
181
RemoveSeparatorsPhoneNumber(const std::string & phoneString)182 std::string CallNumberUtils::RemoveSeparatorsPhoneNumber(const std::string &phoneString)
183 {
184 std::string newString;
185 if (phoneString.empty()) {
186 TELEPHONY_LOGE("RemoveSeparatorsPhoneNumber return, phoneStr is empty.");
187 return newString;
188 }
189 for (char c : phoneString) {
190 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N' || c == ',' || c == ';') {
191 newString += c;
192 }
193 }
194
195 return newString;
196 }
197
RemovePostDialPhoneNumber(const std::string & phoneString)198 std::string CallNumberUtils::RemovePostDialPhoneNumber(const std::string &phoneString)
199 {
200 std::string newString = "";
201 if (phoneString.empty()) {
202 TELEPHONY_LOGE("RemovePostDialPhoneNumber return, phoneStr is empty.");
203 return newString;
204 }
205 for (char c : phoneString) {
206 if ((c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == 'N') {
207 newString += c;
208 } else if (c == ',' || c == ';') {
209 break;
210 }
211 }
212
213 return newString;
214 }
215
HasAlphabetInPhoneNum(const std::string & inputValue)216 bool CallNumberUtils::HasAlphabetInPhoneNum(const std::string &inputValue)
217 {
218 if (inputValue.empty()) {
219 TELEPHONY_LOGE("HasAlphabetInPhoneNum return, input is empty.");
220 return true;
221 }
222 for (char c : inputValue) {
223 if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) {
224 TELEPHONY_LOGE("The Phone Number contains letter");
225 return true;
226 }
227 }
228 TELEPHONY_LOGI("The Phone Number is valid");
229 return false;
230 }
231
HasBCPhoneNumber(const std::string & phoneNumber)232 bool CallNumberUtils::HasBCPhoneNumber(const std::string &phoneNumber)
233 {
234 int32_t phoneNumberStart = 0;
235 int32_t phoneNumberStartLength = 3;
236 size_t bCNumberLength = 11;
237 std::string bCNumberStart = "192";
238 if (phoneNumber.length() == bCNumberLength &&
239 phoneNumber.substr(phoneNumberStart, phoneNumberStartLength) == bCNumberStart) {
240 return true;
241 }
242 return false;
243 }
244
SelectAccountId(int32_t slotId,AppExecFwk::PacMap & extras)245 bool CallNumberUtils::SelectAccountId(int32_t slotId, AppExecFwk::PacMap &extras)
246 {
247 if (IsValidSlotId(slotId)) {
248 return true;
249 }
250 int32_t defaultVoiceSlotId = DelayedRefSingleton<CoreServiceClient>::GetInstance().GetDefaultVoiceSlotId();
251 if (defaultVoiceSlotId != TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL && IsValidSlotId(defaultVoiceSlotId)) {
252 extras.PutIntValue("accountId", defaultVoiceSlotId);
253 TELEPHONY_LOGI("select accountId to defaultVoiceSlotId = %{public}d", defaultVoiceSlotId);
254 return true;
255 }
256 #ifdef CELLULAR_DATA_SUPPORT
257 int32_t defaultDataSlotId = DelayedRefSingleton<CellularDataClient>::GetInstance().GetDefaultCellularDataSlotId();
258 if (defaultDataSlotId != TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL && IsValidSlotId(defaultDataSlotId)) {
259 extras.PutIntValue("accountId", defaultDataSlotId);
260 TELEPHONY_LOGI("select accountId to defaultDataSlotId = %{public}d", defaultDataSlotId);
261 return true;
262 }
263 #endif
264 return false;
265 }
266
QueryNumberLocationInfo(std::string & numberLocation,std::string accountNumber)267 int32_t CallNumberUtils::QueryNumberLocationInfo(std::string &numberLocation, std::string accountNumber)
268 {
269 TELEPHONY_LOGW("QueryNumberLocationInfo");
270 if (accountNumber == "") {
271 TELEPHONY_LOGE("accountNumber is null");
272 return TELEPHONY_ERR_ARGUMENT_INVALID;
273 }
274 std::shared_ptr<NumberIdentityDataBaseHelper> callDataPtr =
275 DelayedSingleton<NumberIdentityDataBaseHelper>::GetInstance();
276 if (callDataPtr == nullptr) {
277 TELEPHONY_LOGE("callDataPtr is nullptr!");
278 return TELEPHONY_ERR_LOCAL_PTR_NULL;
279 }
280
281 DataShare::DataSharePredicates predicates;
282 std::vector<std::string> phoneNumber;
283 phoneNumber.push_back(accountNumber);
284 predicates.SetWhereArgs(phoneNumber);
285 bool ret = callDataPtr->Query(numberLocation, predicates);
286 if (!ret) {
287 TELEPHONY_LOGE("Query number location database fail!");
288 return TELEPHONY_ERR_DATABASE_READ_FAIL;
289 }
290 return TELEPHONY_SUCCESS;
291 }
292
NumberLocationUpdate(const sptr<CallBase> & callObjectPtr)293 void CallNumberUtils::NumberLocationUpdate(const sptr<CallBase> &callObjectPtr)
294 {
295 CallAttributeInfo info;
296 callObjectPtr->GetCallAttributeBaseInfo(info);
297 TELEPHONY_LOGW("NumberLocationUpdate, callId[%{public}d]", info.callId);
298 std::string numberLocation = callObjectPtr->GetNumberLocation();
299 int32_t ret = QueryNumberLocationInfo(numberLocation, callObjectPtr->GetAccountNumber());
300 if (ret != TELEPHONY_SUCCESS) {
301 return;
302 }
303 sptr<CallBase> call = callObjectPtr;
304 if (info.callState == TelCallState::CALL_STATUS_DIALING) {
305 call = CallObjectManager::GetOneCallObject(info.callId);
306 if (call == nullptr) {
307 TELEPHONY_LOGE("call is nullptr");
308 call = callObjectPtr;
309 }
310 }
311 call->SetNumberLocation(numberLocation);
312 CallVoiceAssistantManager::GetInstance()->UpdateNumberLocation(numberLocation, info.callId);
313 if (!CallObjectManager::IsCallExist(info.callId)) {
314 TELEPHONY_LOGE("call is not exist");
315 return;
316 }
317 if (numberLocation != "" && numberLocation != "default") {
318 TELEPHONY_LOGW("need report call info of numberLocation");
319 call->GetCallAttributeInfo(info);
320 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportCallStateInfo(info);
321 }
322 }
323
YellowPageAndMarkUpdate(const sptr<CallBase> & callObjectPtr)324 void CallNumberUtils::YellowPageAndMarkUpdate(const sptr<CallBase> &callObjectPtr)
325 {
326 if (OHOS::system::GetParameter("const.global.region", "CN") != "CN") {
327 TELEPHONY_LOGI("not the chinese version, no need to query markinfo.");
328 return;
329 }
330 CallAttributeInfo info;
331 callObjectPtr->GetCallAttributeInfo(info);
332 TELEPHONY_LOGI("YellowPageAndMarkUpdate, callId[%{public}d]", info.callId);
333 NumberMarkInfo numberMarkInfo;
334 int32_t ret = QueryYellowPageAndMarkInfo(numberMarkInfo, callObjectPtr->GetAccountNumber());
335 if (ret != TELEPHONY_SUCCESS) {
336 TELEPHONY_LOGE("QueryYellowPageAndMarkInfo fail!");
337 return;
338 }
339 sptr<CallBase> call = callObjectPtr;
340 if (info.callState == TelCallState::CALL_STATUS_DIALING) {
341 call = CallObjectManager::GetOneCallObject(info.callId);
342 if (call == nullptr) {
343 TELEPHONY_LOGE("call is nullptr");
344 return;
345 }
346 }
347 call->SetNumberMarkInfo(numberMarkInfo);
348 if (!CallObjectManager::IsCallExist(info.callId)) {
349 TELEPHONY_LOGE("call is not exist");
350 return;
351 }
352 TELEPHONY_LOGI("markType: %{public}d, isEcc: %{public}d",
353 static_cast<int32_t>(numberMarkInfo.markType), info.isEcc);
354 if (numberMarkInfo.markType > MarkType::MARK_TYPE_NONE || info.isEcc) {
355 call->GetCallAttributeInfo(info);
356 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportCallStateInfo(info);
357 }
358 }
359
QueryYellowPageAndMarkInfo(NumberMarkInfo & numberMarkInfo,std::string accountNumber)360 int32_t CallNumberUtils::QueryYellowPageAndMarkInfo(NumberMarkInfo &numberMarkInfo, std::string accountNumber)
361 {
362 TELEPHONY_LOGW("QueryYellowPageAndMarkInfo");
363 if (accountNumber == "") {
364 TELEPHONY_LOGE("accountNumber is null");
365 return TELEPHONY_ERR_ARGUMENT_INVALID;
366 }
367 std::shared_ptr<NumberIdentityDataBaseHelper> callDataPtr =
368 DelayedSingleton<NumberIdentityDataBaseHelper>::GetInstance();
369 if (callDataPtr == nullptr) {
370 TELEPHONY_LOGE("callDataPtr is nullptr!");
371 return TELEPHONY_ERR_LOCAL_PTR_NULL;
372 }
373
374 DataShare::DataSharePredicates predicates;
375 std::vector<std::string> phoneNumber;
376 phoneNumber.push_back(accountNumber);
377 predicates.SetWhereArgs(phoneNumber);
378 bool ret = callDataPtr->QueryYellowPageAndMark(numberMarkInfo, predicates);
379 if (!ret) {
380 TELEPHONY_LOGE("Query yellow page and mark fail!");
381 return TELEPHONY_ERR_DATABASE_READ_FAIL;
382 }
383 return TELEPHONY_SUCCESS;
384 }
385 } // namespace Telephony
386 } // namespace OHOS
387