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