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