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 "ims_call.h"
17 
18 #include "call_control_manager.h"
19 #include "call_object_manager.h"
20 #include "call_manager_errors.h"
21 #include "telephony_log_wrapper.h"
22 #include "ims_conference.h"
23 #include "video_control_manager.h"
24 
25 #include "cellular_call_connection.h"
26 
27 namespace OHOS {
28 namespace Telephony {
IMSCall(DialParaInfo & info)29 IMSCall::IMSCall(DialParaInfo &info) : CarrierCall(info), videoCallState_(nullptr), isInitialized_(false) {}
30 
IMSCall(DialParaInfo & info,AppExecFwk::PacMap & extras)31 IMSCall::IMSCall(DialParaInfo &info, AppExecFwk::PacMap &extras)
32     : CarrierCall(info, extras), videoCallState_(nullptr), isInitialized_(false)
33 {}
34 
~IMSCall()35 IMSCall::~IMSCall() {}
36 
InitVideoCall()37 int32_t IMSCall::InitVideoCall()
38 {
39     if (isInitialized_) {
40         VideoStateType videoStateType = GetVideoStateType();
41         AssignVideoCallState(videoStateType);
42         TELEPHONY_LOGI("video call initialize ok!");
43         return TELEPHONY_SUCCESS;
44     }
45     sptr<VideoCallState> state = (std::make_unique<AudioOnlyState>(this)).release();
46     if (state == nullptr) {
47         TELEPHONY_LOGE("null pointer");
48         return TELEPHONY_ERR_LOCAL_PTR_NULL;
49     }
50     videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY] = state;
51     state = (std::make_unique<VideoSendState>(this)).release();
52     if (state == nullptr) {
53         TELEPHONY_LOGE("null pointer");
54         return TELEPHONY_ERR_LOCAL_PTR_NULL;
55     }
56     videoStateMap_[ImsCallMode::CALL_MODE_SEND_ONLY] = state;
57     state = (std::make_unique<VideoReceiveState>(this)).release();
58     if (state == nullptr) {
59         TELEPHONY_LOGE("null pointer");
60         return TELEPHONY_ERR_LOCAL_PTR_NULL;
61     }
62     videoStateMap_[ImsCallMode::CALL_MODE_RECEIVE_ONLY] = state;
63     state = (std::make_unique<VideoSendReceiveState>(this)).release();
64     if (state == nullptr) {
65         TELEPHONY_LOGE("null pointer");
66         return TELEPHONY_ERR_LOCAL_PTR_NULL;
67     }
68     videoStateMap_[ImsCallMode::CALL_MODE_SEND_RECEIVE] = state;
69     state = (std::make_unique<VideoPauseState>(this)).release();
70     if (state == nullptr) {
71         TELEPHONY_LOGE("null pointer");
72         return TELEPHONY_ERR_LOCAL_PTR_NULL;
73     }
74     videoStateMap_[ImsCallMode::CALL_MODE_VIDEO_PAUSED] = state;
75     VideoStateType videoStateType = GetVideoStateType();
76     AssignVideoCallState(videoStateType);
77     isInitialized_ = true;
78     return TELEPHONY_SUCCESS;
79 }
80 
AssignVideoCallState(VideoStateType videoStateType)81 void IMSCall::AssignVideoCallState(VideoStateType videoStateType)
82 {
83     switch (videoStateType) {
84         case VideoStateType::TYPE_VOICE:
85             videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY];
86             break;
87         case VideoStateType::TYPE_SEND_ONLY:
88             videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_SEND_ONLY];
89             break;
90         case VideoStateType::TYPE_RECEIVE_ONLY:
91             videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_RECEIVE_ONLY];
92             break;
93         case VideoStateType::TYPE_VIDEO:
94             videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_SEND_RECEIVE];
95             break;
96         default:
97             videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY];
98             break;
99     }
100 }
101 
DialingProcess()102 int32_t IMSCall::DialingProcess()
103 {
104     return CarrierDialingProcess();
105 }
106 
AnswerCall(int32_t videoState)107 int32_t IMSCall::AnswerCall(int32_t videoState)
108 {
109     return CarrierAnswerCall(videoState);
110 }
111 
RejectCall()112 int32_t IMSCall::RejectCall()
113 {
114     return CarrierRejectCall();
115 }
116 
HangUpCall()117 int32_t IMSCall::HangUpCall()
118 {
119     return CarrierHangUpCall();
120 }
121 
HoldCall()122 int32_t IMSCall::HoldCall()
123 {
124     return CarrierHoldCall();
125 }
126 
UnHoldCall()127 int32_t IMSCall::UnHoldCall()
128 {
129     return CarrierUnHoldCall();
130 }
131 
SwitchCall()132 int32_t IMSCall::SwitchCall()
133 {
134     return CarrierSwitchCall();
135 }
136 
StartRtt(std::u16string & msg)137 int32_t IMSCall::StartRtt(std::u16string &msg)
138 {
139     CellularCallInfo callInfo;
140     int32_t ret = PackCellularCallInfo(callInfo);
141     if (ret != TELEPHONY_SUCCESS) {
142         TELEPHONY_LOGW("PackCellularCallInfo failed!");
143         return ret;
144     }
145     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->StartRtt(callInfo, msg);
146     if (ret != TELEPHONY_SUCCESS) {
147         TELEPHONY_LOGE("StartRtt failed!");
148         return CALL_ERR_STARTRTT_FAILED;
149     }
150     return TELEPHONY_SUCCESS;
151 }
152 
StopRtt()153 int32_t IMSCall::StopRtt()
154 {
155     CellularCallInfo callInfo;
156     int32_t ret = PackCellularCallInfo(callInfo);
157     if (ret != TELEPHONY_SUCCESS) {
158         TELEPHONY_LOGW("PackCellularCallInfo failed!");
159         return ret;
160     }
161     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->StopRtt(callInfo);
162     if (ret != TELEPHONY_SUCCESS) {
163         TELEPHONY_LOGE("StopRtt failed!");
164         return CALL_ERR_STOPRTT_FAILED;
165     }
166     return TELEPHONY_SUCCESS;
167 }
168 
SetMute(int32_t mute,int32_t slotId)169 int32_t IMSCall::SetMute(int32_t mute, int32_t slotId)
170 {
171     return CarrierSetMute(mute, slotId);
172 }
173 
GetCallAttributeInfo(CallAttributeInfo & info)174 void IMSCall::GetCallAttributeInfo(CallAttributeInfo &info)
175 {
176     GetCallAttributeCarrierInfo(info);
177 }
178 
CombineConference()179 int32_t IMSCall::CombineConference()
180 {
181     int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->SetMainCall(GetCallID());
182     if (ret != TELEPHONY_SUCCESS) {
183         TELEPHONY_LOGE("SetMainCall failed,  error%{public}d", ret);
184         return ret;
185     }
186     ConferenceState currentState = DelayedSingleton<ImsConference>::GetInstance()->GetConferenceState();
187     if (currentState == ConferenceState::CONFERENCE_STATE_CREATING) {
188         TELEPHONY_LOGE("skip combine, a process of combine already exsists");
189         return TELEPHONY_SUCCESS;
190     }
191     DelayedSingleton<ImsConference>::GetInstance()->SetConferenceState(ConferenceState::CONFERENCE_STATE_CREATING);
192     return CarrierCombineConference();
193 }
194 
HandleCombineConferenceFailEvent()195 void IMSCall::HandleCombineConferenceFailEvent()
196 {
197     std::set<std::int32_t> subCallIdList = DelayedSingleton<ImsConference>::GetInstance()->GetSubCallIdList();
198     if (subCallIdList.empty()) {
199         DelayedSingleton<ImsConference>::GetInstance()->SetMainCall(ERR_ID);
200     } else {
201         DelayedSingleton<ImsConference>::GetInstance()->SetMainCall(*subCallIdList.begin());
202     }
203     ConferenceState oldState = DelayedSingleton<ImsConference>::GetInstance()->GetOldConferenceState();
204     DelayedSingleton<ImsConference>::GetInstance()->SetConferenceState(oldState);
205 }
206 
SeparateConference()207 int32_t IMSCall::SeparateConference()
208 {
209     return CarrierSeparateConference();
210 }
211 
KickOutFromConference()212 int32_t IMSCall::KickOutFromConference()
213 {
214     return CarrierKickOutFromConference();
215 }
216 
CanCombineConference()217 int32_t IMSCall::CanCombineConference()
218 {
219     int32_t ret = IsSupportConferenceable();
220     if (ret != TELEPHONY_SUCCESS) {
221         TELEPHONY_LOGE("call unsupported conference,  error%{public}d", ret);
222         return ret;
223     }
224     return DelayedSingleton<ImsConference>::GetInstance()->CanCombineConference();
225 }
226 
CanSeparateConference()227 int32_t IMSCall::CanSeparateConference()
228 {
229     return DelayedSingleton<ImsConference>::GetInstance()->CanSeparateConference();
230 }
231 
CanKickOutFromConference()232 int32_t IMSCall::CanKickOutFromConference()
233 {
234     return DelayedSingleton<ImsConference>::GetInstance()->CanKickOutFromConference();
235 }
236 
GetMainCallId(int32_t & mainCallId)237 int32_t IMSCall::GetMainCallId(int32_t &mainCallId)
238 {
239     mainCallId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
240     return TELEPHONY_SUCCESS;
241 }
242 
LaunchConference()243 int32_t IMSCall::LaunchConference()
244 {
245     int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->JoinToConference(GetCallID());
246     if (ret == TELEPHONY_SUCCESS) {
247         SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_ACTIVE);
248     }
249     return ret;
250 }
251 
ExitConference()252 int32_t IMSCall::ExitConference()
253 {
254     int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->LeaveFromConference(GetCallID());
255     if (ret == TELEPHONY_SUCCESS) {
256         SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_IDLE);
257     }
258     return ret;
259 }
260 
HoldConference()261 int32_t IMSCall::HoldConference()
262 {
263     int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->HoldConference(GetCallID());
264     if (ret == TELEPHONY_SUCCESS) {
265         SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_HOLDING);
266     }
267     return ret;
268 }
269 
GetSubCallIdList(std::vector<std::u16string> & callIdList)270 int32_t IMSCall::GetSubCallIdList(std::vector<std::u16string> &callIdList)
271 {
272     return DelayedSingleton<ImsConference>::GetInstance()->GetSubCallIdList(GetCallID(), callIdList);
273 }
274 
GetCallIdListForConference(std::vector<std::u16string> & callIdList)275 int32_t IMSCall::GetCallIdListForConference(std::vector<std::u16string> &callIdList)
276 {
277     return DelayedSingleton<ImsConference>::GetInstance()->GetCallIdListForConference(GetCallID(), callIdList);
278 }
279 
IsSupportConferenceable()280 int32_t IMSCall::IsSupportConferenceable()
281 {
282 #ifdef ABILIT_CONFIG_SUPPORT
283     bool carrierSupport = GetCarrierConfig(IMS_SUPPORT_CONFERENCE);
284     if (!carrierSupport) {
285         return TELEPHONY_CONFERENCE_CARRIER_NOT_SUPPORT;
286     }
287     if (isVideoCall()) {
288         carrierSupport = GetCarrierConfig(IMS_VIDEO_SUPPORT_CONFERENCE)
289     }
290     if (!carrierSupport) {
291         return TELEPHONY_CONFERENCE_VIDEO_CALL_NOT_SUPPORT;
292     }
293 #endif
294     return CarrierCall::IsSupportConferenceable();
295 }
296 
UpdateImsCallMode(ImsCallMode mode)297 int32_t IMSCall::UpdateImsCallMode(ImsCallMode mode)
298 {
299     std::lock_guard<std::mutex> lock(videoUpdateMutex_);
300     int32_t ret = TELEPHONY_SUCCESS;
301     if (GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
302         TELEPHONY_LOGE("call state is not active");
303         return CALL_ERR_CALL_STATE;
304     }
305     if (videoCallState_ == nullptr) {
306         TELEPHONY_LOGE("unexpected null pointer");
307         return TELEPHONY_ERR_LOCAL_PTR_NULL;
308     }
309     VideoUpdateStatus status = videoCallState_->GetVideoUpdateStatus();
310     if (VideoUpdateStatus::STATUS_NONE == status) {
311         ret = videoCallState_->SendUpdateCallMediaModeRequest(mode);
312     } else if (VideoUpdateStatus::STATUS_RECV_REQUEST == status) {
313         ret = videoCallState_->SendUpdateCallMediaModeResponse(mode);
314     }
315     return ret;
316 }
317 
ReportImsCallModeInfo(CallMediaModeInfo & imsCallModeInfo)318 int32_t IMSCall::ReportImsCallModeInfo(CallMediaModeInfo &imsCallModeInfo)
319 {
320     TELEPHONY_LOGI("callMode:%{public}d", imsCallModeInfo.callMode);
321     return DelayedSingleton<VideoControlManager>::GetInstance()->ReportImsCallModeInfo(imsCallModeInfo);
322 }
323 
SendUpdateCallMediaModeRequest(ImsCallMode mode)324 int32_t IMSCall::SendUpdateCallMediaModeRequest(ImsCallMode mode)
325 {
326     CellularCallInfo callInfo;
327     int32_t ret = PackCellularCallInfo(callInfo);
328     TELEPHONY_LOGI("SendUpdateCallMediaModeRequest callMode:%{public}d", mode);
329     if (ret != TELEPHONY_SUCCESS) {
330         TELEPHONY_LOGW("PackCellularCallInfo failed!");
331         return ret;
332     }
333     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SendUpdateCallMediaModeRequest(callInfo, mode);
334     if (ret != TELEPHONY_SUCCESS) {
335         TELEPHONY_LOGE("send update media failed, errno:%{public}d!", ret);
336         return ret;
337     }
338     return TELEPHONY_SUCCESS;
339 }
340 
SendUpdateCallMediaModeResponse(ImsCallMode mode)341 int32_t IMSCall::SendUpdateCallMediaModeResponse(ImsCallMode mode)
342 {
343     CellularCallInfo callInfo;
344     int32_t ret = PackCellularCallInfo(callInfo);
345     TELEPHONY_LOGI("SendUpdateCallMediaModeResponse callMode:%{public}d", mode);
346     if (ret != TELEPHONY_SUCCESS) {
347         TELEPHONY_LOGW("PackCellularCallInfo failed!");
348         return ret;
349     }
350     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SendUpdateCallMediaModeResponse(callInfo, mode);
351     if (ret != TELEPHONY_SUCCESS) {
352         TELEPHONY_LOGE("send update media failed, errno:%{public}d!", ret);
353         return ret;
354     }
355     return TELEPHONY_SUCCESS;
356 }
357 
RecieveUpdateCallMediaModeRequest(CallModeReportInfo & response)358 int32_t IMSCall::RecieveUpdateCallMediaModeRequest(CallModeReportInfo &response)
359 {
360     std::lock_guard<std::mutex> lock(videoUpdateMutex_);
361     if (videoCallState_ == nullptr) {
362         TELEPHONY_LOGE("unexpected null pointer");
363         return TELEPHONY_ERR_LOCAL_PTR_NULL;
364     }
365     CallMediaModeInfo callModeInfo;
366     callModeInfo.callId = GetCallID();
367     callModeInfo.result = response.result;
368     callModeInfo.callMode = response.callMode;
369     callModeInfo.isRequestInfo = true;
370     TELEPHONY_LOGI("RecieveUpdateCallMediaModeRequest callMode:%{public}d", callModeInfo.callMode);
371     return videoCallState_->RecieveUpdateCallMediaModeRequest(callModeInfo);
372 }
373 
ReceiveUpdateCallMediaModeResponse(CallModeReportInfo & response)374 int32_t IMSCall::ReceiveUpdateCallMediaModeResponse(CallModeReportInfo &response)
375 {
376     std::lock_guard<std::mutex> lock(videoUpdateMutex_);
377     if (videoCallState_ == nullptr) {
378         TELEPHONY_LOGE("unexpected null pointer");
379         return TELEPHONY_ERR_LOCAL_PTR_NULL;
380     }
381     CallMediaModeInfo callModeInfo;
382     callModeInfo.callId = GetCallID();
383     callModeInfo.result = response.result;
384     callModeInfo.callMode = response.callMode;
385     callModeInfo.isRequestInfo = false;
386     TELEPHONY_LOGI("ReceiveUpdateCallMediaModeResponse callMode:%{public}d", callModeInfo.callMode);
387     if (response.result == VideoRequestResultType::TYPE_REQUEST_SUCCESS) {
388         return videoCallState_->ReceiveUpdateCallMediaModeResponse(callModeInfo);
389     }
390     callModeInfo.callMode = ImsCallMode::CALL_MODE_AUDIO_ONLY;
391     return videoCallState_->ReceiveUpdateCallMediaModeResponse(callModeInfo);
392 }
393 
ControlCamera(std::string & cameraId,int32_t callingUid,int32_t callingPid)394 int32_t IMSCall::ControlCamera(std::string &cameraId, int32_t callingUid, int32_t callingPid)
395 {
396     TELEPHONY_LOGI("cameraId:%{public}s", cameraId.c_str());
397     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->ControlCamera(
398         GetSlotId(), GetCallIndex(), cameraId, callingUid, callingPid);
399     if (ret != TELEPHONY_SUCCESS) {
400         TELEPHONY_LOGE("CancelCallUpgrade failed!");
401         return ret;
402     }
403     return TELEPHONY_SUCCESS;
404 }
405 
SetPreviewWindow(std::string & surfaceId,sptr<Surface> surface)406 int32_t IMSCall::SetPreviewWindow(std::string &surfaceId, sptr<Surface> surface)
407 {
408     TELEPHONY_LOGI("surfaceId:%{public}s", surfaceId.c_str());
409     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SetPreviewWindow(
410         GetSlotId(), GetCallIndex(), surfaceId, surface);
411     if (ret != TELEPHONY_SUCCESS) {
412         TELEPHONY_LOGE("CancelCallUpgrade failed!");
413         return ret;
414     }
415     return TELEPHONY_SUCCESS;
416 }
417 
SetDisplayWindow(std::string & surfaceId,sptr<Surface> surface)418 int32_t IMSCall::SetDisplayWindow(std::string &surfaceId, sptr<Surface> surface)
419 {
420     TELEPHONY_LOGI("surfaceId:%{public}s", surfaceId.c_str());
421     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SetDisplayWindow(
422         GetSlotId(), GetCallIndex(), surfaceId, surface);
423     if (ret != TELEPHONY_SUCCESS) {
424         TELEPHONY_LOGE("CancelCallUpgrade failed!");
425         return ret;
426     }
427     return TELEPHONY_SUCCESS;
428 }
429 
SetPausePicture(std::string & path)430 int32_t IMSCall::SetPausePicture(std::string &path)
431 {
432     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SetPausePicture(
433         GetSlotId(), GetCallIndex(), path);
434     if (ret != TELEPHONY_SUCCESS) {
435         TELEPHONY_LOGE("CancelCallUpgrade failed!");
436         return ret;
437     }
438     return TELEPHONY_SUCCESS;
439 }
440 
SetDeviceDirection(int32_t rotation)441 int32_t IMSCall::SetDeviceDirection(int32_t rotation)
442 {
443     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SetDeviceDirection(
444         GetSlotId(), GetCallIndex(), rotation);
445     if (ret != TELEPHONY_SUCCESS) {
446         TELEPHONY_LOGE("CancelCallUpgrade failed!");
447         return ret;
448     }
449     return TELEPHONY_SUCCESS;
450 }
451 
RequestCameraCapabilities()452 int32_t IMSCall::RequestCameraCapabilities()
453 {
454     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->RequestCameraCapabilities(
455         GetSlotId(), GetCallIndex());
456     if (ret != TELEPHONY_SUCCESS) {
457         TELEPHONY_LOGE("CancelCallUpgrade failed!");
458         return ret;
459     }
460     return TELEPHONY_SUCCESS;
461 }
462 
CancelCallUpgrade()463 int32_t IMSCall::CancelCallUpgrade()
464 {
465     int32_t ret = DelayedSingleton<CellularCallConnection>::GetInstance()->CancelCallUpgrade(
466         GetSlotId(), GetCallIndex());
467     if (ret != TELEPHONY_SUCCESS) {
468         TELEPHONY_LOGE("CancelCallUpgrade failed!");
469         return ret;
470     }
471     return TELEPHONY_SUCCESS;
472 }
473 
SwitchVideoState(ImsCallMode mode)474 void IMSCall::SwitchVideoState(ImsCallMode mode)
475 {
476     // save old state.
477     TELEPHONY_LOGI("SwitchVideoState call %{public}d switch to state %{public}d", GetCallID(), mode);
478     if (videoStateMap_.find(mode) != videoStateMap_.end()) {
479         videoCallState_ = videoStateMap_[mode];
480     } else {
481         videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY];
482     }
483     return;
484 }
485 
IsSupportVideoCall()486 bool IMSCall::IsSupportVideoCall()
487 {
488     bool isSupportVideoCall = true;
489 #ifdef ABILITY_CONFIG_SUPPORT
490     isSupportVideoCall = GetCarrierConfig(ITEM_VIDEO_CALL);
491 #endif
492     if (GetTelCallState() == TelCallState::CALL_STATUS_INCOMING) {
493         TELEPHONY_LOGW("incoming call not support video upgrade");
494         isSupportVideoCall = false;
495     }
496     if (GetEmergencyState()) {
497         TELEPHONY_LOGW("emergency call not support video upgrade");
498         isSupportVideoCall = false;
499     }
500     return isSupportVideoCall;
501 }
502 
GetCallVideoState(ImsCallMode mode)503 sptr<VideoCallState> IMSCall::GetCallVideoState(ImsCallMode mode)
504 {
505     TELEPHONY_LOGI("get call video state %{public}d", mode);
506     if (videoStateMap_.find(mode) != videoStateMap_.end()) {
507         return videoStateMap_[mode];
508     } else {
509         return nullptr;
510     }
511 }
512 
IsVoiceModifyToVideo()513 bool IMSCall::IsVoiceModifyToVideo()
514 {
515     if (videoCallState_ != nullptr &&
516         VideoUpdateStatus::STATUS_SEND_REQUEST == videoCallState_->GetVideoUpdateStatus()) {
517         return true;
518     }
519     return false;
520 }
521 } // namespace Telephony
522 } // namespace OHOS
523