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