• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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_status_manager.h"
17 
18 #include <securec.h>
19 
20 #include "audio_control_manager.h"
21 #include "bluetooth_call_service.h"
22 #include "call_control_manager.h"
23 #include "call_manager_errors.h"
24 #include "call_manager_hisysevent.h"
25 #include "cs_call.h"
26 #include "datashare_predicates.h"
27 #include "hitrace_meter.h"
28 #include "ims_call.h"
29 #include "ott_call.h"
30 #include "report_call_info_handler.h"
31 #include "telephony_log_wrapper.h"
32 
33 namespace OHOS {
34 namespace Telephony {
CallStatusManager()35 CallStatusManager::CallStatusManager()
36 {
37     (void)memset_s(&callReportInfo_, sizeof(CallDetailInfo), 0, sizeof(CallDetailInfo));
38     (void)memset_s(&callDetailsInfo_, sizeof(CallDetailsInfo), 0, sizeof(CallDetailsInfo));
39 }
40 
~CallStatusManager()41 CallStatusManager::~CallStatusManager()
42 {
43     UnInit();
44 }
45 
Init()46 int32_t CallStatusManager::Init()
47 {
48     callDetailsInfo_.callVec.clear();
49     mEventIdTransferMap_.clear();
50     mOttEventIdTransferMap_.clear();
51     InitCallBaseEvent();
52     CallIncomingFilterManagerPtr_ = (std::make_unique<CallIncomingFilterManager>()).release();
53     return TELEPHONY_SUCCESS;
54 }
55 
InitCallBaseEvent()56 void CallStatusManager::InitCallBaseEvent()
57 {
58     mEventIdTransferMap_[RequestResultEventId::RESULT_DIAL_NO_CARRIER] = CallAbilityEventId::EVENT_DIAL_NO_CARRIER;
59     mOttEventIdTransferMap_[OttCallEventId::OTT_CALL_EVENT_FUNCTION_UNSUPPORTED] =
60         CallAbilityEventId::EVENT_OTT_FUNCTION_UNSUPPORTED;
61 }
62 
UnInit()63 int32_t CallStatusManager::UnInit()
64 {
65     callDetailsInfo_.callVec.clear();
66     mEventIdTransferMap_.clear();
67     mOttEventIdTransferMap_.clear();
68     return TELEPHONY_SUCCESS;
69 }
70 
HandleCallReportInfo(const CallDetailInfo & info)71 int32_t CallStatusManager::HandleCallReportInfo(const CallDetailInfo &info)
72 {
73     int32_t ret = TELEPHONY_ERR_FAIL;
74     callReportInfo_ = info;
75     switch (info.state) {
76         case TelCallState::CALL_STATUS_ACTIVE:
77             ret = ActiveHandle(info);
78             break;
79         case TelCallState::CALL_STATUS_HOLDING:
80             ret = HoldingHandle(info);
81             break;
82         case TelCallState::CALL_STATUS_DIALING: {
83             ret = DialingHandle(info);
84             FinishAsyncTrace(HITRACE_TAG_OHOS, "DialCall", getpid());
85             DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingDialTimeOut(
86                 info.accountId, static_cast<int32_t>(info.callType), static_cast<int32_t>(info.callMode));
87             break;
88         }
89         case TelCallState::CALL_STATUS_ALERTING:
90             ret = AlertHandle(info);
91             break;
92         case TelCallState::CALL_STATUS_INCOMING: {
93             ret = IncomingHandle(info);
94             FinishAsyncTrace(HITRACE_TAG_OHOS, "InComingCall", getpid());
95             DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingIncomingTimeOut(
96                 info.accountId, static_cast<int32_t>(info.callType), static_cast<int32_t>(info.callMode));
97             break;
98         }
99         case TelCallState::CALL_STATUS_WAITING:
100             ret = WaitingHandle(info);
101             break;
102         case TelCallState::CALL_STATUS_DISCONNECTED:
103             ret = DisconnectedHandle(info);
104             break;
105         case TelCallState::CALL_STATUS_DISCONNECTING:
106             ret = DisconnectingHandle(info);
107             break;
108         default:
109             TELEPHONY_LOGE("Invalid call state!");
110             break;
111     }
112     TELEPHONY_LOGI("Entry CallStatusManager HandleCallReportInfo");
113     DelayedSingleton<BluetoothCallService>::GetInstance()->GetCallState();
114     return ret;
115 }
116 
117 // handle call state changes, incoming call, outgoing call.
HandleCallsReportInfo(const CallDetailsInfo & info)118 int32_t CallStatusManager::HandleCallsReportInfo(const CallDetailsInfo &info)
119 {
120     bool flag = false;
121     TELEPHONY_LOGI("call list size:%{public}zu,slotId:%{public}d", info.callVec.size(), info.slotId);
122     for (auto &it : info.callVec) {
123         for (const auto &it1 : callDetailsInfo_.callVec) {
124             if (strcmp(it.phoneNum, it1.phoneNum) == 0) {
125                 // call state changes
126                 if (it.state != it1.state) {
127                     TELEPHONY_LOGI("handle updated call state:%{public}d", it.state);
128                     HandleCallReportInfo(it);
129                 }
130                 flag = true;
131                 break;
132             }
133         }
134         // incoming/outgoing call handle
135         if (!flag || callDetailsInfo_.callVec.empty()) {
136             TELEPHONY_LOGI("handle new call state:%{public}d", it.state);
137             HandleCallReportInfo(it);
138         }
139         flag = false;
140     }
141     // disconnected calls handle
142     for (auto &it2 : callDetailsInfo_.callVec) {
143         for (const auto &it3 : info.callVec) {
144             if (strcmp(it2.phoneNum, it3.phoneNum) == 0) {
145                 TELEPHONY_LOGI("state:%{public}d", it2.state);
146                 flag = true;
147                 break;
148             }
149         }
150         if (!flag) {
151             it2.state = TelCallState::CALL_STATUS_DISCONNECTED;
152             HandleCallReportInfo(it2);
153         }
154         flag = false;
155     }
156     callDetailsInfo_.callVec.clear();
157     callDetailsInfo_ = info;
158     return TELEPHONY_SUCCESS;
159 }
160 
HandleDisconnectedCause(const DisconnectedDetails & details)161 int32_t CallStatusManager::HandleDisconnectedCause(const DisconnectedDetails &details)
162 {
163     bool ret = DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallDestroyed(details);
164     if (!ret) {
165         TELEPHONY_LOGI("NotifyCallDestroyed failed!");
166         return CALL_ERR_PHONE_CALLSTATE_NOTIFY_FAILED;
167     }
168     return TELEPHONY_SUCCESS;
169 }
170 
HandleEventResultReportInfo(const CellularCallEventInfo & info)171 int32_t CallStatusManager::HandleEventResultReportInfo(const CellularCallEventInfo &info)
172 {
173     if (info.eventType != CellularCallEventType::EVENT_REQUEST_RESULT_TYPE) {
174         TELEPHONY_LOGE("unexpected type event occurs, eventId:%{public}d", info.eventId);
175         return CALL_ERR_PHONE_TYPE_UNEXPECTED;
176     }
177     TELEPHONY_LOGI("recv one Event, eventId:%{public}d", info.eventId);
178     CallEventInfo eventInfo;
179     (void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
180     if (mEventIdTransferMap_.find(info.eventId) != mEventIdTransferMap_.end()) {
181         eventInfo.eventId = mEventIdTransferMap_[info.eventId];
182         DialParaInfo dialInfo;
183         if (eventInfo.eventId == CallAbilityEventId::EVENT_DIAL_NO_CARRIER) {
184             DelayedSingleton<CallControlManager>::GetInstance()->GetDialParaInfo(dialInfo);
185             if (dialInfo.number.length() > static_cast<size_t>(kMaxNumberLen)) {
186                 TELEPHONY_LOGE("Number out of limit!");
187                 return CALL_ERR_NUMBER_OUT_OF_RANGE;
188             }
189             if (memcpy_s(eventInfo.phoneNum, kMaxNumberLen, dialInfo.number.c_str(), dialInfo.number.length()) != EOK) {
190                 TELEPHONY_LOGE("memcpy_s failed!");
191                 return TELEPHONY_ERR_MEMCPY_FAIL;
192             }
193         }
194         DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
195     } else {
196         TELEPHONY_LOGW("unknown type Event, eventid %{public}d", info.eventId);
197     }
198     return TELEPHONY_SUCCESS;
199 }
200 
HandleOttEventReportInfo(const OttCallEventInfo & info)201 int32_t CallStatusManager::HandleOttEventReportInfo(const OttCallEventInfo &info)
202 {
203     TELEPHONY_LOGI("recv one Event, eventId:%{public}d", info.ottCallEventId);
204     CallEventInfo eventInfo;
205     (void)memset_s(&eventInfo, sizeof(CallEventInfo), 0, sizeof(CallEventInfo));
206     if (mOttEventIdTransferMap_.find(info.ottCallEventId) != mOttEventIdTransferMap_.end()) {
207         eventInfo.eventId = mOttEventIdTransferMap_[info.ottCallEventId];
208         if (strlen(info.bundleName) > static_cast<size_t>(kMaxNumberLen)) {
209             TELEPHONY_LOGE("Number out of limit!");
210             return CALL_ERR_NUMBER_OUT_OF_RANGE;
211         }
212         if (memcpy_s(eventInfo.bundleName, kMaxNumberLen, info.bundleName, strlen(info.bundleName)) != EOK) {
213             TELEPHONY_LOGE("memcpy_s failed!");
214             return TELEPHONY_ERR_MEMCPY_FAIL;
215         }
216         DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
217     } else {
218         TELEPHONY_LOGW("unknown type Event, eventid %{public}d", info.ottCallEventId);
219     }
220     return TELEPHONY_SUCCESS;
221 }
222 
IncomingHandle(const CallDetailInfo & info)223 int32_t CallStatusManager::IncomingHandle(const CallDetailInfo &info)
224 {
225     int32_t ret = IncomingHandlePolicy(info);
226     if (ret != TELEPHONY_SUCCESS) {
227         TELEPHONY_LOGE("IncomingHandlePolicy failed!");
228         if (info.state == TelCallState::CALL_STATUS_INCOMING) {
229             CallManagerHisysevent::WriteIncomingCallFaultEvent(info.accountId, static_cast<int32_t>(info.callType),
230                 static_cast<int32_t>(info.callMode), ret, "IncomingHandlePolicy failed");
231         }
232         return ret;
233     }
234     if (info.callType == CallType::TYPE_CS || info.callType == CallType::TYPE_IMS) {
235         ret = IncomingFilterPolicy(info);
236         if (ret != TELEPHONY_SUCCESS) {
237             TELEPHONY_LOGE("IncomingFilterPolicy failed!");
238             return ret;
239         }
240     }
241     sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_IN);
242     if (call == nullptr) {
243         TELEPHONY_LOGE("CreateNewCall failed!");
244         return CALL_ERR_CALL_OBJECT_IS_NULL;
245     }
246 
247     // allow list filtering
248     // Get the contact data from the database
249     ContactInfo contactInfo = {
250         .name = "",
251         .number = "",
252         .isContacterExists = false,
253         .ringtonePath = "",
254         .isSendToVoicemail = false,
255         .isEcc = false,
256         .isVoiceMail = false,
257     };
258     QueryCallerInfo(contactInfo, std::string(info.phoneNum));
259     call->SetCallerInfo(contactInfo);
260 
261     DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
262     ret = UpdateCallState(call, info.state);
263     if (ret != TELEPHONY_SUCCESS) {
264         TELEPHONY_LOGE("UpdateCallState failed!");
265         return ret;
266     }
267     ret = FilterResultsDispose(call);
268     if (ret != TELEPHONY_SUCCESS) {
269         TELEPHONY_LOGE("FilterResultsDispose failed!");
270     }
271     return ret;
272 }
273 
QueryCallerInfo(ContactInfo & contactInfo,std::string phoneNum)274 void CallStatusManager::QueryCallerInfo(ContactInfo &contactInfo, std::string phoneNum)
275 {
276     TELEPHONY_LOGI("Entry CallStatusManager QueryCallerInfo");
277     std::shared_ptr<CallDataBaseHelper> callDataPtr = DelayedSingleton<CallDataBaseHelper>::GetInstance();
278     if (callDataPtr == nullptr) {
279         TELEPHONY_LOGE("callDataPtr is nullptr!");
280         return;
281     }
282     DataShare::DataSharePredicates predicates;
283     predicates.EqualTo(DETAIL_INFO, phoneNum);
284     predicates.And();
285     predicates.EqualTo(CONTENT_TYPE, PHONE);
286     bool ret = callDataPtr->Query(contactInfo, predicates);
287     if (!ret) {
288         TELEPHONY_LOGE("Query contact database fail!");
289     }
290 }
291 
IncomingFilterPolicy(const CallDetailInfo & info)292 int32_t CallStatusManager::IncomingFilterPolicy(const CallDetailInfo &info)
293 {
294     if (CallIncomingFilterManagerPtr_ == nullptr) {
295         TELEPHONY_LOGE("CallIncomingFilterManagerPtr_ is null");
296         return TELEPHONY_ERR_LOCAL_PTR_NULL;
297     }
298     if (CallIncomingFilterManagerPtr_->IsFirstIncoming()) {
299         CallIncomingFilterManagerPtr_->UpdateIncomingFilterData();
300     }
301     return CallIncomingFilterManagerPtr_->doIncomingFilter(info);
302 }
303 
CallFilterCompleteResult(const CallDetailInfo & info)304 void CallStatusManager::CallFilterCompleteResult(const CallDetailInfo &info)
305 {
306     int32_t ret = TELEPHONY_ERR_FAIL;
307     sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_IN);
308     if (call == nullptr) {
309         TELEPHONY_LOGE("CreateNewCall failed!");
310         return;
311     }
312 #ifdef ABILITY_DATABASE_SUPPORT
313     // allow list filtering
314     // Get the contact data from the database
315     GetCallerInfoDate(ContactInfo);
316     SetCallerInfo(contactInfo);
317 #endif
318     DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
319     ret = UpdateCallState(call, info.state);
320     if (ret != TELEPHONY_SUCCESS) {
321         TELEPHONY_LOGE("UpdateCallState failed!");
322         return;
323     }
324     ret = FilterResultsDispose(call);
325     if (ret != TELEPHONY_SUCCESS) {
326         TELEPHONY_LOGE("FilterResultsDispose failed!");
327         return;
328     }
329 }
330 
DialingHandle(const CallDetailInfo & info)331 int32_t CallStatusManager::DialingHandle(const CallDetailInfo &info)
332 {
333     TELEPHONY_LOGI("handle dialing state");
334     int32_t ret = DialingHandlePolicy(info);
335     if (ret != TELEPHONY_SUCCESS) {
336         TELEPHONY_LOGE("DialingHandlePolicy failed!");
337         return ret;
338     }
339     sptr<CallBase> call = CreateNewCall(info, CallDirection::CALL_DIRECTION_OUT);
340     if (call == nullptr) {
341         TELEPHONY_LOGE("CreateNewCall failed!");
342         return TELEPHONY_ERR_LOCAL_PTR_NULL;
343     }
344     ret = call->DialingProcess();
345     if (ret != TELEPHONY_SUCCESS) {
346         return ret;
347     }
348     DelayedSingleton<CallControlManager>::GetInstance()->NotifyNewCallCreated(call);
349     ret = UpdateCallState(call, TelCallState::CALL_STATUS_DIALING);
350     if (ret != TELEPHONY_SUCCESS) {
351         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
352     }
353     return ret;
354 }
355 
ActiveHandle(const CallDetailInfo & info)356 int32_t CallStatusManager::ActiveHandle(const CallDetailInfo &info)
357 {
358     TELEPHONY_LOGI("handle active state");
359     std::string tmpStr(info.phoneNum);
360     sptr<CallBase> call = GetOneCallObject(tmpStr);
361     if (call == nullptr) {
362         TELEPHONY_LOGE("Call is NULL");
363         return TELEPHONY_ERR_LOCAL_PTR_NULL;
364     }
365     call = RefreshCallIfNecessary(call, info);
366     // call state change active, need to judge if launching a conference
367     int32_t ret = call->LaunchConference();
368     if (ret == TELEPHONY_SUCCESS) {
369         int32_t mainCallId = ERR_ID;
370         call->GetMainCallId(mainCallId);
371         sptr<CallBase> mainCall = GetOneCallObject(mainCallId);
372         if (mainCall != nullptr) {
373             mainCall->SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_ACTIVE);
374         }
375     }
376     ret = UpdateCallState(call, TelCallState::CALL_STATUS_ACTIVE);
377     if (ret != TELEPHONY_SUCCESS) {
378         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
379         return ret;
380     }
381 #ifdef AUDIO_SUPPORT
382     ToSpeakerPhone(call);
383     DelayedSingleton<AudioControlManager>::GetInstance()->SetVolumeAudible();
384 #endif
385     TELEPHONY_LOGI("handle active state success");
386     return ret;
387 }
388 
HoldingHandle(const CallDetailInfo & info)389 int32_t CallStatusManager::HoldingHandle(const CallDetailInfo &info)
390 {
391     TELEPHONY_LOGI("handle holding state");
392     std::string tmpStr(info.phoneNum);
393     sptr<CallBase> call = GetOneCallObject(tmpStr);
394     if (call == nullptr) {
395         TELEPHONY_LOGE("Call is NULL");
396         return TELEPHONY_ERR_LOCAL_PTR_NULL;
397     }
398     // if the call is in a conference, it will exit, otherwise just set it holding
399     call = RefreshCallIfNecessary(call, info);
400     int32_t ret = call->HoldConference();
401     if (ret == TELEPHONY_SUCCESS) {
402         TELEPHONY_LOGI("HoldConference success");
403     }
404     ret = UpdateCallState(call, TelCallState::CALL_STATUS_HOLDING);
405     if (ret != TELEPHONY_SUCCESS) {
406         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
407     }
408     return ret;
409 }
410 
WaitingHandle(const CallDetailInfo & info)411 int32_t CallStatusManager::WaitingHandle(const CallDetailInfo &info)
412 {
413     return IncomingHandle(info);
414 }
415 
AlertHandle(const CallDetailInfo & info)416 int32_t CallStatusManager::AlertHandle(const CallDetailInfo &info)
417 {
418     TELEPHONY_LOGI("handle alerting state");
419     std::string tmpStr(info.phoneNum);
420     sptr<CallBase> call = GetOneCallObject(tmpStr);
421     if (call == nullptr) {
422         TELEPHONY_LOGE("Call is NULL");
423         return TELEPHONY_ERR_LOCAL_PTR_NULL;
424     }
425     call = RefreshCallIfNecessary(call, info);
426     int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_ALERTING);
427     if (ret != TELEPHONY_SUCCESS) {
428         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
429         return ret;
430     }
431 #ifdef AUDIO_SUPPORT
432     ToSpeakerPhone(call);
433     TurnOffMute(call);
434     DelayedSingleton<AudioControlManager>::GetInstance()->SetVolumeAudible();
435 #endif
436     return ret;
437 }
438 
DisconnectingHandle(const CallDetailInfo & info)439 int32_t CallStatusManager::DisconnectingHandle(const CallDetailInfo &info)
440 {
441     TELEPHONY_LOGI("handle disconnecting state");
442     std::string tmpStr(info.phoneNum);
443     sptr<CallBase> call = GetOneCallObject(tmpStr);
444     if (call == nullptr) {
445         TELEPHONY_LOGE("Call is NULL");
446         return TELEPHONY_ERR_LOCAL_PTR_NULL;
447     }
448     call = RefreshCallIfNecessary(call, info);
449     int32_t ret = UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTING);
450     if (ret != TELEPHONY_SUCCESS) {
451         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
452     }
453     return ret;
454 }
455 
DisconnectedHandle(const CallDetailInfo & info)456 int32_t CallStatusManager::DisconnectedHandle(const CallDetailInfo &info)
457 {
458     TELEPHONY_LOGI("handle disconnected state");
459     std::string tmpStr(info.phoneNum);
460     sptr<CallBase> call = GetOneCallObject(tmpStr);
461     if (call == nullptr) {
462         TELEPHONY_LOGE("Call is NULL");
463         return TELEPHONY_ERR_LOCAL_PTR_NULL;
464     }
465     call = RefreshCallIfNecessary(call, info);
466     int32_t ret = call->ExitConference();
467     if (ret == TELEPHONY_SUCCESS) {
468         TELEPHONY_LOGI("SubCallSeparateFromConference success");
469     }
470     ret = UpdateCallState(call, TelCallState::CALL_STATUS_DISCONNECTED);
471     if (ret != TELEPHONY_SUCCESS) {
472         TELEPHONY_LOGE("UpdateCallState failed, errCode:%{public}d", ret);
473         return ret;
474     }
475     DeleteOneCallObject(call->GetCallID());
476     return ret;
477 }
478 
UpdateCallState(sptr<CallBase> & call,TelCallState nextState)479 int32_t CallStatusManager::UpdateCallState(sptr<CallBase> &call, TelCallState nextState)
480 {
481     TELEPHONY_LOGI("UpdateCallState start");
482     if (call == nullptr) {
483         TELEPHONY_LOGE("Call is NULL");
484         return TELEPHONY_ERR_LOCAL_PTR_NULL;
485     }
486     TelCallState priorState = call->GetTelCallState();
487     TELEPHONY_LOGI("priorState:%{public}d, nextState:%{public}d", priorState, nextState);
488     if (priorState == TelCallState::CALL_STATUS_INCOMING && nextState == TelCallState::CALL_STATUS_ACTIVE) {
489         DelayedSingleton<CallManagerHisysevent>::GetInstance()->JudgingAnswerTimeOut(
490             call->GetSlotId(), call->GetCallID(), static_cast<int32_t>(call->GetVideoStateType()));
491     }
492     // need DTMF judge
493     int32_t ret = call->SetTelCallState(nextState);
494     if (ret != TELEPHONY_SUCCESS && ret != CALL_ERR_NOT_NEW_STATE) {
495         TELEPHONY_LOGE("SetTelCallState failed");
496         return TELEPHONY_ERR_LOCAL_PTR_NULL;
497     }
498     // notify state changed
499     if (!DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallStateUpdated(call, priorState, nextState)) {
500         TELEPHONY_LOGE(
501             "NotifyCallStateUpdated failed! priorState:%{public}d,nextState:%{public}d", priorState, nextState);
502         if (nextState == TelCallState::CALL_STATUS_INCOMING) {
503             CallManagerHisysevent::WriteIncomingCallFaultEvent(call->GetSlotId(),
504                 static_cast<int32_t>(call->GetCallType()), static_cast<int32_t>(call->GetVideoStateType()), ret,
505                 "NotifyCallStateUpdated failed");
506         }
507         return CALL_ERR_PHONE_CALLSTATE_NOTIFY_FAILED;
508     }
509     return TELEPHONY_SUCCESS;
510 }
511 
RefreshCallIfNecessary(const sptr<CallBase> & call,const CallDetailInfo & info)512 sptr<CallBase> CallStatusManager::RefreshCallIfNecessary(const sptr<CallBase> &call, const CallDetailInfo &info)
513 {
514     TELEPHONY_LOGI("RefreshCallIfNecessary");
515     if (call->GetCallType() == info.callType) {
516         TELEPHONY_LOGI("RefreshCallIfNecessary not need Refresh");
517         return call;
518     }
519     CallAttributeInfo attrInfo;
520     (void)memset_s(&attrInfo, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
521     call->GetCallAttributeBaseInfo(attrInfo);
522     sptr<CallBase> newCall = CreateNewCall(info, attrInfo.callDirection);
523     if (newCall == nullptr) {
524         TELEPHONY_LOGE("RefreshCallIfNecessary createCallFail");
525         return call;
526     }
527     newCall->SetCallRunningState(call->GetCallRunningState());
528     newCall->SetTelConferenceState(call->GetTelConferenceState());
529     newCall->SetStartTime(attrInfo.startTime);
530     newCall->SetPolicyFlag(PolicyFlag(call->GetPolicyFlag()));
531     newCall->SetSpeakerphoneOn(call->IsSpeakerphoneOn());
532     newCall->SetCallEndedType(call->GetCallEndedType());
533     newCall->SetCallBeginTime(attrInfo.callBeginTime);
534     newCall->SetCallEndTime(attrInfo.callEndTime);
535     newCall->SetRingBeginTime(attrInfo.ringBeginTime);
536     newCall->SetRingEndTime(attrInfo.ringEndTime);
537     newCall->SetAnswerType(attrInfo.answerType);
538     DeleteOneCallObject(call->GetCallID());
539     newCall->SetCallId(call->GetCallID());
540     return newCall;
541 }
542 
ToSpeakerPhone(sptr<CallBase> & call)543 int32_t CallStatusManager::ToSpeakerPhone(sptr<CallBase> &call)
544 {
545     int32_t ret = TELEPHONY_ERR_FAIL;
546     if (call == nullptr) {
547         TELEPHONY_LOGE("Call is NULL");
548         return TELEPHONY_ERR_LOCAL_PTR_NULL;
549     }
550     if (call->GetCallRunningState() == CallRunningState::CALL_RUNNING_STATE_DIALING) {
551         TELEPHONY_LOGI("Call is CALL_STATUS_DIALING");
552         return ret;
553     }
554     if (call->IsSpeakerphoneOn()) {
555         DelayedSingleton<AudioControlManager>::GetInstance()->SetAudioDevice(AudioDevice::DEVICE_SPEAKER);
556         ret = call->SetSpeakerphoneOn(false);
557     }
558     return ret;
559 }
560 
TurnOffMute(sptr<CallBase> & call)561 int32_t CallStatusManager::TurnOffMute(sptr<CallBase> &call)
562 {
563     bool enabled = true;
564     if (HasEmergencyCall(enabled) != TELEPHONY_SUCCESS) {
565         TELEPHONY_LOGI("CallStatusManager::TurnOffMute HasEmergencyCall failed.");
566     }
567     if (call->GetEmergencyState() || enabled) {
568         DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(false);
569     } else {
570         DelayedSingleton<AudioControlManager>::GetInstance()->SetMute(true);
571     }
572     return TELEPHONY_SUCCESS;
573 }
574 
CreateNewCall(const CallDetailInfo & info,CallDirection dir)575 sptr<CallBase> CallStatusManager::CreateNewCall(const CallDetailInfo &info, CallDirection dir)
576 {
577     sptr<CallBase> callPtr = nullptr;
578     DialParaInfo paraInfo;
579     AppExecFwk::PacMap extras;
580     extras.Clear();
581     PackParaInfo(paraInfo, info, dir, extras);
582     switch (info.callType) {
583         case CallType::TYPE_CS: {
584             if (dir == CallDirection::CALL_DIRECTION_OUT) {
585                 callPtr = (std::make_unique<CSCall>(paraInfo, extras)).release();
586             } else {
587                 callPtr = (std::make_unique<CSCall>(paraInfo)).release();
588             }
589             break;
590         }
591         case CallType::TYPE_IMS: {
592             if (dir == CallDirection::CALL_DIRECTION_OUT) {
593                 callPtr = (std::make_unique<IMSCall>(paraInfo, extras)).release();
594             } else {
595                 callPtr = (std::make_unique<IMSCall>(paraInfo)).release();
596             }
597             break;
598         }
599         case CallType::TYPE_OTT: {
600             if (dir == CallDirection::CALL_DIRECTION_OUT) {
601                 callPtr = (std::make_unique<OTTCall>(paraInfo, extras)).release();
602             } else {
603                 callPtr = (std::make_unique<OTTCall>(paraInfo)).release();
604             }
605             break;
606         }
607         default:
608             return nullptr;
609     }
610     if (callPtr == nullptr) {
611         TELEPHONY_LOGE("CreateNewCall failed!");
612         return nullptr;
613     }
614     AddOneCallObject(callPtr);
615     return callPtr;
616 }
617 
PackParaInfo(DialParaInfo & paraInfo,const CallDetailInfo & info,CallDirection dir,AppExecFwk::PacMap & extras)618 void CallStatusManager::PackParaInfo(
619     DialParaInfo &paraInfo, const CallDetailInfo &info, CallDirection dir, AppExecFwk::PacMap &extras)
620 {
621     paraInfo.isEcc = false;
622     paraInfo.dialType = DialType::DIAL_CARRIER_TYPE;
623     if (dir == CallDirection::CALL_DIRECTION_OUT) {
624         DelayedSingleton<CallControlManager>::GetInstance()->GetDialParaInfo(paraInfo, extras);
625     }
626     paraInfo.number = info.phoneNum;
627     paraInfo.callId = GetNewCallId();
628     paraInfo.index = info.index;
629     paraInfo.videoState = VideoStateType::TYPE_VOICE;
630     paraInfo.accountId = info.accountId;
631     paraInfo.callType = info.callType;
632     paraInfo.callState = info.state;
633     paraInfo.bundleName = info.bundleName;
634 }
635 } // namespace Telephony
636 } // namespace OHOS
637