89650f46b0c3358478274fdb0f8d3909544711e8
[apps/osp/Call.git] / src / CallPresentationModel.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        CallCallPresentationModel.cpp
19  * @brief       Call Presentation model class
20  */
21 #include <FApp.h>
22 #include <FUi.h>
23 #include <FMedia.h>
24 #include "CallApp.h"
25 #include "CallActiveCallForm.h"
26 #include "CallInfo.h"
27 #include "CallPresentationModel.h"
28 #include "CallSettingsPresentationModel.h"
29 #include "CallConfCallerListForm.h"
30 #include "CallTelephonyManager.h"
31 #include "CallSceneRegister.h"
32 #include "CallTypes.h"
33
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Collection;
36 using namespace Tizen::App;
37 using namespace Tizen::Graphics;
38 using namespace Tizen::Media;
39 using namespace Tizen::Social;
40 using namespace Tizen::Ui::Scenes;
41
42 CallPresentationModel* CallPresentationModel::__pInstance = null;
43
44 CallPresentationModel::CallPresentationModel(void)
45 {
46         __pTelephonyMgr = null;
47         __pTelEventListener = null;
48         __pSettingsPresentor = null;
49         __isMessageAppControlRunning = false;
50         __isDialAppControlRunning = false;
51 }
52
53 CallPresentationModel::~CallPresentationModel(void)
54 {
55         __pTelephonyMgr = null;
56         __pSettingsPresentor = null;
57 }
58
59 void
60 CallPresentationModel::CreateInstance(void)
61 {
62         __pInstance = new (std::nothrow) CallPresentationModel();
63         result r = __pInstance->Construct();
64         if(IsFailed(r))
65         {
66                 delete __pInstance;
67                 __pInstance = null;
68                 return;
69         }
70
71         std::atexit(DestroyInstance);
72 }
73
74 CallPresentationModel*
75 CallPresentationModel::GetInstance(void)
76 {
77         if (__pInstance == null)
78         {
79                 CreateInstance();
80         }
81         return __pInstance;
82 }
83
84 void
85 CallPresentationModel::DestroyInstance(void)
86 {
87         if (__pInstance != null)
88         {
89                 delete __pInstance;
90                 __pInstance = null;
91         }
92 }
93
94 result
95 CallPresentationModel::Construct(void)
96 {
97         //Fetch Telephony Manager
98         __pTelephonyMgr = TelephonyManager::GetInstance(this);
99         __pSettingsPresentor = SettingsPresentationModel::GetInstance();
100         return E_SUCCESS;
101 }
102
103 void
104 CallPresentationModel::SetTelEventListener(ITelephonyEventListener* pTelEventListener)
105 {
106         //set form as telephony event listener
107         __pTelEventListener = pTelEventListener;
108 }
109
110 void
111 CallPresentationModel::DialCall(String& contactNumber, bool isEmergency)
112 {
113         int errorCode = ERROR_NONE;
114         //Check if Telephony Manager is initialized
115         TryCatch(__pTelephonyMgr != null, (errorCode = ERROR_TAPI_INIT_FAILED), "TAPI initialization failed");
116
117         //check if phone is in flight mode
118         if(__pSettingsPresentor->GetFlightModeStatus() == true)
119         {
120                 __pTelEventListener->HandleTelephonyError(ERROR_FLIGHT_MODE_SET);
121                 return;
122         }
123         //setup outgoing call
124         errorCode = __pTelephonyMgr->SetupMoCall(contactNumber, isEmergency);
125         TryCatch(errorCode == ERROR_NONE,,"Error occurred while setup MO call");
126         if(__pSettingsPresentor != null)
127         {
128                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
129         }
130         return;
131
132 CATCH:
133         __pTelEventListener->HandleTelephonyError(errorCode);
134 }
135
136 void
137 CallPresentationModel::EndActiveCall(Long callHandle)
138 {
139         if(__pTelephonyMgr != null)
140         {
141                 __pTelephonyMgr->EndActiveCall(callHandle);
142         }
143 }
144
145 void
146 CallPresentationModel::EndDialingCall(String& contactNumber)
147 {
148         if(__pTelephonyMgr != null)
149         {
150                 __pTelephonyMgr->EndDialingCall(contactNumber);
151         }
152 }
153
154 bool
155 CallPresentationModel::EndConferenceCall(void)
156 {
157         result r = __pTelephonyMgr->EndConferenceCall();
158         if (IsFailed(r))
159         {
160                 //TODO: send proper error code
161                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
162                 return false;
163         }
164         return true;
165 }
166
167 void
168 CallPresentationModel::EndAllCall(void)
169 {
170         if(__pTelephonyMgr != null)
171         {
172                 __pTelephonyMgr->EndAllCalls();
173         }
174 }
175 bool
176 CallPresentationModel::HoldCall(Tizen::Base::Long callHandle)
177 {
178         result r = __pTelephonyMgr->HoldCall(callHandle, true);
179         return (!IsFailed(r));
180 }
181
182 bool
183 CallPresentationModel::UnHoldCall(Tizen::Base::Long callHandle)
184 {
185         result r = __pTelephonyMgr->HoldCall(callHandle, false);
186         return (!IsFailed(r));
187 }
188
189 bool
190 CallPresentationModel::HoldConferenceCall(void)
191 {
192         result r = __pTelephonyMgr->HoldConferenceCall(true);
193         return (!IsFailed(r));
194 }
195
196 bool
197 CallPresentationModel::ActivateConferenceCall(void)
198 {
199         result r = __pTelephonyMgr->HoldConferenceCall(false);
200         return (!IsFailed(r));
201 }
202
203 void
204 CallPresentationModel::JoinCall(void)
205 {
206         result r = __pTelephonyMgr->JoinCall();
207         if (IsFailed(r))
208         {
209                 __pTelEventListener->HandleTelephonyError(ERROR_JOIN_FAILED);
210         }
211 }
212
213 void
214 CallPresentationModel::SwapCalls(void)
215 {
216         result r = __pTelephonyMgr->SwapCalls();
217         if (IsFailed(r))
218         {
219                 __pTelEventListener->HandleTelephonyError(ERROR_SWAP_FAILED);
220         }
221 }
222
223 bool
224 CallPresentationModel::SetMuteStatus(bool setMute)
225 {
226         result r = __pTelephonyMgr->SetMuteStatus(setMute);
227         return (!IsFailed(r));
228 }
229
230 bool
231 CallPresentationModel::IsCallMuted(void)
232 {
233         return __pTelephonyMgr->IsCallMuted();
234 }
235
236 bool
237 CallPresentationModel::SetSpeakerStatus(bool setSpeaker)
238 {
239         result r = __pTelephonyMgr->SetSpeakerStatus(setSpeaker);
240         return (!IsFailed(r));
241 }
242
243 bool
244 CallPresentationModel::IsSpeakerOn(void)
245 {
246         return __pTelephonyMgr->IsSpeakerOn();
247 }
248 void
249 CallPresentationModel::SendDTMFSignal(String& textToBeSent)
250 {
251         __pTelephonyMgr->SendCallDTMF(textToBeSent);
252 }
253
254 CallInfo*
255 CallPresentationModel::GetConferenceCallInfoN(void)
256 {
257         return __pTelephonyMgr->GetConferenceCallInfoN();
258 }
259
260 void
261 CallPresentationModel::SplitFromConference(SplitConfCallerCmdIds splitCallerCmdId, IListT<CallInfo>* pConfCallList)
262 {
263         int callIndex = -1;
264         CallInfo callToBeSpli;
265         switch (splitCallerCmdId)
266         {
267         case IDA_SPLIT_CALLER1:
268                 callIndex = 0;
269                 break;
270
271         case IDA_SPLIT_CALLER2:
272                 callIndex = 1;
273                 break;
274
275         case IDA_SPLIT_CALLER3:
276                 callIndex = 2;
277                 break;
278
279         case IDA_SPLIT_CALLER4:
280                 callIndex = 3;
281                 break;
282
283         case IDA_SPLIT_CALLER5:
284                 callIndex = 4;
285                 break;
286
287         default:
288         break;
289         }
290
291         result r = pConfCallList->GetAt(callIndex, callToBeSpli);
292         TryCatch(r == E_SUCCESS,,"conf. call list corrupted");
293         //split single call from conference
294         r = __pTelephonyMgr->SplitFromConference(callToBeSpli.GetCallHandle()->ToLong());
295         TryCatch(r == E_SUCCESS,,"Split from conf. call failed");
296         return;
297
298 CATCH:
299         __pTelEventListener->HandleTelephonyError(ERROR_SPLIT_FROM_CONFERENCE_FAILED);
300         return;
301 }
302
303 void
304 CallPresentationModel::EndCallFromConference(EndConfCallerCmdIds endCallerCmdId, IListT<CallInfo>* pConfCallList)
305 {
306         int callIndex = -1;
307         CallInfo callToBeEnded;
308         switch (endCallerCmdId)
309         {
310         case IDA_END_CALLER1:
311                 callIndex = 0;
312                 break;
313
314         case IDA_END_CALLER2:
315                 callIndex = 1;
316                 break;
317
318         case IDA_END_CALLER3:
319                 callIndex = 2;
320                 break;
321
322         case IDA_END_CALLER4:
323                 callIndex = 3;
324                 break;
325
326         case IDA_END_CALLER5:
327                 callIndex = 4;
328                 break;
329
330         default:
331         break;
332         }
333
334         result r = pConfCallList->GetAt(callIndex, callToBeEnded);
335         TryCatch(r == E_SUCCESS,,"conference call list corrupted");
336         //end single call
337         r = __pTelephonyMgr->EndFromConference(callToBeEnded.GetCallHandle()->ToLong());
338         TryCatch(r == E_SUCCESS,,"End single call from conference call failed");
339
340         return;
341
342 CATCH:
343         __pTelEventListener->HandleTelephonyError(ERROR_END_CALL_FAILED);
344         return;
345 }
346
347 bool
348 CallPresentationModel::IsSplitAllowed(void)
349 {
350         return __pTelephonyMgr->IsSplitAllowed();
351 }
352
353 void
354 CallPresentationModel::AcceptIncomingCall(CallAnsweringOptions answerOptions,int callHandle)
355 {
356         result r = E_FAILURE;
357         if (answerOptions == ANSERWING_OPTION_ACCEPT_CALL)
358         {
359                 r = __pTelephonyMgr->AnswerCall(callHandle, true);
360         }
361         else
362         {
363                 r = __pTelephonyMgr->AcceptCall(answerOptions,callHandle);
364         }
365         if (IsFailed(r))
366         {
367                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
368         }
369 }
370
371 IListT<CallInfo>*
372 CallPresentationModel::GetCallListN(void)
373 {
374         return __pTelephonyMgr->GetCallListN();
375 }
376
377
378 bool
379 CallPresentationModel::RejectCall(int callHandle, bool sendMsg, const String& contactNumber)
380 {
381         result r = __pTelephonyMgr->AnswerCall(callHandle, false);
382         if (IsFailed(r))
383         {
384                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
385                 return false;
386         }
387
388         if (sendMsg == true)
389         {
390                 //launch message
391                 result r = E_SUCCESS;
392                 HashMap extraData;
393                 extraData.Construct();
394
395                 extraData.Add(new (std::nothrow) String(MESSAGE_TYPE), new (std::nothrow) String(MESSAGE_SMS_TYPE));
396                 extraData.Add(new (std::nothrow) String(MESSAGE_TO), new (std::nothrow) String(contactNumber));
397
398                 AppControl* pAc = AppManager::FindAppControlN(PROVIDER_ID_MESSAGE, OPERATION_ID_COMPOSE);
399                 if (pAc != null)
400                 {
401                         r = pAc->Start(null, null, &extraData, this);
402                         __isMessageAppControlRunning = true;
403                         delete pAc;
404                 }
405
406                 extraData.RemoveAll(true);
407         }
408         return true;
409 }
410
411 void
412 CallPresentationModel::OnAppControlCompleteResponseReceived(const AppId& appId, const String& operationId, AppCtrlResult appControlResult, const IMap* pExtraData)
413 {
414         if (__isMessageAppControlRunning == true)
415         {
416                 //This comes here, when Message AppControl is finished working.
417                 __isMessageAppControlRunning = false;
418                 //Check if this was the last call, then terminate application.
419                 //And if any calls are active, then those cases are already handled from Other places.
420                 if( GetCurrentCallCount() == 0)
421                 {
422                         CallApp* pPhoneApp = static_cast<CallApp*>(UiApp::GetInstance());
423                         pPhoneApp->Terminate();
424                 }
425         }
426         if(appId.Equals(PROVIDER_ID_PHONE,false) == true &&  operationId.Equals(OPERATION_ID_DIAL,false) == true)
427         {
428                 __isDialAppControlRunning = false;
429
430                 if(appControlResult == APP_CTRL_RESULT_SUCCEEDED)
431                 {
432                         String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
433                         if (pExtraData->ContainsKey(*pKey) == true)
434                         {
435                                 const String* pPhoneNumber = static_cast<const String*>(pExtraData->GetValue(*pKey));
436                                 if(pPhoneNumber != null && pPhoneNumber->IsEmpty() == false)
437                                 {
438                                         AddCall(*pPhoneNumber);
439                                 }
440
441                         }
442
443                 }
444
445         }
446 }
447
448 void
449 CallPresentationModel::AddCall(const String& phoneNumber)
450 {
451         ArrayList* pLaunchArgs = null;
452         SceneManager* pSceneManager = SceneManager::GetInstance();
453         int currentActiveCallCount = GetCurrentCallCount();
454         if(currentActiveCallCount <= 1)
455         {
456                 //make an outgoing call with given number
457                 String* contactTxt = new (std::nothrow) String(phoneNumber);
458                 pLaunchArgs =  new (std::nothrow) ArrayList(SingleObjectDeleter);
459                 pLaunchArgs->Construct();
460                 pLaunchArgs->Add(contactTxt);
461                 bool isEmergencyCall = IsEmergencyNumber(*contactTxt, true);
462
463                 SceneId nextScene = IDSCN_SCENE_OUTCALL;
464                 if (isEmergencyCall)
465                 {
466                         nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
467                 }
468                 pSceneManager->GoForward( ForwardSceneTransition( nextScene), pLaunchArgs);
469
470         }
471 }
472
473 int
474 CallPresentationModel::GetCurrentCallCount(void)
475 {
476         return __pTelephonyMgr->GetCurrentCallCount();
477 }
478
479 bool
480 CallPresentationModel::CheckSimInitializationIsCompleted()
481 {
482         result r = E_FAILURE;
483         if(__pTelephonyMgr != null)
484         {
485                 r = __pTelephonyMgr->CheckIfMOCallIsPossible();
486         }
487         return (!IsFailed(r));
488 }
489
490 bool
491 CallPresentationModel::IsEmergencyNumber(const Tizen::Base::String& phoneNumber, bool isSimInitialized)
492 {
493         return __pTelephonyMgr->CheckIfMOCallIsEmergency(phoneNumber, isSimInitialized);
494 }
495
496 void
497 CallPresentationModel::StartAlert(CallInfo& incomingCallInfo)
498 {
499         //Adding incoming call sate setting here
500         if(__pSettingsPresentor != null)
501         {
502                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
503         }
504         __pTelephonyMgr->StartAlert(incomingCallInfo);
505 }
506
507 void
508 CallPresentationModel::StopAlert(void)
509 {
510         __pTelephonyMgr->StopAlert();
511 }
512
513 Contact*
514 CallPresentationModel::GetContactN(const String& phoneNumber)
515 {
516         return __pTelephonyMgr->GetContactN(phoneNumber);
517 }
518
519 CallInfo*
520 CallPresentationModel::FetchIncomingCallDetailsN(const String& callHandle, const String& contactNumber)
521 {
522
523         return __pTelephonyMgr->FetchIncomingCallHandleN(callHandle, contactNumber);
524 }
525
526 bool
527 CallPresentationModel::CheckIncomingCallToBeRejected(CallInfo* pIncomingCallInfo)
528 {
529         return __pTelephonyMgr->CheckIncomingCallToBeRejected(pIncomingCallInfo);
530 }
531
532 /////////////////////////////////////////////////////////////////
533 /////  Event Listener methods from ITelephonyEventListener  /////
534 /////////////////////////////////////////////////////////////////
535 void
536 CallPresentationModel::HandleCallConnected(Tizen::Base::Collection::IListT<CallInfo>& pCallList)
537 {
538         if (__pTelEventListener != null)
539         {
540                 __pTelEventListener->HandleCallConnected(pCallList);
541         }
542         if(__pSettingsPresentor != null)
543         {
544                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_ACTIVE);
545         }
546 }
547
548 void
549 CallPresentationModel::HandleCallDisconnected(bool isLastCall, Tizen::Base::Collection::IListT<CallInfo>& pCallList)
550 {
551         if (isLastCall == true)
552         {
553                 SetSpeakerStatus(false);
554                 SetMuteStatus(false);
555                 if(__pSettingsPresentor != null)
556                 {
557                         __pSettingsPresentor->SetCallState(CALL_STATE_CALL_OFF);
558                 }
559         }
560         else
561         {
562                 if(__pSettingsPresentor != null)
563                 {
564                         __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_ACTIVE);
565                 }
566         }
567         //Defer from sending call disconnected event to form, in case Msg AppControl is running,
568         //to avoid PhoneApp from going to EndCall form, where it shows for 3 sec. and automatically closes.
569         if (__pTelEventListener != null && __isMessageAppControlRunning == false)
570         {
571                 __pTelEventListener->HandleCallDisconnected(isLastCall, pCallList);
572         }
573
574 }
575
576 void
577 CallPresentationModel::HandleConferenceCall(CallInfo& pCallInfo)
578 {
579         if (__pTelEventListener != null)
580         {
581                 __pTelEventListener->HandleConferenceCall(pCallInfo);
582         }
583 }
584
585 void
586 CallPresentationModel::HandleIncomingCall(CallInfo& pCallInfo)
587 {
588         AppLogDebug("Error - This will never come here. Since, now we are getting incoming call event through AppControl!!");
589 }
590
591 void
592 CallPresentationModel::HandleCallSwapOccured(Tizen::Base::Collection::IListT<CallInfo>& pCallList)
593 {
594         if (__pTelEventListener != null)
595         {
596                 __pTelEventListener->HandleCallSwapOccured(pCallList);
597         }
598 }
599
600 void
601 CallPresentationModel::HandleConferenceChange(void)
602 {
603         if (__pTelEventListener != null)
604         {
605                 __pTelEventListener->HandleConferenceChange();
606         }
607 }
608
609 void
610 CallPresentationModel::HandleTelephonyError(int errorCode)
611 {
612         if (__pTelEventListener != null)
613         {
614                 __pTelEventListener->HandleTelephonyError(errorCode);
615         }
616 }
617
618
619 result
620 CallPresentationModel::LaunchDialAppControl()
621 {
622         result r = E_SUCCESS;
623         AppControl* pAppControl = null;
624
625         if(__isDialAppControlRunning == true)
626         {
627                 //Do not allow another app control if already running
628                 return r;
629         }
630
631         HashMap extraData;
632         extraData.Construct();
633         extraData.Add(new (std::nothrow) String(PARAM_PHONE_NUMBER), new (std::nothrow) String(L""));
634
635         pAppControl = AppManager::FindAppControlN(PROVIDER_ID_PHONE, OPERATION_ID_DIAL);
636         if (pAppControl != null)
637         {
638                 r = pAppControl->Start(null, null, &extraData, this);
639                 __isDialAppControlRunning = true;
640         }
641
642         extraData.RemoveAll(true);
643
644         return r;
645
646
647 }