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