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
24 #include "cellular_call_connection.h"
25
26 namespace OHOS {
27 namespace Telephony {
IMSCall(DialParaInfo & info)28 IMSCall::IMSCall(DialParaInfo &info) : CarrierCall(info), videoCallState_(nullptr), isInitialized_(false) {}
29
IMSCall(DialParaInfo & info,AppExecFwk::PacMap & extras)30 IMSCall::IMSCall(DialParaInfo &info, AppExecFwk::PacMap &extras)
31 : CarrierCall(info, extras), videoCallState_(nullptr), isInitialized_(false)
32 {}
33
~IMSCall()34 IMSCall::~IMSCall() {}
35
InitVideoCall()36 int32_t IMSCall::InitVideoCall()
37 {
38 if (isInitialized_) {
39 TELEPHONY_LOGI("video call initialize ok!");
40 return TELEPHONY_SUCCESS;
41 }
42 sptr<VideoCallState> state = new (std::nothrow) AudioOnlyState(this);
43 if (state == nullptr) {
44 TELEPHONY_LOGE("null pointer");
45 return TELEPHONY_ERR_LOCAL_PTR_NULL;
46 }
47 videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY] = state;
48 videoCallState_ = state;
49 state = (std::make_unique<VideoSendState>(this)).release();
50 if (state == nullptr) {
51 TELEPHONY_LOGE("null pointer");
52 return TELEPHONY_ERR_LOCAL_PTR_NULL;
53 }
54 videoStateMap_[ImsCallMode::CALL_MODE_SEND_ONLY] = state;
55 state = (std::make_unique<VideoReceiveState>(this)).release();
56 if (state == nullptr) {
57 TELEPHONY_LOGE("null pointer");
58 return TELEPHONY_ERR_LOCAL_PTR_NULL;
59 }
60 videoStateMap_[ImsCallMode::CALL_MODE_RECEIVE_ONLY] = state;
61 state = (std::make_unique<VideoSendReceiveState>(this)).release();
62 if (state == nullptr) {
63 TELEPHONY_LOGE("null pointer");
64 return TELEPHONY_ERR_LOCAL_PTR_NULL;
65 }
66 videoStateMap_[ImsCallMode::CALL_MODE_SEND_RECEIVE] = state;
67 state = (std::make_unique<VideoPauseState>(this)).release();
68 if (state == nullptr) {
69 TELEPHONY_LOGE("null pointer");
70 return TELEPHONY_ERR_LOCAL_PTR_NULL;
71 }
72 videoStateMap_[ImsCallMode::CALL_MODE_VIDEO_PAUSED] = state;
73 isInitialized_ = true;
74 return TELEPHONY_SUCCESS;
75 }
76
DialingProcess()77 int32_t IMSCall::DialingProcess()
78 {
79 return CarrierDialingProcess();
80 }
81
AnswerCall(int32_t videoState)82 int32_t IMSCall::AnswerCall(int32_t videoState)
83 {
84 return CarrierAnswerCall(videoState);
85 }
86
RejectCall()87 int32_t IMSCall::RejectCall()
88 {
89 return CarrierRejectCall();
90 }
91
HangUpCall()92 int32_t IMSCall::HangUpCall()
93 {
94 return CarrierHangUpCall();
95 }
96
HoldCall()97 int32_t IMSCall::HoldCall()
98 {
99 return CarrierHoldCall();
100 }
101
UnHoldCall()102 int32_t IMSCall::UnHoldCall()
103 {
104 return CarrierUnHoldCall();
105 }
106
SwitchCall()107 int32_t IMSCall::SwitchCall()
108 {
109 return CarrierSwitchCall();
110 }
111
StartRtt(std::u16string & msg)112 int32_t IMSCall::StartRtt(std::u16string &msg)
113 {
114 CellularCallInfo callInfo;
115 int32_t ret = PackCellularCallInfo(callInfo);
116 if (ret != TELEPHONY_SUCCESS) {
117 TELEPHONY_LOGW("PackCellularCallInfo failed!");
118 return ret;
119 }
120 ret = DelayedSingleton<CellularCallConnection>::GetInstance()->StartRtt(callInfo, msg);
121 if (ret != TELEPHONY_SUCCESS) {
122 TELEPHONY_LOGE("StartRtt failed!");
123 return CALL_ERR_STARTRTT_FAILED;
124 }
125 return TELEPHONY_SUCCESS;
126 }
127
StopRtt()128 int32_t IMSCall::StopRtt()
129 {
130 CellularCallInfo callInfo;
131 int32_t ret = PackCellularCallInfo(callInfo);
132 if (ret != TELEPHONY_SUCCESS) {
133 TELEPHONY_LOGW("PackCellularCallInfo failed!");
134 return ret;
135 }
136 ret = DelayedSingleton<CellularCallConnection>::GetInstance()->StopRtt(callInfo);
137 if (ret != TELEPHONY_SUCCESS) {
138 TELEPHONY_LOGE("StopRtt failed!");
139 return CALL_ERR_STOPRTT_FAILED;
140 }
141 return TELEPHONY_SUCCESS;
142 }
143
SetMute(int32_t mute,int32_t slotId)144 int32_t IMSCall::SetMute(int32_t mute, int32_t slotId)
145 {
146 return CarrierSetMute(mute, slotId);
147 }
148
GetCallAttributeInfo(CallAttributeInfo & info)149 void IMSCall::GetCallAttributeInfo(CallAttributeInfo &info)
150 {
151 GetCallAttributeCarrierInfo(info);
152 }
153
CombineConference()154 int32_t IMSCall::CombineConference()
155 {
156 int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->SetMainCall(GetCallID());
157 if (ret != TELEPHONY_SUCCESS) {
158 TELEPHONY_LOGE("SetMainCall failed, error%{public}d", ret);
159 return ret;
160 }
161 return CarrierCombineConference();
162 }
163
SeparateConference()164 int32_t IMSCall::SeparateConference()
165 {
166 return CarrierSeparateConference();
167 }
168
CanCombineConference()169 int32_t IMSCall::CanCombineConference()
170 {
171 int32_t ret = IsSupportConferenceable();
172 if (ret != TELEPHONY_SUCCESS) {
173 TELEPHONY_LOGE("call unsupported conference, error%{public}d", ret);
174 return ret;
175 }
176 return DelayedSingleton<ImsConference>::GetInstance()->CanCombineConference();
177 }
178
CanSeparateConference()179 int32_t IMSCall::CanSeparateConference()
180 {
181 return DelayedSingleton<ImsConference>::GetInstance()->CanSeparateConference();
182 }
183
GetMainCallId(int32_t & mainCallId)184 int32_t IMSCall::GetMainCallId(int32_t &mainCallId)
185 {
186 mainCallId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
187 return TELEPHONY_SUCCESS;
188 }
189
LaunchConference()190 int32_t IMSCall::LaunchConference()
191 {
192 int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->JoinToConference(GetCallID());
193 if (ret == TELEPHONY_SUCCESS) {
194 SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_ACTIVE);
195 }
196 return ret;
197 }
198
ExitConference()199 int32_t IMSCall::ExitConference()
200 {
201 return DelayedSingleton<ImsConference>::GetInstance()->LeaveFromConference(GetCallID());
202 }
203
HoldConference()204 int32_t IMSCall::HoldConference()
205 {
206 int32_t ret = DelayedSingleton<ImsConference>::GetInstance()->HoldConference(GetCallID());
207 if (ret == TELEPHONY_SUCCESS) {
208 SetTelConferenceState(TelConferenceState::TEL_CONFERENCE_HOLDING);
209 }
210 return ret;
211 }
212
GetSubCallIdList(std::vector<std::u16string> & callIdList)213 int32_t IMSCall::GetSubCallIdList(std::vector<std::u16string> &callIdList)
214 {
215 return DelayedSingleton<ImsConference>::GetInstance()->GetSubCallIdList(GetCallID(), callIdList);
216 }
217
GetCallIdListForConference(std::vector<std::u16string> & callIdList)218 int32_t IMSCall::GetCallIdListForConference(std::vector<std::u16string> &callIdList)
219 {
220 return DelayedSingleton<ImsConference>::GetInstance()->GetCallIdListForConference(GetCallID(), callIdList);
221 }
222
IsSupportConferenceable()223 int32_t IMSCall::IsSupportConferenceable()
224 {
225 #ifdef ABILIT_CONFIG_SUPPORT
226 bool carrierSupport = GetCarrierConfig(IMS_SUPPORT_CONFERENCE);
227 if (!carrierSupport) {
228 return TELEPHONY_CONFERENCE_CARRIER_NOT_SUPPORT;
229 }
230 if (isVideoCall()) {
231 carrierSupport = GetCarrierConfig(IMS_VIDEO_SUPPORT_CONFERENCE)
232 }
233 if (!carrierSupport) {
234 return TELEPHONY_CONFERENCE_VIDEO_CALL_NOT_SUPPORT;
235 }
236 #endif
237 return CarrierCall::IsSupportConferenceable();
238 }
239
AcceptVideoCall()240 int32_t IMSCall::AcceptVideoCall()
241 {
242 TELEPHONY_LOGI("always accept video call request.");
243 return SendUpdateCallMediaModeResponse(ImsCallMode::CALL_MODE_SEND_RECEIVE);
244 }
245
RefuseVideoCall()246 int32_t IMSCall::RefuseVideoCall()
247 {
248 TELEPHONY_LOGI("always refuse video call request.");
249 return SendUpdateCallMediaModeResponse(ImsCallMode::CALL_MODE_AUDIO_ONLY);
250 }
251
SendUpdateCallMediaModeRequest(ImsCallMode mode)252 int32_t IMSCall::SendUpdateCallMediaModeRequest(ImsCallMode mode)
253 {
254 std::lock_guard<std::mutex> lock(videoUpdateMutex_);
255 int32_t ret = InitVideoCall();
256 if (ret != TELEPHONY_SUCCESS) {
257 TELEPHONY_LOGE("video call initialize failed");
258 return ret;
259 }
260 if (GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
261 TELEPHONY_LOGE("call state is not active");
262 return CALL_ERR_CALL_STATE;
263 }
264 if (videoCallState_ == nullptr) {
265 TELEPHONY_LOGE("unexpected null pointer");
266 return TELEPHONY_ERR_LOCAL_PTR_NULL;
267 }
268 return videoCallState_->SendUpdateCallMediaModeRequest(mode);
269 }
270
SendUpdateCallMediaModeResponse(ImsCallMode mode)271 int32_t IMSCall::SendUpdateCallMediaModeResponse(ImsCallMode mode)
272 {
273 std::lock_guard<std::mutex> lock(videoUpdateMutex_);
274 int32_t ret = InitVideoCall();
275 if (ret != TELEPHONY_SUCCESS) {
276 TELEPHONY_LOGE("video call initialize failed");
277 return ret;
278 }
279
280 if (GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
281 TELEPHONY_LOGE("call state is not active");
282 return CALL_ERR_CALL_STATE;
283 }
284 return videoCallState_->SendUpdateCallMediaModeResponse(mode);
285 }
286
RecieveUpdateCallMediaModeRequest(ImsCallMode mode)287 int32_t IMSCall::RecieveUpdateCallMediaModeRequest(ImsCallMode mode)
288 {
289 std::lock_guard<std::mutex> lock(videoUpdateMutex_);
290 int32_t ret = InitVideoCall();
291 if (ret != TELEPHONY_SUCCESS) {
292 TELEPHONY_LOGE("video call initialize failed");
293 return ret;
294 }
295 if (GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
296 TELEPHONY_LOGE("call state is not active");
297 return CALL_ERR_CALL_STATE;
298 }
299 return videoCallState_->RecieveUpdateCallMediaModeRequest(mode);
300 }
301
ReceiveUpdateCallMediaModeResponse(CallMediaModeResponse & response)302 int32_t IMSCall::ReceiveUpdateCallMediaModeResponse(CallMediaModeResponse &response)
303 {
304 std::lock_guard<std::mutex> lock(videoUpdateMutex_);
305 int32_t ret = InitVideoCall();
306 if (ret != TELEPHONY_SUCCESS) {
307 TELEPHONY_LOGE("video call initialize failed");
308 return ret;
309 }
310 if (GetTelCallState() != TelCallState::CALL_STATUS_ACTIVE) {
311 TELEPHONY_LOGE("call state is not active");
312 return CALL_ERR_CALL_STATE;
313 }
314 if (response.result == TELEPHONY_SUCCESS) {
315 return videoCallState_->ReceiveUpdateCallMediaModeResponse(ImsCallMode::CALL_MODE_SEND_RECEIVE);
316 }
317 return videoCallState_->ReceiveUpdateCallMediaModeResponse(ImsCallMode::CALL_MODE_AUDIO_ONLY);
318 }
319
SwitchVideoState(ImsCallMode mode)320 void IMSCall::SwitchVideoState(ImsCallMode mode)
321 {
322 // save old state.
323 TELEPHONY_LOGI("SwitchVideoState call %{public}d switch to state %{public}d", GetCallID(), mode);
324 if (videoStateMap_.find(mode) != videoStateMap_.end()) {
325 videoCallState_ = videoStateMap_[mode];
326 } else {
327 videoCallState_ = videoStateMap_[ImsCallMode::CALL_MODE_AUDIO_ONLY];
328 }
329 return;
330 }
331
IsSupportVideoCall()332 bool IMSCall::IsSupportVideoCall()
333 {
334 bool isSupportVideoCall = true;
335 #ifdef ABILITY_CONFIG_SUPPORT
336 isSupportVideoCall = GetCarrierConfig(ITEM_VIDEO_CALL);
337 #endif
338 if (GetTelCallState() == TelCallState::CALL_STATUS_INCOMING) {
339 TELEPHONY_LOGW("incoming call not support video upgrade");
340 isSupportVideoCall = false;
341 }
342 if (GetEmergencyState()) {
343 TELEPHONY_LOGW("emergency call not support video upgrade");
344 isSupportVideoCall = false;
345 }
346 return isSupportVideoCall;
347 }
348
DispatchUpdateVideoRequest(ImsCallMode mode)349 int32_t IMSCall::DispatchUpdateVideoRequest(ImsCallMode mode)
350 {
351 CellularCallInfo callInfo;
352 int32_t ret = PackCellularCallInfo(callInfo);
353 if (ret != TELEPHONY_SUCCESS) {
354 TELEPHONY_LOGW("PackCellularCallInfo failed!");
355 return ret;
356 }
357 ret = DelayedSingleton<CellularCallConnection>::GetInstance()->SendUpdateCallMediaModeRequest(callInfo, mode);
358 if (ret != TELEPHONY_SUCCESS) {
359 TELEPHONY_LOGE("send update media failed, errno:%{public}d!", ret);
360 return ret;
361 }
362 return TELEPHONY_SUCCESS;
363 }
364
DispatchUpdateVideoResponse(ImsCallMode mode)365 int32_t IMSCall::DispatchUpdateVideoResponse(ImsCallMode mode)
366 {
367 return TELEPHONY_SUCCESS;
368 }
369
GetCallVideoState(ImsCallMode mode)370 sptr<VideoCallState> IMSCall::GetCallVideoState(ImsCallMode mode)
371 {
372 TELEPHONY_LOGI("get call video state %{public}d", mode);
373 if (videoStateMap_.find(mode) != videoStateMap_.end()) {
374 return videoStateMap_[mode];
375 } else {
376 return nullptr;
377 }
378 }
379 } // namespace Telephony
380 } // namespace OHOS
381