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
27namespace OHOS {
28namespace Telephony {
29IMSCall::IMSCall(DialParaInfo &info) : CarrierCall(info), videoCallState_(nullptr), isInitialized_(false) {}
30
31IMSCall::IMSCall(DialParaInfo &info, AppExecFwk::PacMap &extras)
32    : CarrierCall(info, extras), videoCallState_(nullptr), isInitialized_(false)
33{}
34
35IMSCall::~IMSCall() {}
36
37int32_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
81void 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
102int32_t IMSCall::DialingProcess()
103{
104    return CarrierDialingProcess();
105}
106
107int32_t IMSCall::AnswerCall(int32_t videoState)
108{
109    return CarrierAnswerCall(videoState);
110}
111
112int32_t IMSCall::RejectCall()
113{
114    return CarrierRejectCall();
115}
116
117int32_t IMSCall::HangUpCall()
118{
119    return CarrierHangUpCall();
120}
121
122int32_t IMSCall::HoldCall()
123{
124    return CarrierHoldCall();
125}
126
127int32_t IMSCall::UnHoldCall()
128{
129    return CarrierUnHoldCall();
130}
131
132int32_t IMSCall::SwitchCall()
133{
134    return CarrierSwitchCall();
135}
136
137int32_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
153int32_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
169int32_t IMSCall::SetMute(int32_t mute, int32_t slotId)
170{
171    return CarrierSetMute(mute, slotId);
172}
173
174void IMSCall::GetCallAttributeInfo(CallAttributeInfo &info)
175{
176    GetCallAttributeCarrierInfo(info);
177}
178
179int32_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
195void 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
207int32_t IMSCall::SeparateConference()
208{
209    return CarrierSeparateConference();
210}
211
212int32_t IMSCall::KickOutFromConference()
213{
214    return CarrierKickOutFromConference();
215}
216
217int32_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
227int32_t IMSCall::CanSeparateConference()
228{
229    return DelayedSingleton<ImsConference>::GetInstance()->CanSeparateConference();
230}
231
232int32_t IMSCall::CanKickOutFromConference()
233{
234    return DelayedSingleton<ImsConference>::GetInstance()->CanKickOutFromConference();
235}
236
237int32_t IMSCall::GetMainCallId(int32_t &mainCallId)
238{
239    mainCallId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
240    return TELEPHONY_SUCCESS;
241}
242
243int32_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
252int32_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
261int32_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
270int32_t IMSCall::GetSubCallIdList(std::vector<std::u16string> &callIdList)
271{
272    return DelayedSingleton<ImsConference>::GetInstance()->GetSubCallIdList(GetCallID(), callIdList);
273}
274
275int32_t IMSCall::GetCallIdListForConference(std::vector<std::u16string> &callIdList)
276{
277    return DelayedSingleton<ImsConference>::GetInstance()->GetCallIdListForConference(GetCallID(), callIdList);
278}
279
280int32_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
297int32_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
318int32_t IMSCall::ReportImsCallModeInfo(CallMediaModeInfo &imsCallModeInfo)
319{
320    TELEPHONY_LOGI("callMode:%{public}d", imsCallModeInfo.callMode);
321    return DelayedSingleton<VideoControlManager>::GetInstance()->ReportImsCallModeInfo(imsCallModeInfo);
322}
323
324int32_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
341int32_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
358int32_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
374int32_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
394int32_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
406int32_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
418int32_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
430int32_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
441int32_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
452int32_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
463int32_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
474void 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
486bool 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
503sptr<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
513bool 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