• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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