Tizen 2.0 Release
[apps/osp/Phone.git] / src / PhnCallPresentationModel.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        PhnCallPresentationModel.cpp
19  * @brief       Call Presentation model class
20  */
21 #include <FApp.h>
22 #include <FUi.h>
23 #include <FMedia.h>
24 #include "PhnPhoneApp.h"
25 #include "PhnActiveCallForm.h"
26 #include "PhnCallInfo.h"
27 #include "PhnCallPresentationModel.h"
28 #include "PhnSettingsPresentationModel.h"
29 #include "PhnConfCallerListForm.h"
30 #include "PhnTelephonyManager.h"
31 #include "PhnSceneRegister.h"
32 #include "PhnTypes.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 }
51
52 CallPresentationModel::~CallPresentationModel(void)
53 {
54         __pTelephonyMgr = null;
55         __pSettingsPresentor = null;
56 }
57
58 void
59 CallPresentationModel::CreateInstance(void)
60 {
61         __pInstance = new (std::nothrow) CallPresentationModel();
62         result r = __pInstance->Construct();
63         if(IsFailed(r))
64         {
65                 delete __pInstance;
66                 __pInstance = null;
67                 return;
68         }
69
70         std::atexit(DestroyInstance);
71 }
72
73 CallPresentationModel*
74 CallPresentationModel::GetInstance(void)
75 {
76         if (__pInstance == null)
77         {
78                 CreateInstance();
79         }
80         return __pInstance;
81 }
82
83 void
84 CallPresentationModel::DestroyInstance(void)
85 {
86         if (__pInstance != null)
87         {
88                 delete __pInstance;
89                 __pInstance = null;
90         }
91 }
92
93 result
94 CallPresentationModel::Construct(void)
95 {
96         //Fetch Telephony Manager
97         __pTelephonyMgr = TelephonyManager::GetInstance(this);
98         __pSettingsPresentor = SettingsPresentationModel::GetInstance();
99         return E_SUCCESS;
100 }
101
102 void
103 CallPresentationModel::SetTelEventListener(ITelephonyEventListener* pTelEventListener)
104 {
105         //set form as telephony event listener
106         __pTelEventListener = pTelEventListener;
107 }
108
109 void
110 CallPresentationModel::DialCall(String& contactNumber, bool isEmergency)
111 {
112         int errorCode = ERROR_NONE;
113         //Check if Telephony Manager is initialized
114         TryCatch(__pTelephonyMgr != null, (errorCode = ERROR_TAPI_INIT_FAILED), "TAPI initialization failed");
115
116         //check if phone is in flight mode
117         if(__pSettingsPresentor->GetFlightModeStatus() == true)
118         {
119                 __pTelEventListener->HandleTelephonyError(ERROR_FLIGHT_MODE_SET);
120                 return;
121         }
122         //setup outgoing call
123         errorCode = __pTelephonyMgr->SetupMoCall(contactNumber, isEmergency);
124         TryCatch(errorCode == ERROR_NONE,,"Error occurred while setup MO call");
125         if(__pSettingsPresentor != null)
126         {
127                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
128         }
129         return;
130
131 CATCH:
132         __pTelEventListener->HandleTelephonyError(errorCode);
133 }
134
135 void
136 CallPresentationModel::EndCall(Long callHandle)
137 {
138         if(__pTelephonyMgr != null)
139         {
140                 __pTelephonyMgr->EndCall(callHandle);
141         }
142 }
143
144 void
145 CallPresentationModel::EndCall(String& contactNumber)
146 {
147         if(__pTelephonyMgr != null)
148         {
149                 __pTelephonyMgr->EndCall(contactNumber);
150         }
151 }
152
153 bool
154 CallPresentationModel::EndConferenceCall(void)
155 {
156         result r = __pTelephonyMgr->EndConferenceCall();
157         if (IsFailed(r))
158         {
159                 //TODO: send proper error code
160                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
161                 return false;
162         }
163         return true;
164 }
165
166 void
167 CallPresentationModel::EndAllCall(void)
168 {
169         if(__pTelephonyMgr != null)
170         {
171                 __pTelephonyMgr->EndAllCalls();
172         }
173 }
174 bool
175 CallPresentationModel::HoldCall(Tizen::Base::Long callHandle)
176 {
177         result r = __pTelephonyMgr->HoldCall(callHandle, true);
178         return (!IsFailed(r));
179 }
180
181 bool
182 CallPresentationModel::UnHoldCall(Tizen::Base::Long callHandle)
183 {
184         result r = __pTelephonyMgr->HoldCall(callHandle, false);
185         return (!IsFailed(r));
186 }
187
188 bool
189 CallPresentationModel::HoldConferenceCall(void)
190 {
191         result r = __pTelephonyMgr->HoldConferenceCall(true);
192         return (!IsFailed(r));
193 }
194
195 bool
196 CallPresentationModel::ActivateConferenceCall(void)
197 {
198         result r = __pTelephonyMgr->HoldConferenceCall(false);
199         return (!IsFailed(r));
200 }
201
202 void
203 CallPresentationModel::JoinCall(void)
204 {
205         result r = __pTelephonyMgr->JoinCall();
206         if (IsFailed(r))
207         {
208                 __pTelEventListener->HandleTelephonyError(ERROR_JOIN_FAILED);
209         }
210 }
211
212 void
213 CallPresentationModel::SwapCalls(void)
214 {
215         result r = __pTelephonyMgr->SwapCalls();
216         if (IsFailed(r))
217         {
218                 __pTelEventListener->HandleTelephonyError(ERROR_SWAP_FAILED);
219         }
220 }
221
222 bool
223 CallPresentationModel::SetMuteStatus(bool setMute)
224 {
225         result r = __pTelephonyMgr->SetMuteStatus(setMute);
226         return (!IsFailed(r));
227 }
228
229 bool
230 CallPresentationModel::IsCallMuted(void)
231 {
232         return __pTelephonyMgr->IsCallMuted();
233 }
234
235 bool
236 CallPresentationModel::SetSpeakerStatus(bool setSpeaker)
237 {
238         result r = __pTelephonyMgr->SetSpeakerStatus(setSpeaker);
239         return (!IsFailed(r));
240 }
241
242 bool
243 CallPresentationModel::IsSpeakerOn(void)
244 {
245         return __pTelephonyMgr->IsSpeakerOn();
246 }
247 void
248 CallPresentationModel::SendDTMFSignal(String& textToBeSent)
249 {
250         __pTelephonyMgr->SendCallDTMF(textToBeSent);
251 }
252
253 CallInfo*
254 CallPresentationModel::GetConferenceCallInfoN(void)
255 {
256         return __pTelephonyMgr->GetConferenceCallInfoN();
257 }
258
259 void
260 CallPresentationModel::SplitFromConference(SplitConfCallerCmdIds splitCallerCmdId, IListT<CallInfo>* pConfCallList)
261 {
262         int callIndex = -1;
263         CallInfo callToBeSpli;
264         switch (splitCallerCmdId)
265         {
266         case IDA_SPLIT_CALLER1:
267                 callIndex = 0;
268                 break;
269
270         case IDA_SPLIT_CALLER2:
271                 callIndex = 1;
272                 break;
273
274         case IDA_SPLIT_CALLER3:
275                 callIndex = 2;
276                 break;
277
278         case IDA_SPLIT_CALLER4:
279                 callIndex = 3;
280                 break;
281
282         case IDA_SPLIT_CALLER5:
283                 callIndex = 4;
284                 break;
285
286         default:
287         break;
288         }
289
290         result r = pConfCallList->GetAt(callIndex, callToBeSpli);
291         TryCatch(r == E_SUCCESS,,"conf. call list corrupted");
292         //split single call from conference
293         r = __pTelephonyMgr->SplitFromConference(callToBeSpli.GetCallHandle()->ToLong());
294         TryCatch(r == E_SUCCESS,,"Split from conf. call failed");
295         return;
296
297 CATCH:
298         __pTelEventListener->HandleTelephonyError(ERROR_SPLIT_FROM_CONFERENCE_FAILED);
299         return;
300 }
301
302 void
303 CallPresentationModel::EndCallFromConference(EndConfCallerCmdIds endCallerCmdId, IListT<CallInfo>* pConfCallList)
304 {
305         int callIndex = -1;
306         CallInfo callToBeEnded;
307         switch (endCallerCmdId)
308         {
309         case IDA_END_CALLER1:
310                 callIndex = 0;
311                 break;
312
313         case IDA_END_CALLER2:
314                 callIndex = 1;
315                 break;
316
317         case IDA_END_CALLER3:
318                 callIndex = 2;
319                 break;
320
321         case IDA_END_CALLER4:
322                 callIndex = 3;
323                 break;
324
325         case IDA_END_CALLER5:
326                 callIndex = 4;
327                 break;
328
329         default:
330         break;
331         }
332
333         result r = pConfCallList->GetAt(callIndex, callToBeEnded);
334         TryCatch(r == E_SUCCESS,,"conference call list corrupted");
335         //end single call
336         r = __pTelephonyMgr->EndFromConference(callToBeEnded.GetCallHandle()->ToLong());
337         TryCatch(r == E_SUCCESS,,"End single call from conference call failed");
338
339         return;
340
341 CATCH:
342         __pTelEventListener->HandleTelephonyError(ERROR_END_CALL_FAILED);
343         return;
344 }
345
346 bool
347 CallPresentationModel::IsSplitAllowed(void)
348 {
349         return __pTelephonyMgr->IsSplitAllowed();
350 }
351
352 void
353 CallPresentationModel::AcceptIncomingCall(CallAnswerOptions answerOptions,int callHandle)
354 {
355         result r = E_FAILURE;
356         if (answerOptions == CALL_ANSWER_CALL)
357         {
358                 r = __pTelephonyMgr->AnswerCall(callHandle, true);
359         }
360         else
361         {
362                 r = __pTelephonyMgr->AcceptCall(answerOptions,callHandle);
363         }
364         if (IsFailed(r))
365         {
366                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
367         }
368 }
369
370 IListT<CallInfo>*
371 CallPresentationModel::GetCallListN(void)
372 {
373         return __pTelephonyMgr->GetCallListN();
374 }
375
376
377 bool
378 CallPresentationModel::RejectCall(int callHandle, bool sendMsg, const String& contactNumber)
379 {
380         result r = __pTelephonyMgr->AnswerCall(callHandle, false);
381         if (IsFailed(r))
382         {
383                 __pTelEventListener->HandleTelephonyError(ERROR_GENERAL);
384                 return false;
385         }
386
387         if (sendMsg == true)
388         {
389                 //launch message
390                 result r = E_SUCCESS;
391                 HashMap extraData;
392                 extraData.Construct();
393
394                 extraData.Add(new (std::nothrow) String(MESSAGE_TYPE), new (std::nothrow) String(MESSAGE_SMS_TYPE));
395                 extraData.Add(new (std::nothrow) String(MESSAGE_TO), new (std::nothrow) String(contactNumber));
396
397                 AppControl* pAc = AppManager::FindAppControlN(PROVIDER_ID_MESSAGE, OPERATION_ID_COMPOSE);
398                 if (pAc != null)
399                 {
400                         r = pAc->Start(null, null, &extraData, this);
401                         __isMessageAppControlRunning = true;
402                         delete pAc;
403                 }
404
405                 extraData.RemoveAll(true);
406         }
407         return true;
408 }
409
410 void
411 CallPresentationModel::OnAppControlCompleteResponseReceived(const AppId& appId, const String& operationId, AppCtrlResult appControlResult, const IMap* pExtraData)
412 {
413         if (__isMessageAppControlRunning == true)
414         {
415                 //This comes here, when Message AppControl is finished working.
416                 __isMessageAppControlRunning = false;
417                 //Check if this was the last call, then terminate application.
418                 //And if any calls are active, then those cases are already handled from Other places.
419                 if( GetCurrentCallCount() == 0)
420                 {
421                         PhoneApp* pPhoneApp = static_cast<PhoneApp*>(UiApp::GetInstance());
422                         SceneManager* pSceneManager = SceneManager::GetInstance();
423                         SceneId startingScene = pPhoneApp->GetInitialScene();
424                         //No more calls are active
425                         if (startingScene == IDSCN_DIALER || startingScene == IDSCN_CALL_LOG)
426                         {
427                                 pSceneManager->GoForward( ForwardSceneTransition(startingScene, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
428                                         SCENE_HISTORY_OPTION_NO_HISTORY));
429                         }
430                         else
431                         {
432                                 pPhoneApp->Terminate();
433                         }
434                 }
435         }
436 }
437
438 int
439 CallPresentationModel::GetCurrentCallCount(void)
440 {
441         return __pTelephonyMgr->GetCurrentCallCount();
442 }
443
444 bool
445 CallPresentationModel::CheckSimInitializationIsCompleted()
446 {
447         result r = E_FAILURE;
448         if(__pTelephonyMgr != null)
449         {
450                 r = __pTelephonyMgr->CheckIfMOCallIsPossible();
451         }
452         return (!IsFailed(r));
453 }
454
455 bool
456 CallPresentationModel::IsEmergencyNumber(const Tizen::Base::String& phoneNumber, bool isSimInitialized)
457 {
458         return __pTelephonyMgr->CheckIfMOCallIsEmergency(phoneNumber, isSimInitialized);
459 }
460
461 void
462 CallPresentationModel::StartAlert(CallInfo& incomingCallInfo)
463 {
464         __pTelephonyMgr->StartAlert(incomingCallInfo);
465 }
466
467 void
468 CallPresentationModel::StopAlert(void)
469 {
470         __pTelephonyMgr->StopAlert();
471 }
472
473 Contact*
474 CallPresentationModel::GetContactN(const String& phoneNumber)
475 {
476         return __pTelephonyMgr->GetContactN(phoneNumber);
477 }
478
479 CallInfo*
480 CallPresentationModel::FetchIncomingCallDetailsN(const String& callHandle, const String& contactNumber)
481 {
482         //Adding incoming call sate setting here
483         if(__pSettingsPresentor != null)
484         {
485                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
486         }
487         return __pTelephonyMgr->FetchIncomingCallHandleN(callHandle, contactNumber);
488 }
489
490 bool
491 CallPresentationModel::CheckIncomingCallToBeRejected(CallInfo* pIncomingCallInfo)
492 {
493         return __pTelephonyMgr->CheckIncomingCallToBeRejected(pIncomingCallInfo);
494 }
495
496 /////////////////////////////////////////////////////////////////
497 /////  Event Listener methods from ITelephonyEventListener  /////
498 /////////////////////////////////////////////////////////////////
499 void
500 CallPresentationModel::HandleCallConnected(Tizen::Base::Collection::IListT<CallInfo>& pCallList)
501 {
502         if (__pTelEventListener != null)
503         {
504                 __pTelEventListener->HandleCallConnected(pCallList);
505         }
506         if(__pSettingsPresentor != null)
507         {
508                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_ACTIVE);
509         }
510 }
511
512 void
513 CallPresentationModel::HandleCallDisconnected(bool isLastCall, Tizen::Base::Collection::IListT<CallInfo>& pCallList)
514 {
515         if (isLastCall == true)
516         {
517                 SetSpeakerStatus(false);
518                 SetMuteStatus(false);
519                 if(__pSettingsPresentor != null)
520                 {
521                         __pSettingsPresentor->SetCallState(CALL_STATE__CALL_OFF);
522                 }
523         }
524         //Defer from sending call disconnected event to form, in case Msg AppControl is running,
525         //to avoid PhoneApp from going to EndCall form, where it shows for 3 sec. and automatically closes.
526         if (__pTelEventListener != null && __isMessageAppControlRunning == false)
527         {
528                 __pTelEventListener->HandleCallDisconnected(isLastCall, pCallList);
529         }
530
531 }
532
533 void
534 CallPresentationModel::HandleConferenceCall(CallInfo& pCallInfo)
535 {
536         if (__pTelEventListener != null)
537         {
538                 __pTelEventListener->HandleConferenceCall(pCallInfo);
539         }
540 }
541
542 void
543 CallPresentationModel::HandleIncomingCall(CallInfo& pCallInfo)
544 {
545         StartAlert(pCallInfo);
546         if (__pTelEventListener != null)
547         {
548                 __pTelEventListener->HandleIncomingCall(pCallInfo);
549         }
550         else
551         {
552                 //as base form not created. So no listener set.
553                 SceneManager* pSceneManager = SceneManager::GetInstance();
554
555                 //Ownership - To be deleted in 'OnSceneActivatedN' of next form
556                 ArrayList* pCallInfoList = new (std::nothrow) ArrayList(SingleObjectDeleter);
557                 pCallInfoList->Construct(1);
558
559                 //update list to be passed
560                 CallInfo* pIncomingCall = new (std::nothrow) CallInfo();
561                 *pIncomingCall = pCallInfo;
562                 pCallInfoList->Add(pIncomingCall);
563
564                 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), pCallInfoList);
565         }
566         if(__pSettingsPresentor != null)
567         {
568                 __pSettingsPresentor->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
569         }
570 }
571
572 void
573 CallPresentationModel::HandleCallSwapOccured(Tizen::Base::Collection::IListT<CallInfo>& pCallList)
574 {
575         if (__pTelEventListener != null)
576         {
577                 __pTelEventListener->HandleCallSwapOccured(pCallList);
578         }
579 }
580
581 void
582 CallPresentationModel::HandleConferenceChange(void)
583 {
584         if (__pTelEventListener != null)
585         {
586                 __pTelEventListener->HandleConferenceChange();
587         }
588 }
589
590 void
591 CallPresentationModel::HandleTelephonyError(int errorCode)
592 {
593         if (__pTelEventListener != null)
594         {
595                 __pTelEventListener->HandleTelephonyError(errorCode);
596         }
597 }
598