Fix for 44593 42495
[apps/osp/Call.git] / src / CallTelephonyManager.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.1 (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        CallTelephonyManager.cpp
19  * @brief       Call log item provider
20  */
21 #include <stdio.h>
22 #include <FBaseSys.h>
23 #include <FSystem.h>
24 #include <FTelephony.h>
25 #include "ITapiModem.h"
26 #include "ITapiSim.h"
27 #include "CallInfo.h"
28 #include "CallTelephonyManager.h"
29 #include "CallSettingsManager.h"
30 #include "CallTypes.h"
31
32 using namespace Tizen::Base;
33 using namespace Tizen::Graphics;
34 using namespace Tizen::Social;
35 using namespace Tizen::System;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Telephony;
38 using namespace Tizen::Base::Utility;
39
40 const char* callEventList[] = {
41                 TAPI_NOTI_VOICE_CALL_STATUS_IDLE,
42                 TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE,
43                 TAPI_NOTI_VOICE_CALL_STATUS_HELD,
44                 TAPI_NOTI_VOICE_CALL_STATUS_DIALING,
45                 TAPI_NOTI_VOICE_CALL_STATUS_ALERT,
46                 TAPI_NOTI_VOICE_CALL_STATUS_WAITING,
47                 TAPI_NOTI_CALL_INFO_CALL_CONNECTED_LINE,
48                 TAPI_NOTI_CALL_INFO_WAITING,
49                 TAPI_NOTI_CALL_INFO_CUG,
50                 TAPI_NOTI_CALL_INFO_FORWARDED,
51                 TAPI_NOTI_CALL_INFO_BARRED_INCOMING,
52                 TAPI_NOTI_CALL_INFO_BARRED_OUTGOING,
53                 TAPI_NOTI_CALL_INFO_DEFLECTED,
54                 TAPI_NOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
55                 TAPI_NOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
56                 TAPI_NOTI_CALL_INFO_FORWARD_CONDITIONAL,
57                 TAPI_NOTI_CALL_INFO_CALL_LINE_IDENTITY,
58                 TAPI_NOTI_CALL_INFO_CALL_NAME_INFORMATION,
59                 TAPI_NOTI_CALL_INFO_FORWARDED_CALL,
60                 TAPI_NOTI_CALL_INFO_CUG_CALL,
61                 TAPI_NOTI_CALL_INFO_DEFLECTED_CALL,
62                 TAPI_NOTI_CALL_INFO_TRANSFERED_CALL,
63                 TAPI_NOTI_CALL_INFO_HELD,
64                 TAPI_NOTI_CALL_INFO_ACTIVE,
65                 TAPI_NOTI_CALL_INFO_JOINED,
66                 TAPI_NOTI_CALL_INFO_RELEASED_ON_HOLD,
67                 TAPI_NOTI_CALL_INFO_TRANSFER_ALERT,
68                 TAPI_NOTI_CALL_INFO_TRANSFERED,
69                 TAPI_NOTI_CALL_INFO_CF_CHECK_MESSAGE,
70 };
71
72 TelephonyManager* TelephonyManager::__pManager = null;
73
74 TelephonyManager::TelephonyManager(ITelephonyEventListener* pEventListener)
75 : __pEventListener(pEventListener)
76 {
77         __pDialedCall = null;
78         __pIncomingCall = null;
79         __pActiveCallList = null;
80         __pSettingsManager = null;
81         __pTapiHandle = null;
82         __pAddressBook = null;
83         __pCachedContact = null;
84         __isMuted = false;
85         __isSpeakerOn = false;
86         __pSoundManager = null;
87         __pCalllogMgr = null;
88         __pNetworkManager = null;
89 }
90
91 TelephonyManager::~TelephonyManager(void)
92 {
93         if (__pActiveCallList != null)
94         {
95                 delete __pActiveCallList;
96         }
97
98         if (__pDialedCall != null)
99         {
100                 delete __pDialedCall;
101                 __pDialedCall = null;
102         }
103
104         if (__pIncomingCall != null)
105         {
106                 delete __pIncomingCall;
107                 __pIncomingCall = null;
108         }
109
110         if (__pAddressBook != null)
111         {
112                 delete __pAddressBook;
113                 __pAddressBook = null;
114         }
115         if (__pCachedContact != null)
116         {
117                 delete __pCachedContact;
118                 __pCachedContact = null;
119         }
120
121         //unregister for events from TAPI Lib.
122         UnregisterEvents();
123
124         //De-initialize the TAPI Library
125         if(__pTapiHandle != null)
126         {
127                 tel_deinit(__pTapiHandle);
128         }
129
130         if (__pSoundManager != null)
131         {
132                 delete __pSoundManager;
133         }
134
135         if (__pCalllogMgr != null)
136         {
137                 __pCalllogMgr = null;
138         }
139 }
140
141 TelephonyManager*
142 TelephonyManager::GetInstance(ITelephonyEventListener* pEventListener)
143 {
144         if (__pManager == null)
145         {
146                 CreateInstance(pEventListener);
147         }
148         return __pManager;
149 }
150
151 void
152 TelephonyManager::CreateInstance(ITelephonyEventListener* pEventListener)
153 {
154         __pManager = new (std::nothrow) TelephonyManager(pEventListener);
155         result r = __pManager->Initialize();
156         if (IsFailed(r))
157         {
158                 delete __pManager;
159                 __pManager = null;
160         }
161         atexit(&(TelephonyManager::DestroyInstance));
162 }
163
164 void
165 TelephonyManager::DestroyInstance(void)
166 {
167         if (__pManager != null)
168         {
169                 __pManager->EndAllCalls();
170                 delete __pManager;
171                 __pManager = null;
172         }
173 }
174
175 result
176 TelephonyManager::Initialize(void)
177 {
178         //Initialize telephony library
179         result r = InitializeTelephonyLibrary();
180         if (IsFailed(r))
181         {
182                 return r;
183         }
184         __pActiveCallList = new (std::nothrow) HashMapT<long, AppCallInfo>();
185         __pActiveCallList->Construct(IDI_MAX_ACTIVE_CALLS);
186
187         //Initialize the Settings Manager to fetch call settings
188         __pSettingsManager = SettingsManager::GetInstance();
189
190         __pSoundManager = new (std::nothrow) SoundManager();
191         __pCalllogMgr = CallLogManager::GetInstance();
192
193         //initialize address book to fetch contacts information
194         __pAddressBook = AddressbookManager::GetInstance()->GetAddressbookN();
195         if(__pAddressBook == null)
196         {
197                 return E_FAILURE;
198         }
199         __pNetworkManager = new NetworkManager();
200         if(__pNetworkManager != null)
201         {
202                 __pNetworkManager->Construct(this);
203         }
204         return r;
205 }
206
207 result
208 TelephonyManager::InitializeTelephonyLibrary(void)
209 {
210         result r = E_FAILURE;
211
212         __pTapiHandle = tel_init(null);
213         if (__pTapiHandle != null)
214         {
215                 //register telephony events
216                 int errorCode = RegisterEvents();
217                 if (errorCode == TAPI_CAUSE_SUCCESS)
218                 {
219                         r = E_SUCCESS;
220                 }
221         }
222         //TAPI Library is initialized and events registered successfully
223         return r;
224 }
225
226 int
227 TelephonyManager::RegisterEvents(void)
228 {
229         int errCode = -1;
230         int eventCount = sizeof(callEventList) / sizeof(char *);
231         for (int index = 0; index < eventCount; index++)
232         {
233                 errCode = tel_register_noti_event(__pTapiHandle, callEventList[index], &HandleCallback, this);
234                 if (errCode != TAPI_API_SUCCESS)
235                 {
236                         return errCode;
237                 }
238         }
239         return errCode;
240 }
241
242 void
243 TelephonyManager::UnregisterEvents(void)
244 {
245         int eventCount = sizeof(callEventList) / sizeof(char *);
246         for (int index = 0; index < eventCount; index++)
247         {
248                 tel_deregister_noti_event(__pTapiHandle, callEventList[index]);
249         }
250 }
251
252 ErrorCodes
253 TelephonyManager::SetupMoCall(String& contactNumber, bool isEmergency)
254 {
255         result res = E_SUCCESS;
256         //check if valid phone number exist
257         res = CheckValidTelePhoneNumber(contactNumber);
258         if (IsFailed(res))
259         {
260                 return ERROR_INVALID_NUMBER;
261         }
262
263         //if dialing an emergency call and active calls exist
264         //then end all active calls.
265         if (isEmergency && __pActiveCallList->GetCount() > 0)
266         {
267                 //Get first call handle
268                 AppCallInfo endCallInfo;
269                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
270                 pCallList->GetAt(0, endCallInfo);
271                 int callHandle = endCallInfo.GetCallHandle()->ToLong();
272                 delete pCallList;
273                 pCallList = null;
274
275                 //release all active or held calls
276                 int tapiRes = tel_end_call(__pTapiHandle, callHandle, TAPI_CALL_END_ALL, &HandleCallbackResponse, this);
277                 if (tapiRes == TAPI_CAUSE_SUCCESS)
278                 {
279                         __pActiveCallList->RemoveAll();
280                         res = E_SUCCESS;
281                 }
282                 else
283                 {
284                         res = E_FAILURE;
285                 }
286         }
287         else if (__pActiveCallList->GetCount() == 1)
288         {
289                 //Check if there is already an active call,
290                 //Put the already active call on hold.
291                 AppCallInfo holdCallInfo;
292                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
293
294                 pCallList->GetAt(0, holdCallInfo);
295                 //Check if call is active, then put on hold
296                 if (holdCallInfo.IsOnHold() == false)
297                 {
298                         res = HoldActiveCall(&holdCallInfo, true);
299                 }
300                 delete pCallList;
301                 pCallList = null;
302         }
303
304         //make the next call, only if any existing active call
305         //is successfully put on hold or is already on hold.
306         if (res == E_SUCCESS)
307         {
308                 res = DialOutgoingCall(contactNumber, isEmergency);
309         }
310
311         if(res == E_SUCCESS)
312         {
313                 return ERROR_NONE;
314         }
315         else
316         {
317                 return ERROR_TAPI_ERROR;
318         }
319 }
320
321 void
322 TelephonyManager::EndAllCalls(void)
323 {
324         if(__pDialedCall != null)
325         {
326                 if(__pDialedCall->GetCallHandle() != null)
327                 {
328                         tel_end_call(__pTapiHandle, __pDialedCall->GetCallHandle()->ToLong(), TAPI_CALL_END, &HandleCallbackResponse, this);
329                 }
330         }
331         tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_HOLD_ALL, &HandleCallbackResponse, this);
332         //end all active calls before terminating application
333         tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_ALL, &HandleCallbackResponse, this);
334         __pSettingsManager->SetCallState(CALL_STATE_CALL_OFF);
335 }
336
337 result
338 TelephonyManager::EndActiveCall(Long callHandle)
339 {
340         result r = E_FAILURE;
341         //fetch ended callInfo from active call list
342         AppCallInfo endCall;
343         r = __pActiveCallList->GetValue(callHandle.ToLong(), endCall);
344         if (r == E_SUCCESS)
345         {
346                 r = EndCall(endCall);
347         }
348
349         return r;
350 }
351
352 result
353 TelephonyManager::EndDialingCall(String& contactNumber)
354 {
355         result r = E_FAILURE;
356         //This is because for a dialing call, call handle is updated with some delay in telephony manager.
357         //And it is not available with outgoing call screen.
358         if (contactNumber.IsEmpty())
359         {
360                 return r;
361         }
362
363         //Check If Ended call matches Dialed Call.
364         AppCallInfo endCall;
365         if (__pDialedCall != null && __pDialedCall->GetContactNumber().Equals(contactNumber))
366         {
367                 endCall = *__pDialedCall;
368                 r = EndCall(endCall);
369         }
370         return r;
371 }
372
373 result
374 TelephonyManager::EndCall(AppCallInfo& endCallInfo)
375 {
376         result r = E_FAILURE;
377
378         if (endCallInfo.GetCallHandle() != null)
379         {
380                 unsigned int callHandle = endCallInfo.GetCallHandle()->ToLong();
381                 //end "dialed but unconnected" call or active call - processing to be handled in HandleIdleCallback().
382                 int res = tel_end_call(__pTapiHandle, callHandle, TAPI_CALL_END, &HandleCallbackResponse, this);
383                 if (res == TAPI_CAUSE_SUCCESS)
384                 {
385                         r = E_SUCCESS;
386                 }
387         }
388         return r;
389 }
390
391 result
392 TelephonyManager::AnswerAutoRejectCall(int callHandle)
393 {
394         //Incoming call automatically blocked is handled here.
395         AppLogDebug("Enter ");
396         result r = E_FAILURE;
397         TelCallAnswerType_t answerType = TAPI_CALL_ANSWER_REJECT;
398         int res = -1;
399
400         AppLogDebug("tel_answer_call");
401         //save to logs db.
402         AppCallInfo rejectedCallInfo;
403         rejectedCallInfo = *(__pIncomingCall);
404         rejectedCallInfo.SetCalllogType(CALL_LOG_TYPE_VOICE_BLOCKED);
405         SaveCallInfoToLogsDb(rejectedCallInfo);
406         delete __pIncomingCall;
407         __pIncomingCall = null;
408
409         // redirect to reject call back handler as the flow has to be handled
410         res = tel_answer_call(__pTapiHandle, callHandle, answerType, &HandleCallbackResponse, this);
411
412         if (res == TAPI_CAUSE_SUCCESS)
413         {
414                 r = E_SUCCESS;
415         }
416         else
417         {
418                 r = E_FAILURE;
419         }
420         return r;
421 }
422
423 result
424 TelephonyManager::AnswerCall(int callHandle, bool acceptCall)
425 {
426         AppLogDebug("Enter %d",acceptCall);
427         result r = E_FAILURE;
428         __pSoundManager->StopAlert();
429         TelCallAnswerType_t answerType = TAPI_CALL_ANSWER_ACCEPT;
430         int res = -1;
431         if (acceptCall == true)
432         {
433                 answerType = TAPI_CALL_ANSWER_ACCEPT;
434                 // redirect to dummy call back handler as the flow already handled in registered event callback
435                 res = tel_answer_call(__pTapiHandle, callHandle, answerType, &HandleCallbackResponse, this);
436         }
437         else
438         {
439                 AppLogDebug("tel_answer_call");
440                 answerType = TAPI_CALL_ANSWER_REJECT;
441                 // redirect to reject call back handler as the flow has to be handled
442                 res = tel_answer_call(__pTapiHandle, callHandle, answerType, &HandleRejectCallbackResponse, this);
443         }
444
445         if (res == TAPI_CAUSE_SUCCESS)
446         {
447                 r = E_SUCCESS;
448         }
449         else
450         {
451                 r = E_FAILURE;
452         }
453         return r;
454 }
455
456 result
457 TelephonyManager::AcceptCall(CallAnsweringOptions answerOptions,int callHandle)
458 {
459         result r = E_FAILURE;
460         __pSoundManager->StopAlert();
461         __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
462
463         //Check if this is a new incoming call
464         if(__pIncomingCall == null || (callHandle != (unsigned int)__pIncomingCall->GetCallHandle()->ToLong()))
465         {
466                 //construct and fetch new Incoming call Info
467                 String incomingHandle;
468                 incomingHandle.Append(callHandle);
469                 AppCallInfo* pDuplicateCallInfo = FetchIncomingCallHandleN(incomingHandle, String(L""));
470                 if(pDuplicateCallInfo == null)
471                 {
472                         r = E_FAILURE;
473                         return r;
474                 }
475                 delete pDuplicateCallInfo;
476                 pDuplicateCallInfo = null;
477         }
478
479         switch(answerOptions)
480         {
481         case ANSERWING_OPTION_HOLD_SINGLE_CALL:
482         case ANSERWING_OPTION_END_SINGLE_CALL:
483         {
484                 r = AcceptSecondCall(answerOptions, callHandle);
485         }
486         break;
487
488         case ANSERWING_OPTION_REPLACE_ACTIVE_CALL:
489         case ANSERWING_OPTION_REPLACE_HELD_CALL:
490         case ANSERWING_OPTION_END_ALL_CALLS:
491         {
492                 r = AcceptMultipleCall(answerOptions, callHandle);
493         }
494         break;
495
496         default:
497                 break;
498         }
499         return r;
500 }
501
502 result
503 TelephonyManager::AcceptSecondCall(CallAnsweringOptions answerOptions, const int incomingCallHandle)
504 {
505         result r = E_FAILURE;
506
507         switch (answerOptions)
508         {
509         case ANSERWING_OPTION_HOLD_SINGLE_CALL:
510         {
511                 //accept incoming call by putting active call on Hold with 'TAPI_CALL_ANSWER_HOLD_AND_ACCEPT'
512                 int res = tel_answer_call(__pTapiHandle, incomingCallHandle, TAPI_CALL_ANSWER_HOLD_AND_ACCEPT, &HandleCallbackResponse, this);
513                 if (res != 0)
514                 {
515                         r = E_FAILURE;
516                         break;
517                 }
518
519                 //Call connected successfully
520                 r = E_SUCCESS;
521                 //update status of first call to "OnHold"
522                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
523                 AppCallInfo firstCallInfo;
524                 pCallList->GetAt(0, firstCallInfo);
525                 //replace old object with update AppCallInfo
526                 AppCallInfo* pHeldCallInfo = new (std::nothrow) AppCallInfo();
527                 *pHeldCallInfo = firstCallInfo;
528                 pHeldCallInfo->SetOnHold(true);
529                 __pActiveCallList->Remove(firstCallInfo.GetCallHandle()->ToLong());
530                 __pActiveCallList->Add(pHeldCallInfo->GetCallHandle()->ToLong(), *pHeldCallInfo);
531                 delete pCallList;
532                 pCallList = null;
533         }
534         break;
535
536         case ANSERWING_OPTION_END_SINGLE_CALL:
537         {
538                 //Transfer Old active calls to a separate list to avoid any processing in HandleIdleCallback().
539                 HashMapT<long, AppCallInfo>*  pEndCallsList = __pActiveCallList;
540                 //create a new ActiveCallList
541                 __pActiveCallList = new (std::nothrow) HashMapT<long, AppCallInfo>();
542                 __pActiveCallList->Construct(IDI_MAX_ACTIVE_CALLS);
543
544                 //accept call and reject all active calls with 'TAPI_CALL_ANSWER_REPLACE'
545                 int res = tel_answer_call(__pTapiHandle, incomingCallHandle, TAPI_CALL_ANSWER_REPLACE, &HandleCallbackResponse, this);
546                 if (res != 0)
547                 {
548                         r = E_FAILURE;
549                         //delete newly constructed list and gain ownership of old list
550                         delete __pActiveCallList;
551                         __pActiveCallList = pEndCallsList;
552                         break;
553                 }
554
555                 //Call connected successfully
556                 r = E_SUCCESS;
557                 //Add calls information to call log before deleting from active call list.
558                 IListT<AppCallInfo>* pCallList = pEndCallsList->GetValuesN();
559                 if(pCallList != null)
560                 {
561                         AppCallInfo endCallInfo;
562                         if (pCallList->GetAt(0, endCallInfo) == E_SUCCESS)
563                         {
564                                 SaveCallInfoToLogsDb(endCallInfo);
565                         }
566                         delete pCallList;
567                 }
568                 pEndCallsList->RemoveAll();
569                 delete pEndCallsList;
570         }
571         break;
572
573         default:
574                 break;
575         }
576         return r;
577 }
578
579 result
580 TelephonyManager::AcceptMultipleCall(CallAnsweringOptions answerOptions, const int incomingCallHandle)
581 {
582         result r = E_FAILURE;
583
584         switch (answerOptions)
585         {
586         case ANSERWING_OPTION_REPLACE_ACTIVE_CALL:
587         {
588                 //Replace "Active" call by incoming call and save ended call to call logs db.
589                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
590                 AppCallInfo callToBeEnded;
591                 pCallList->GetAt(0, callToBeEnded);
592                 //Check if the call is on "Hold", then fetch 2nd callInfo
593                 if (callToBeEnded.IsOnHold() == true)
594                 {
595                         pCallList->GetAt(1, callToBeEnded);
596                 }
597                 delete pCallList;
598                 pCallList = null;
599
600                 //remove "CallToBeEnded" from Active call list to avoid processing in HandleIdleCallback().
601                 __pActiveCallList->Remove(callToBeEnded.GetCallHandle()->ToLong());
602
603                 //Accept incoming call by End Active call with 'TAPI_CALL_ANSWER_REPLACE'
604                 int res = tel_answer_call(__pTapiHandle, incomingCallHandle, TAPI_CALL_ANSWER_REPLACE, &HandleCallbackResponse, this);
605                 if (res != 0)
606                 {
607                         r = E_FAILURE;
608                         //save the previous call back to active call list
609                         __pActiveCallList->Add(callToBeEnded.GetCallHandle()->ToLong(), callToBeEnded);
610                         break;
611                 }
612
613                 //Incoming Call connected successfully
614                 r = E_SUCCESS;
615                 //save to ended call to call logs db.
616                 SaveCallInfoToLogsDb(callToBeEnded);
617         }
618         break;
619
620         case ANSERWING_OPTION_REPLACE_HELD_CALL:
621         {
622                 //Replace "Held" call by incoming call and save ended call to call logs db.
623                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
624                 //"Held" call is to be ended
625                 AppCallInfo callToBeEnded;
626                 //"Active" call will be put on Hold
627                 AppCallInfo callToPutOnHold;
628                 pCallList->GetAt(0, callToBeEnded);
629                 //Check if the call is NOT "Held", then fetch 2nd callInfo
630                 if (callToBeEnded.IsOnHold() == false)
631                 {
632                         callToPutOnHold = callToBeEnded;
633                         pCallList->GetAt(1, callToBeEnded);
634                 }
635                 else
636                 {
637                         pCallList->GetAt(1, callToPutOnHold);
638                 }
639                 delete pCallList;
640                 pCallList = null;
641
642                 //remove "CallToBeEnded" from Active call list to avoid processing in HandleIdleCallback().
643                 __pActiveCallList->Remove(callToBeEnded.GetCallHandle()->ToLong());
644
645                 //End "Held" Call using 'TAPI_CALL_END'.
646                 int res = -1;
647                 if (callToBeEnded.IsConferenceCall() == false)
648                 {
649                         res = tel_end_call(__pTapiHandle, callToBeEnded.GetCallHandle()->ToLong(), TAPI_CALL_END, &HandleCallbackResponse, this);
650                 }
651                 else
652                 {
653                         IListT<AppCallInfo>* pParticipantsInfo = callToBeEnded.GetCallerList();
654                         //need to end every participant individually for conference call
655                         for (int index = 0; index < pParticipantsInfo->GetCount(); index++)
656                         {
657                                 AppCallInfo memberCallInfo;
658                                 pParticipantsInfo->GetAt(index, memberCallInfo);
659                                 res = tel_end_call(__pTapiHandle, memberCallInfo.GetCallHandle()->ToLong(), TAPI_CALL_END, &HandleCallbackResponse, this);
660                         }
661                 }
662
663                 if (res != 0)
664                 {
665                         r = E_FAILURE;
666                         //save the previous "callToBeEnded" call back to active call list
667                         __pActiveCallList->Add(callToBeEnded.GetCallHandle()->ToLong(), callToBeEnded);
668                         break;
669                 }
670                 //"Held" call successfully ended - Add call ended to call log database
671                 SaveCallInfoToLogsDb(callToBeEnded);
672
673                 //accept incoming call by Holding "Active" call using "TAPI_CALL_ANSWER_HOLD_AND_ACCEPT".
674                 res = tel_answer_call(__pTapiHandle, incomingCallHandle, TAPI_CALL_ANSWER_HOLD_AND_ACCEPT, &HandleCallbackResponse, this);
675                 if (res != 0)
676                 {
677                         r = E_FAILURE;
678                         break;
679                 }
680
681                 //Call connected successfully and active call is "Onhold"
682                 r = E_SUCCESS;
683                 //replace old object with update CallInfo
684                 AppCallInfo* pHeldCallInfo = new (std::nothrow) AppCallInfo();
685                 *pHeldCallInfo = callToPutOnHold;
686                 pHeldCallInfo->SetOnHold(true);
687                 __pActiveCallList->Remove(callToPutOnHold.GetCallHandle()->ToLong());
688                 __pActiveCallList->Add(pHeldCallInfo->GetCallHandle()->ToLong(), *pHeldCallInfo);
689         }
690         break;
691
692         case ANSERWING_OPTION_END_ALL_CALLS:
693         {
694                 //End all active and Held calls after saving to call log. Incoming call is automatically accepted by TAPI engine,
695                 // and processing of Incoming call is handled in HandleActiveCallback().
696
697                 //Transfer Old active calls to a separate list to avoid any processing in HandleIdleCallback().
698                 HashMapT<long, AppCallInfo>*  pEndCallsList = __pActiveCallList;
699                 //create a new ActiveCallList
700                 __pActiveCallList = new (std::nothrow) HashMapT<long, AppCallInfo>();
701                 __pActiveCallList->Construct(IDI_MAX_ACTIVE_CALLS);
702
703                 //End all active calls and all hold calls
704                 int res = tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_ACTIVE_ALL, &HandleCallbackResponse, this);
705                 if(res == 0)
706                 {
707                         res = tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_HOLD_ALL, &HandleCallbackResponse, this);
708                 }
709
710                 if (res != 0)
711                 {
712                         r = E_FAILURE;
713                         //delete newly constructed list and gain ownership of old list
714                         delete __pActiveCallList;
715                         __pActiveCallList = pEndCallsList;
716                         break;
717                 }
718
719                 //all calls ended successfully, Incoming call is automatically accepted.
720                 r = E_SUCCESS;
721
722                 //Add calls information to call log before deleting from active call list.
723                 IListT<AppCallInfo>* pCallList = pEndCallsList->GetValuesN();
724                 if(pCallList != null)
725                 {
726                         int callCount = pCallList->GetCount();
727                         for (int index = 0; index < callCount; index++)
728                         {
729                                 AppCallInfo endCallInfo;
730                                 if (pCallList->GetAt(index, endCallInfo) == E_SUCCESS)
731                                 {
732                                         SaveCallInfoToLogsDb(endCallInfo);
733                                 }
734                         }
735                         delete pCallList;
736                         pCallList = null;
737                 }
738                 pEndCallsList->RemoveAll();
739                 delete pEndCallsList;
740                 pEndCallsList = null;
741         }
742         break;
743
744         default:
745                 break;
746         }
747         return r;
748 }
749
750 result
751 TelephonyManager::HoldCall(Tizen::Base::Long callHandle, bool holdCall)
752 {
753         result r = E_SUCCESS;
754         //Check if there are any existing active calls
755         if (__pActiveCallList->GetCount())
756         {
757                 IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
758                 int callCount = pCallList->GetCount();
759                 for (int index = 0; index < callCount; index++)
760                 {
761                         AppCallInfo holdCallInfo;
762
763                         r = pCallList->GetAt(index, holdCallInfo);
764                         //check if an active call is found with matching contact no.
765                         if ((r == E_SUCCESS) && (holdCallInfo.GetCallHandle()->Equals(callHandle)))
766                         {
767                                 r = HoldActiveCall(&holdCallInfo, holdCall);
768                                 break;
769                         }
770                 }
771                 delete pCallList;
772                 pCallList = null;
773         }
774
775         return r;
776 }
777
778 result
779 TelephonyManager::EndConferenceCall(void)
780 {
781         result r = E_FAILURE;
782         //fetch conference callInfo to end
783         AppCallInfo confCallToEnd;
784         bool isConferenceCallFound = false;
785
786         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
787         int callCount = pCallList->GetCount();
788         for (int index = 0; index < callCount; index++)
789         {
790                 pCallList->GetAt(index, confCallToEnd);
791                 if (confCallToEnd.IsConferenceCall() == true)
792                 {
793                         isConferenceCallFound = true;
794                         break;
795                 }
796         }
797         delete pCallList;
798         pCallList = null;
799
800         if (isConferenceCallFound == true)
801         {
802                 //End conference call
803                 TelCallEndType_t callEndType = TAPI_CALL_END_ACTIVE_ALL;
804                 if (confCallToEnd.IsOnHold() == true)
805                 {
806                         callEndType = TAPI_CALL_END_HOLD_ALL;
807                 }
808                 int res = tel_end_call(__pTapiHandle, confCallToEnd.GetCallHandle()->ToLong(), callEndType, &HandleEndConferenceCallbackResponse, this);
809                 if (res == TAPI_CAUSE_SUCCESS)
810                 {
811                         r = E_SUCCESS;
812                 }
813         }
814         return r;
815 }
816
817 result
818 TelephonyManager::HoldConferenceCall(bool holdCall)
819 {
820         result r = E_FAILURE;
821         int confCallIndex = -1;
822         AppCallInfo confCallToHold;
823         bool isConferenceCallFound = false;
824
825         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
826         int confCallCount = pCallList->GetCount();
827
828         for (int index = 0; index < confCallCount; index++)
829         {
830                 pCallList->GetAt(index, confCallToHold);
831                 if (confCallToHold.IsConferenceCall() == true)
832                 {
833                         isConferenceCallFound = true;
834                         confCallIndex = index;
835                         //Found the Conference call to be ended.
836                         break;
837                 }
838         }
839
840         if (isConferenceCallFound == false)
841         {
842                 delete pCallList;
843                 pCallList = null;
844                 return r;
845         }
846
847         unsigned int callHandle = confCallToHold.GetCallHandle()->ToLong();
848         int res = TAPI_API_INVALID_INPUT;
849         if (holdCall == true)
850         {
851                 res = tel_hold_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
852         }
853         else
854         {
855                 res = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
856         }
857         if (res == TAPI_API_SUCCESS)
858         {
859                 r = E_SUCCESS;
860                 if (holdCall == true)
861                 {
862                         confCallToHold.SetOnHold(true);
863                 }
864                 else
865                 {
866                         confCallToHold.SetOnHold(false);
867                 }
868                 AppCallInfo* pConfCallInfo = new (std::nothrow) AppCallInfo();
869                 *pConfCallInfo = confCallToHold;
870                 __pActiveCallList->Remove(callHandle);
871                 __pActiveCallList->Add(callHandle, *pConfCallInfo);
872         }
873         else
874         {
875                 r = E_FAILURE;
876         }
877
878         delete pCallList;
879         pCallList = null;
880         return r;
881 }
882
883 result
884 TelephonyManager::JoinCall(void)
885 {
886         result r = E_FAILURE;
887         int res = -1;
888         AppCallInfo activeCall;
889         AppCallInfo heldCall;
890         // Use enumerator to access elements in the map
891         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
892         r = pCallList->GetAt(0, activeCall);
893
894         if (r == E_SUCCESS)
895         {
896                 r = pCallList->GetAt(1, heldCall);
897                 if (r == E_SUCCESS)
898                 {
899                         unsigned int activeCallHandle = activeCall.GetCallHandle()->ToLong();
900                         unsigned int heldCallHandle = heldCall.GetCallHandle()->ToLong();
901
902                         //Check if participants in conference call are under limit.
903                         if ((heldCall.IsConferenceCall() == true) && (heldCall.GetCallerListCount() < IDI_MAX_CONF_CALL_PARTICIPANTS))
904                         {
905                                 res = tel_join_call(__pTapiHandle, heldCallHandle, activeCallHandle, &HandleJoinCallbackResponse, this);
906                         }
907                         else if (activeCall.GetCallerListCount() < IDI_MAX_CONF_CALL_PARTICIPANTS)
908                         {
909                                 res = tel_join_call(__pTapiHandle, activeCallHandle, heldCallHandle, &HandleJoinCallbackResponse, this);
910                         }
911                 }
912         }
913         delete pCallList;
914         pCallList = null;
915         if (res == TAPI_API_SUCCESS)
916         {
917                 r = E_SUCCESS;
918         }
919         else
920         {
921                 r = E_FAILURE;
922         }
923         return r;
924 }
925
926 result
927 TelephonyManager::HoldActiveCall(AppCallInfo* pActiveCallInfo, bool holdCall)
928 {
929         unsigned int callHandle = pActiveCallInfo->GetCallHandle()->ToLong();
930         int retStatus = -1;
931         if (holdCall == true)
932         {
933                 retStatus = tel_hold_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
934         }
935         else
936         {
937                 retStatus = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
938         }
939
940         if (retStatus == TAPI_CAUSE_SUCCESS)
941         {
942                 AppCallInfo* pHeldCallInfo = new (std::nothrow) AppCallInfo();
943                 //copy state into new callinfo object
944                 *pHeldCallInfo = *pActiveCallInfo;
945
946                 //set call to hold state
947                 pHeldCallInfo->SetOnHold(holdCall);
948
949                 __pActiveCallList->Remove(callHandle);
950                 //replace old object with new
951                 __pActiveCallList->Add(callHandle, *pHeldCallInfo);
952                 return E_SUCCESS;
953         }
954         else
955         {
956                 return E_FAILURE;
957         }
958 }
959
960 result
961 TelephonyManager::DialOutgoingCall(String& contactNumber, bool isEmergency)
962 {
963         TelCallDial_t structDialCall;
964
965         AppLogDebug("Enter %ls",contactNumber.GetPointer());
966         //Temp String to replace , with P and ; with W
967         String TempContactNum;
968         TempContactNum.Append(contactNumber);
969         TempContactNum.Replace(L",",L"W");
970         TempContactNum.Replace(L";",L",");
971         //conversion "contactNumber" to char*
972         const wchar_t* pContact = TempContactNum.GetPointer();
973         int len = TempContactNum.GetLength()+1;
974         char* pNumber = new (std::nothrow) char[len];
975         wcstombs(pNumber, pContact, len);
976
977
978         //initialize request parameter
979         memset(&structDialCall, '\0', sizeof(TelCallDial_t));
980         memcpy(structDialCall.szNumber, pNumber, strlen(pNumber));
981         AppLogDebug("%s",structDialCall.szNumber);
982         if(isEmergency == true)
983         {
984                 structDialCall.CallType = TAPI_CALL_TYPE_E911;
985         }
986         else
987         {
988                 structDialCall.CallType = TAPI_CALL_TYPE_VOICE;
989         }
990
991         int res = tel_dial_call(__pTapiHandle, &structDialCall, &HandleDialCallbackResponse, this);
992         if (__pSoundManager == null)
993         {
994                 __pSoundManager = new (std::nothrow) SoundManager();
995         }
996         __pSoundManager->StartSession();
997         delete[] pNumber;
998         pNumber = null;
999
1000         if (res == TAPI_CAUSE_SUCCESS)
1001         {
1002                 if (__pDialedCall != null)
1003                 {
1004                         delete __pDialedCall;
1005                         __pDialedCall = null;
1006                 }
1007                 __pDialedCall = new (std::nothrow) AppCallInfo();
1008                 __pDialedCall->SetContactNumber(contactNumber);
1009                 __pDialedCall->SetEmergency(isEmergency);
1010                 result r = FetchContactInfoForNumber(contactNumber);
1011                 if (!IsFailed(r))
1012                 {
1013                         __pDialedCall->SetContactInfo(*__pCachedContact);
1014                 }
1015                 return E_SUCCESS;
1016         }
1017         else
1018         {
1019                 return E_FAILURE;
1020         }
1021 }
1022
1023 result
1024 TelephonyManager::SwapCalls(void)
1025 {
1026         result r = E_FAILURE;
1027
1028         //check if there are atleast 2 active calls
1029         if (__pActiveCallList->GetCount() == IDI_MAX_ACTIVE_CALLS)
1030         {
1031                 int retStatus = 0;
1032
1033                 //fetch call handles
1034                 IListT<long>* pCallHandleList = __pActiveCallList->GetKeysN();
1035                 long callHandle1 = 0;
1036                 pCallHandleList->GetAt(0, callHandle1);
1037                 long callHandle2 = 0;
1038                 pCallHandleList->GetAt(1, callHandle2);
1039
1040                 retStatus = tel_swap_call(__pTapiHandle, callHandle1, callHandle2, &HandleSwapCallbackResponse, this);
1041
1042                 if (retStatus == TAPI_CAUSE_SUCCESS)
1043                 {
1044                         r = E_SUCCESS;
1045                 }
1046                 delete pCallHandleList;
1047                 pCallHandleList = null;
1048         }
1049
1050         return r;
1051 }
1052
1053 result
1054 TelephonyManager::SendCallDTMF(String& textToBeSent)
1055 {
1056         result r = E_FAILURE;
1057         //check if there is an active Call
1058         if (__pActiveCallList->GetCount() > 0)
1059         {
1060                 //conversion "textToBeSent" to char*
1061                 const wchar_t* pTextToBeSent = textToBeSent.GetPointer();
1062                 int len = textToBeSent.GetLength() + 1;
1063                 char* pNumber = new (std::nothrow) char[len];
1064                 wcstombs(pNumber, pTextToBeSent, len);
1065                 int retStatus = tel_call_dtmf(__pTapiHandle, pNumber, &HandleCallbackResponse, this);
1066                 delete []pNumber;
1067                 pNumber = null;
1068                 if (retStatus == TAPI_CAUSE_SUCCESS)
1069                 {
1070                         r = E_SUCCESS;
1071                 }
1072         }
1073         return r;
1074 }
1075
1076 result
1077 TelephonyManager::EndFromConference(int callHandle)
1078 {
1079         result r = E_FAILURE;
1080         int confCallIndex = -1;
1081         AppCallInfo endConfCall;
1082         bool isConferenceCallFound = false;
1083
1084         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
1085         int callCount = pCallList->GetCount();
1086         for (int index = 0; index < callCount; index++)
1087         {
1088                 pCallList->GetAt(index, endConfCall);
1089                 if (endConfCall.IsConferenceCall() == true)
1090                 {
1091                         isConferenceCallFound = true;
1092                         confCallIndex = index;
1093                         //Found the Conference call to be ended.
1094                         break;
1095                 }
1096         }
1097
1098         delete pCallList;
1099         pCallList = null;
1100
1101         if (isConferenceCallFound == false)
1102         {
1103                 //no conference call found
1104                 return r;
1105         }
1106
1107         //Identify the call to be ended and remove from list on API success
1108         AppCallInfo callToBeEnded;
1109         IListT<AppCallInfo>* pParticipantList = endConfCall.GetCallerList();
1110         int participantCount = pParticipantList->GetCount();
1111         for (int index = 0; index < participantCount; index++)
1112         {
1113                 pParticipantList->GetAt(index, callToBeEnded);
1114                 if (callToBeEnded.GetCallHandle()->ToLong() == callHandle)
1115                 {
1116                         //Identify the call to be ended and remove from list on API success
1117                         TelCallEndType_t endType = TAPI_CALL_END;
1118
1119                         int res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndFromConferenceCallbackResponse, this);
1120                         if (res == TAPI_CAUSE_SUCCESS)
1121                         {
1122                                 r = E_SUCCESS;
1123                         }
1124                         else
1125                         {
1126                                 r = E_FAILURE;
1127                         }
1128                         break;
1129                 }
1130         }
1131
1132         return r;
1133 }
1134
1135 result
1136 TelephonyManager::SplitFromConference(int callHandle)
1137 {
1138         result r = E_FAILURE;
1139         int confCallIndex = -1;
1140         AppCallInfo endConfCall;
1141         bool isConferenceCallFound = false;
1142
1143         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
1144         int callCount = pCallList->GetCount();
1145         for (int index = 0; index < callCount; index++)
1146         {
1147                 pCallList->GetAt(index, endConfCall);
1148                 if (endConfCall.IsConferenceCall() == true)
1149                 {
1150                         isConferenceCallFound = true;
1151                         confCallIndex = index;
1152                         //Found the Conference call to be ended.
1153                         break;
1154                 }
1155         }
1156         delete pCallList;
1157         pCallList = null;
1158         if (isConferenceCallFound == false)
1159         {
1160                 //no conference call found
1161                 return r;
1162         }
1163
1164         //Identify the call to be ended and remove from list on API success
1165         AppCallInfo callToBeEnded;
1166         pCallList = endConfCall.GetCallerList();
1167         callCount = pCallList->GetCount();
1168         for (int index = 0; index < callCount; index++)
1169         {
1170                 pCallList->GetAt(index, callToBeEnded);
1171                 if (callToBeEnded.GetCallHandle()->ToLong() == callHandle)
1172                 {
1173                         int res = tel_split_call(__pTapiHandle, callHandle, &HandleSplitFromConferenceCallbackResponse, this);
1174                         if (res == TAPI_CAUSE_SUCCESS)
1175                         {
1176                                 r = E_SUCCESS;
1177                         }
1178                         else
1179                         {
1180                                 r = E_FAILURE;
1181                         }
1182                         break;
1183                 }
1184         }
1185         return r;
1186 }
1187
1188 result
1189 TelephonyManager::SetMuteStatus(bool setMute)
1190 {
1191         TelSoundMuteStatus_t muteStatus;
1192         result r = E_FAILURE;
1193         if (setMute == true)
1194         {
1195                 muteStatus = TAPI_SOUND_MUTE_STATUS_ON;
1196         }
1197         else
1198         {
1199                 muteStatus = TAPI_SOUND_MUTE_STATUS_OFF;
1200         }
1201         int res = tel_set_call_mute_status(__pTapiHandle, muteStatus, &HandleCallbackResponse, this);
1202         if (res == TAPI_CAUSE_SUCCESS)
1203         {
1204                 __isMuted = setMute;
1205                 r = E_SUCCESS;
1206         }
1207         else
1208         {
1209                 r = E_FAILURE;
1210         }
1211         return r;
1212 }
1213
1214 bool
1215 TelephonyManager::IsCallMuted(void)
1216 {
1217         return __isMuted;
1218 }
1219
1220 result
1221 TelephonyManager::SetSpeakerStatus(bool setSpeaker)
1222 {
1223         result r = E_FAILURE;
1224         TelCallSoundPathInfo_t callSoundPathInfo;
1225         __pSoundManager->SetSpeakerStatus(setSpeaker);
1226         if (setSpeaker == true)
1227         {
1228                 callSoundPathInfo.path = TAPI_SOUND_PATH_SPK_PHONE;
1229         }
1230         else
1231         {
1232                 callSoundPathInfo.path = TAPI_SOUND_PATH_HANDSET;
1233         }
1234         callSoundPathInfo.ex_volume = TelCallSoundPathInfo_t::TAPI_SOUND_EX_VOLUME_ON;
1235
1236         int res = tel_set_call_sound_path(__pTapiHandle, &callSoundPathInfo, &HandleCallbackResponse, this);
1237
1238         if (res == TAPI_CAUSE_SUCCESS)
1239         {
1240                 __isSpeakerOn = setSpeaker;
1241                 r = E_SUCCESS;
1242         }
1243         else
1244         {
1245                 r = E_FAILURE;
1246         }
1247         return r;
1248 }
1249
1250 bool
1251 TelephonyManager::IsSpeakerOn(void)
1252 {
1253         return __isSpeakerOn;
1254 }
1255
1256 bool
1257 TelephonyManager::IsSplitAllowed(void)
1258 {
1259         // Split functionality is allowed only if a one call is present.
1260         // The call can be a single call or a conference call
1261         if (__pActiveCallList->GetCount() == 1)
1262         {
1263                 return true;
1264         }
1265         return false;
1266 }
1267
1268 void
1269 TelephonyManager::HandleCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1270 {
1271         //should not do anything here.
1272 }
1273
1274 void
1275 TelephonyManager::HandleDialCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1276 {
1277         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1278         if (callBackResult != TAPI_CAUSE_SUCCESS)
1279         {
1280                 if (pTelManager->__pDialedCall != null)
1281                 {
1282                         delete pTelManager->__pDialedCall;
1283                         pTelManager->__pDialedCall = null;
1284                 }
1285
1286                 //Check if there are no active connected calls and no incoming call.
1287                 if (pTelManager->__pIncomingCall != null)
1288                 {
1289                         pTelManager->__pSettingsManager->SetCallState(CALL_STATE_CALL_VOICE_CONNECTING);
1290                 }
1291                 else if (pTelManager->GetCurrentCallCount() >= 1)
1292                 {
1293                         pTelManager->__pSettingsManager->SetCallState(CALL_STATE_CALL_VOICE_ACTIVE);
1294                 }
1295                 else
1296                 {
1297                         pTelManager->__pSettingsManager->SetCallState(CALL_STATE_CALL_OFF);
1298                 }
1299
1300                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_DIAL_FAILED);
1301         }
1302 }
1303
1304 void
1305 TelephonyManager::HandleRejectCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1306 {
1307         AppLogDebug("ENTER");
1308         // This callback comes only if user has rejected an incoming call from IncomingCallForm.
1309         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1310         if (pData != null && callBackResult == TAPI_API_SUCCESS)
1311         {
1312                 unsigned int rejectedCallHandle = 0;
1313                 memcpy(&rejectedCallHandle, pData, sizeof(TS_UINT));
1314
1315                 //Check if incoming call is rejected
1316                 if (pTelManager->__pIncomingCall != null && (rejectedCallHandle == (unsigned int) pTelManager->__pIncomingCall->GetCallHandle()->ToLong()))
1317                 {
1318                         AppLogDebug("Call rejected by user");
1319                         AppCallInfo rejectedCallInfo;
1320                         rejectedCallInfo = *(pTelManager->__pIncomingCall);
1321                         delete pTelManager->__pIncomingCall;
1322                         pTelManager->__pIncomingCall = null;
1323
1324                         //rejected by user from incoming call form
1325                         rejectedCallInfo.SetCalllogType(CALL_LOG_TYPE_VOICE_REJECTED);
1326                         //Save rejected incoming call to call log db.
1327                         pTelManager->SaveCallInfoToLogsDb(rejectedCallInfo);
1328
1329                         //check if the ended call was the last call
1330                         bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
1331                         //Stop alert - started only for incoming calls which are not blocked.
1332                         if(pTelManager->__pSoundManager != null)
1333                         {
1334                                 pTelManager->__pSoundManager->StopAlert();
1335                                 //Do not call stop session if there is already a call going on
1336                                 if(isLastCall == true)
1337                                 {
1338                                         pTelManager->__pSoundManager->StopSession();
1339                                 }
1340                         }
1341                         //Send notification to user
1342                         ArrayListT<AppCallInfo>* pCallList = null;
1343                         if (isLastCall)
1344                         {
1345                                 //save 'RejectedCall' to list to show on EndCallForm
1346                                 pCallList = new (std::nothrow) ArrayListT<AppCallInfo>();
1347                                 pCallList->Construct(1);
1348                                 AppCallInfo* pRejectedCall = new (std::nothrow) AppCallInfo();
1349                                 *pRejectedCall = rejectedCallInfo;
1350                                 pCallList->Add(*pRejectedCall);
1351                         }
1352                         else
1353                         {
1354                                 //fetch active calls to show appropriate scene
1355                                 pCallList = static_cast<ArrayListT<AppCallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
1356                         }
1357                         pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
1358                         delete pCallList;
1359                         pCallList = null;
1360                 }
1361         }
1362         else
1363         {
1364                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_REJECT_FAILED);
1365         }
1366         AppLogDebug("EXIT");
1367 }
1368
1369 void
1370 TelephonyManager::HandleJoinCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1371 {
1372         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1373         if (callBackResult == TAPI_API_SUCCESS && pData != null)
1374         {
1375                 unsigned int tempHandle = 0;
1376                 TelCallInfoJoinedNoti_t joinedInfoNotification;
1377                 AppCallInfo confCallInfo;
1378
1379                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
1380                 joinedInfoNotification.id = tempHandle;
1381                 AppCallInfo activeCall;
1382                 AppCallInfo heldCall;
1383                 // Use enumerator to access elements in the map
1384                 IListT<AppCallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1385                 result r = pCallList->GetAt(0, activeCall);
1386
1387                 if (r == E_SUCCESS)
1388                 {
1389                         r = pCallList->GetAt(1, heldCall);
1390                         if (r == E_SUCCESS)
1391                         {
1392                                 AppCallInfo* pConfCallInfo = new (std::nothrow) AppCallInfo();
1393                                 unsigned int activeCallHandle = activeCall.GetCallHandle()->ToLong();
1394                                 unsigned int heldCallHandle = heldCall.GetCallHandle()->ToLong();
1395                                 if (activeCall.IsConferenceCall() == true)
1396                                 {
1397                                         r = E_SUCCESS;
1398                                         //When joined both become active
1399                                         activeCall.SetOnHold(false);
1400                                         heldCall.SetOnHold(false);
1401                                         *pConfCallInfo = activeCall;
1402                                         pConfCallInfo->AddCallToCallerList(heldCall);
1403                                         pConfCallInfo->SetCallHandle(activeCallHandle);
1404                                         //Set call start time
1405                                         if (pConfCallInfo->GetCallConnectTime() > heldCall.GetCallConnectTime())
1406                                         {
1407                                                 pConfCallInfo->SetCallConnectTime(heldCall.GetCallConnectTime());
1408                                                 pConfCallInfo->SetCallNotificationTime(heldCall.GetCallNotificationTime());
1409                                         }
1410                                 }
1411                                 else if (heldCall.IsConferenceCall() == true)
1412                                 {
1413                                         r = E_SUCCESS;
1414                                         heldCall.SetOnHold(false);
1415                                         activeCall.SetOnHold(false);
1416                                         *pConfCallInfo = heldCall;
1417                                         pConfCallInfo->AddCallToCallerList(activeCall);
1418                                         pConfCallInfo->SetCallHandle(heldCallHandle);
1419                                         //Set call start time
1420                                         if (pConfCallInfo->GetCallConnectTime() > activeCall.GetCallConnectTime())
1421                                         {
1422                                                 pConfCallInfo->SetCallConnectTime(activeCall.GetCallConnectTime());
1423                                                 pConfCallInfo->SetCallNotificationTime(activeCall.GetCallNotificationTime());
1424                                         }
1425                                 }
1426                                 else
1427                                 {
1428                                         r = E_SUCCESS;
1429                                         pConfCallInfo->SetConference(true);
1430                                         heldCall.SetOnHold(false);
1431                                         activeCall.SetOnHold(false);
1432                                         pConfCallInfo->AddCallToCallerList(activeCall);
1433                                         pConfCallInfo->AddCallToCallerList(heldCall);
1434                                         pConfCallInfo->SetCallHandle(activeCallHandle);
1435                                         //Set call start time
1436                                         if (activeCall.GetCallConnectTime() > heldCall.GetCallConnectTime())
1437                                         {
1438                                                 pConfCallInfo->SetCallConnectTime(heldCall.GetCallConnectTime());
1439                                                 pConfCallInfo->SetCallNotificationTime(heldCall.GetCallNotificationTime());
1440                                         }
1441                                         else
1442                                         {
1443                                                 pConfCallInfo->SetCallConnectTime(activeCall.GetCallConnectTime());
1444                                                 pConfCallInfo->SetCallNotificationTime(activeCall.GetCallNotificationTime());
1445                                         }
1446                                 }
1447                                 pConfCallInfo->SetCallHandle(joinedInfoNotification.id);
1448                                 pTelManager->__pActiveCallList->RemoveAll();
1449                                 //only one call in the list
1450                                 pTelManager->__pActiveCallList->Add(joinedInfoNotification.id, *pConfCallInfo);
1451                                 //notify listener that call is connected.
1452                                 pTelManager->__pEventListener->HandleConferenceCall(*pConfCallInfo);
1453                                 delete pCallList;
1454                                 pCallList = null;
1455                         }
1456                 }
1457         }
1458         else
1459         {
1460                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_JOIN_FAILED);
1461         }
1462 }
1463
1464 void
1465 TelephonyManager::HandleSwapCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1466 {
1467         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1468         if (callBackResult == TAPI_CAUSE_SUCCESS)
1469         {
1470                 IListT<AppCallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1471                 IListT<long>* pKeyList = pTelManager->__pActiveCallList->GetKeysN();
1472                 int callCount = pTelManager->__pActiveCallList->GetCount();
1473                 for (int index = 0; index < callCount; index++)
1474                 {
1475                         AppCallInfo* pTempCallInfo = new (std::nothrow) AppCallInfo();
1476                         pCallList->GetAt(index, *pTempCallInfo);
1477                         (pTempCallInfo->IsOnHold() == false) ? pTempCallInfo->SetOnHold(true) : pTempCallInfo->SetOnHold(false);
1478                         long callHandle;
1479                         pKeyList->GetAt(index, callHandle);
1480                         pTelManager->__pActiveCallList->SetValue(callHandle, *pTempCallInfo);
1481                 }
1482                 delete pCallList;
1483                 pCallList = null;
1484                 delete pKeyList;
1485                 pKeyList = null;
1486                 pCallList = pTelManager->__pActiveCallList->GetValuesN();
1487                 pTelManager->__pEventListener->HandleCallSwapOccured(*pCallList);
1488         }
1489         else
1490         {
1491                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_SWAP_FAILED);
1492         }
1493 }
1494
1495 void
1496 TelephonyManager::HandleEndFromConferenceCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1497 {
1498         AppLogDebug("ENTER");
1499         //This callback comes if a single call is ended from Conference call.
1500         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1501         bool isParticipantCallEnded = false;
1502
1503         if (callBackResult == TAPI_CAUSE_SUCCESS && pData != null)
1504         {
1505                 //fetch end call handle
1506                 TelCallEndCnf_t callEndNotification;
1507                 memcpy(&callEndNotification, pData, sizeof(TelCallEndCnf_t));
1508                 //Fetch conference call
1509                 AppCallInfo endConfCall;
1510                 bool isConferenceCallFound = false;
1511                 IListT<AppCallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1512                 int callCount = pCallList->GetCount();
1513                 for (int index = 0; index < callCount; index++)
1514                 {
1515                         pCallList->GetAt(index, endConfCall);
1516                         if (endConfCall.IsConferenceCall() == true)
1517                         {
1518                                 isConferenceCallFound = true;
1519                                 //Found the Conference call to be changed.
1520                                 break;
1521                         }
1522                 }
1523                 delete pCallList;
1524                 pCallList = null;
1525
1526                 //Identify the call to be ended and remove from list.
1527                 if (isConferenceCallFound == true)
1528                 {
1529                         isParticipantCallEnded = pTelManager->HandleParticipantEndedFromConference(callEndNotification.id, endConfCall);
1530                 }
1531         }
1532         else
1533         {
1534                 AppLog("TAPI Failed - %d", callBackResult);
1535         }
1536
1537         //Check if participant call or Conference call was not found, then show error
1538         if (isParticipantCallEnded == false)
1539         {
1540                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_END_FROM_CONFERENCE_FAILED);
1541         }
1542         AppLogDebug("EXIT");
1543 }
1544
1545 bool
1546 TelephonyManager::HandleParticipantEndedFromConference(unsigned int participantCallHandle, AppCallInfo& conferenceCall)
1547 {
1548         AppLogDebug("ENTER");
1549         //to check if participant call was found and ended.
1550         bool isParticipantCallEnded = false;
1551         //Identify the call to be ended and remove from list.
1552         AppCallInfo callToBeEnded;
1553         IListT<AppCallInfo>* pCallerList = conferenceCall.GetCallerList();
1554         int callerCount = pCallerList->GetCount();
1555         for (int index = 0; index < callerCount; index++)
1556         {
1557                 pCallerList->GetAt(index, callToBeEnded);
1558                 if ((unsigned int)callToBeEnded.GetCallHandle()->ToLong() == participantCallHandle)
1559                 {
1560                         //Identify the call to be ended and remove from conference list
1561                         conferenceCall.RemoveCallFromCallerList(index);
1562                         //update its status to individual call before saving to database
1563                         callToBeEnded.SetConference(false);
1564                         SaveCallInfoToLogsDb(callToBeEnded);
1565                         isParticipantCallEnded = true;
1566                         break;
1567                 }
1568         }
1569
1570         if(isParticipantCallEnded == false)
1571         {
1572                 //participant call not found and not ended
1573                 return isParticipantCallEnded;
1574         }
1575
1576         unsigned int confCallHandle = (unsigned int)conferenceCall.GetCallHandle()->ToLong();
1577         //Check if last participant removed. If yes, switch to single active view
1578         if (conferenceCall.GetCallerListCount() == 1)
1579         {
1580                 AppCallInfo callFromList;
1581                 pCallerList = conferenceCall.GetCallerList();
1582                 pCallerList->GetAt(0, callFromList);
1583                 //construct a new single active call
1584                 AppCallInfo* pActiveCall = new (std::nothrow) AppCallInfo();
1585                 *pActiveCall = callFromList;
1586                 //update conference status and Hold status
1587                 pActiveCall->SetConference(false);
1588                 pActiveCall->SetOnHold(conferenceCall.IsOnHold());
1589
1590                 __pActiveCallList->Remove(confCallHandle);
1591                 __pActiveCallList->Add(pActiveCall->GetCallHandle()->ToLong(), *pActiveCall);
1592                 pActiveCall = null;
1593
1594                 //using the callConnected to switch to single active screen
1595                 //or update multiple active call screen
1596                 IListT<AppCallInfo>* pActiveCallList = __pActiveCallList->GetValuesN();
1597                 __pEventListener->HandleCallConnected(*pActiveCallList);
1598                 delete pActiveCallList;
1599                 pActiveCallList = null;
1600         }
1601         else
1602         {
1603                 AppCallInfo callFromList;
1604                 pCallerList = conferenceCall.GetCallerList();
1605                 pCallerList->GetAt(0, callFromList);
1606                 //construct a new conference call
1607                 AppCallInfo* pConfCallInfo = new (std::nothrow) AppCallInfo();
1608                 *pConfCallInfo = conferenceCall;
1609                 if (confCallHandle == participantCallHandle)
1610                 {
1611                         //Call Handle is same as conf call handle, so need to change conf call handle
1612                         __pActiveCallList->Remove(confCallHandle);
1613                         int newConfCallHandle = callFromList.GetCallHandle()->ToLong();
1614                         pConfCallInfo->SetCallHandle(newConfCallHandle);
1615                         __pActiveCallList->Add(newConfCallHandle, *pConfCallInfo);
1616                 }
1617                 else
1618                 {
1619                         __pActiveCallList->SetValue(confCallHandle, *pConfCallInfo);
1620                 }
1621                 __pEventListener->HandleConferenceChange();
1622         }
1623         AppLogDebug("EXIT");
1624         return isParticipantCallEnded;
1625 }
1626
1627 void
1628 TelephonyManager::HandleSplitFromConferenceCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1629 {
1630         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1631         if (callBackResult == TAPI_CAUSE_SUCCESS && pData != null)
1632         {
1633                 TelCallSplitCnf_t callSplitNotification;
1634                 memcpy(&callSplitNotification, pData, sizeof(TelCallSplitCnf_t));
1635                 int confCallIndex = -1;
1636                 AppCallInfo endConfCall;
1637                 bool isConferenceCallFound = false;
1638
1639                 IListT<AppCallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1640                 int callCount = pCallList->GetCount();
1641                 for (int index = 0; index < callCount; index++)
1642                 {
1643                         pCallList->GetAt(index, endConfCall);
1644                         if (endConfCall.IsConferenceCall() == true)
1645                         {
1646                                 isConferenceCallFound = true;
1647                                 confCallIndex = index;
1648                                 //Found the Conference call to be ended.
1649                                 break;
1650                         }
1651                 }
1652
1653                 if (isConferenceCallFound == false)
1654                 {
1655                         delete pCallList;
1656                         pCallList = null;
1657                         return;
1658                 }
1659                 delete pCallList;
1660                 pCallList = null;
1661                 //Identify the call to be ended and remove from list on API success
1662                 AppCallInfo callToBeEnded;
1663                 pCallList = endConfCall.GetCallerList();
1664                 callCount = pCallList->GetCount();
1665                 for (int index = 0; index < callCount; index++)
1666                 {
1667                         pCallList->GetAt(index, callToBeEnded);
1668                         if ((unsigned int)callToBeEnded.GetCallHandle()->ToLong() == callSplitNotification.id)
1669                         {
1670                                 //Identified the call to be ended and remove from conference list
1671                                 //Add this to the active call list
1672                                 endConfCall.RemoveCallFromCallerList(index);
1673                                 break;
1674                         }
1675                 }
1676                 unsigned int confCallHandle = (unsigned int)endConfCall.GetCallHandle()->ToLong();
1677                 //Set the hold flags correctly and make the changes to the active call list
1678                 if (endConfCall.GetCallerListCount() == 1)
1679                 {
1680                         //Set hold for the other single call
1681                         // and add to the list
1682                         AppCallInfo callFromList;
1683                         pCallList = endConfCall.GetCallerList();
1684                         pCallList->GetAt(0, callFromList);
1685                         AppCallInfo* pHeldCall = new (std::nothrow) AppCallInfo();
1686                         *pHeldCall = callFromList;
1687                         pHeldCall->SetConference(false);
1688                         pHeldCall->SetOnHold(true);
1689                         pTelManager->__pActiveCallList->Remove(confCallHandle);
1690                         pTelManager->__pActiveCallList->Add(pHeldCall->GetCallHandle()->ToLong(), *pHeldCall);
1691                         pHeldCall = null;
1692                 }
1693                 else
1694                 {
1695                         //Set hold flag for conference call
1696                         endConfCall.SetOnHold(true);
1697                         AppCallInfo callFromList;
1698                         pCallList = endConfCall.GetCallerList();
1699                         pCallList->GetAt(0, callFromList);
1700
1701                         AppCallInfo* pConfCallInfo = new (std::nothrow) AppCallInfo();
1702                         *pConfCallInfo = endConfCall;
1703                         if (confCallHandle == callSplitNotification.id)
1704                         {
1705                                 //Call Handle is same as conf call handle.
1706                                 //Change conf call handle
1707                                 pTelManager->__pActiveCallList->Remove(confCallHandle);
1708                                 int tmpCallHandle = callFromList.GetCallHandle()->ToLong();
1709                                 pConfCallInfo->SetCallHandle(tmpCallHandle);
1710                                 pTelManager->__pActiveCallList->Add(callFromList.GetCallHandle()->ToLong(), *pConfCallInfo);
1711                         }
1712                         else
1713                         {
1714                                 pTelManager->__pActiveCallList->Remove(confCallHandle);
1715                                 pTelManager->__pActiveCallList->Add(confCallHandle, *pConfCallInfo);
1716                         }
1717                 }
1718                 //Add the new active call to active call list
1719                 AppCallInfo* pActiveCall = new (std::nothrow) AppCallInfo();
1720                 *pActiveCall = callToBeEnded;
1721                 pActiveCall->SetConference(false);
1722                 pActiveCall->SetOnHold(false);
1723                 pTelManager->__pActiveCallList->Remove(pActiveCall->GetCallHandle()->ToLong());
1724                 pTelManager->__pActiveCallList->Add(pActiveCall->GetCallHandle()->ToLong(), *pActiveCall);
1725                 pActiveCall = null;
1726                 //using the callConnected to switch to Multiple active screen
1727                 pCallList = pTelManager->__pActiveCallList->GetValuesN();
1728                 pTelManager->__pEventListener->HandleCallConnected(*pCallList);
1729                 pCallList = null;
1730         }
1731         else
1732         {
1733                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_SPLIT_FROM_CONFERENCE_FAILED);
1734         }
1735 }
1736
1737 void
1738 TelephonyManager::HandleEndConferenceCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1739 {
1740         AppLog("ENTER");
1741         //This callback comes only if a conference call is ended by user.
1742         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1743         AppCallInfo heldCall;
1744         if (callBackResult == TAPI_CAUSE_SUCCESS && pData != null)
1745         {
1746                 //fetch ended confCall details
1747                 result r = E_FAILURE;
1748                 AppCallInfo endConfCallInfo;
1749                 IListT<AppCallInfo>* pActiveCallList = pTelManager->__pActiveCallList->GetValuesN();
1750                 if(pActiveCallList != null && pActiveCallList->GetCount() > 0)
1751                 {
1752                         for (int index = 0; index < pActiveCallList->GetCount(); index++)
1753                         {
1754                                 r = pActiveCallList->GetAt(index, endConfCallInfo);
1755                                 if(r == E_SUCCESS && endConfCallInfo.IsConferenceCall() == true)
1756                                 {
1757                                         //conference call found.
1758                                         r = E_SUCCESS;
1759                                         break;
1760                                 }
1761                                 else
1762                                 {
1763                                         r = E_FAILURE;
1764                                 }
1765                         }
1766                 }
1767                 delete pActiveCallList;
1768                 pActiveCallList = null;
1769
1770                 //check if no conference call found, then return.
1771                 if(r == E_FAILURE)
1772                 {
1773                         return;
1774                 }
1775                 //remove the conference call handle from active call list to avoid any processing in HandleIdleCallback().
1776                 pTelManager->__pActiveCallList->Remove(endConfCallInfo.GetCallHandle()->ToLong());
1777                 //Save "End" Conf. call info to call log database
1778                 pTelManager->SaveCallInfoToLogsDb(endConfCallInfo);
1779
1780                 //check if the ended call was the last call and show notification to user
1781                 bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
1782                 ArrayListT<AppCallInfo>* pCallList = null;
1783                 if (isLastCall)
1784                 {
1785                         pTelManager->__pSoundManager->SetlastEndedConferenceCall();
1786                         //stop sound session
1787                         pTelManager->__pSoundManager->StopSession();
1788                         //send empty call list to show dialer or call log screen
1789                         pCallList =new (std::nothrow) ArrayListT<AppCallInfo>();
1790                         pCallList->Construct(1);
1791                         pCallList->Add(endConfCallInfo);
1792                 }
1793                 else
1794                 {
1795                         //fetch active calls to show appropriate scene
1796                         pCallList = static_cast<ArrayListT<AppCallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
1797                         r = pCallList->GetAt(0, heldCall);
1798                         if (r == E_SUCCESS)
1799                         {
1800                                 //pTelManager->HoldActiveCall(&heldCall, false);
1801                                 AppCallInfo* pHeldCallInfo = new (std::nothrow) AppCallInfo();
1802                                 unsigned int callHandle = heldCall.GetCallHandle()->ToLong();
1803                                 //copy state into new callinfo object
1804                                 *pHeldCallInfo = heldCall;
1805
1806                                 //set call to hold state
1807                                 pHeldCallInfo->SetOnHold(false);
1808
1809                                 pTelManager->__pActiveCallList->Remove(callHandle);
1810                                 //replace old object with new
1811                                 pTelManager->__pActiveCallList->Add(callHandle, *pHeldCallInfo);
1812                                 delete pCallList;
1813                                 pCallList = static_cast<ArrayListT<AppCallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
1814                         }
1815                 }
1816                 //notify listener that call is disconnected.
1817                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
1818                 delete pCallList;
1819                 pCallList = null;
1820         }
1821         else
1822         {
1823                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_END_CALL_FAILED);
1824         }
1825         AppLog("EXIT");
1826 }
1827
1828 void
1829 TelephonyManager::HandleIdleCallBack(void* pData)
1830 {
1831         AppLogDebug("ENTER");
1832         //This callback comes when any type of calls are ended
1833         //We do NOT handle below scenarios here -
1834         //1) In incoming call scenarios, if we end any active calls - handled in "AcceptCall()".
1835         //2) Incoming call automatically blocked is handled in "AnswerAutoRejectCall()" and rejection by user scenarios are handled in "HandleRejectCallbackResponse()".
1836         //3) End conference call is handled in "HandleEndConferenceCallbackResponse()".
1837         //4) End Single Call from Conference call by user is handled in "HandleEndFromConferenceCallbackResponse()".
1838         //5) End Single Call from Conference call using eventInjector is diverted to "HandleParticipantEndedFromConference()".
1839         //BUT, we do handle below scenarios here -
1840         //1) "MISSED" incoming call scenario here i.e incoming call is rejected by other caller.
1841         //2) an "unconnected" dialed call is ended by caller or other party.
1842         //3) Any normal active calls(NOT conference calls) ended by user or by other party.
1843
1844
1845
1846         TelCallStatusIdleNoti_t idleNotification;
1847         memcpy(&idleNotification, pData, sizeof(TelCallStatusIdleNoti_t));
1848         //handle end call event, show next screen
1849         unsigned int endCallHandle = idleNotification.id;
1850
1851         //empty active call list or no dialed or incoming calls - ignore this event
1852         IListT<AppCallInfo>* pActiveCallList = __pActiveCallList->GetValuesN();
1853         if((pActiveCallList == null || pActiveCallList->GetCount() <= 0) && __pDialedCall == null && __pIncomingCall == null)
1854         {
1855                 delete pActiveCallList;
1856                 AppLogDebug("EXIT - no calls exist");
1857                 return;
1858         }
1859         if(__pSoundManager->GetLastConferenceCall() == false)
1860         {
1861                 __pSoundManager->SetDisconnectTone();
1862         }
1863         //Check if ended call was among conference caller list,
1864         //then divert event to "HandleParticipantEndedFromConference()"
1865         AppCallInfo confCallInfo;
1866         bool isConferenceCallChanged = false;
1867         for (int index = 0; (pActiveCallList != null && index < pActiveCallList->GetCount()); index++)
1868         {
1869                 //fetch conference call
1870                 result r = pActiveCallList->GetAt(index, confCallInfo);
1871                 if (r == E_SUCCESS && confCallInfo.IsConferenceCall() == true)
1872                 {
1873                         //Conference call found - check if ended call is a participant
1874                         isConferenceCallChanged = HandleParticipantEndedFromConference(endCallHandle, confCallInfo);
1875                         break;
1876                 }
1877         }
1878         delete pActiveCallList;
1879         pActiveCallList = null;
1880         if (isConferenceCallChanged == true)
1881         {
1882                 //end call event handled - conference call will now either remain as conf. call
1883                 //or become single active call, if it has only 1 participant left.
1884                 __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
1885                 AppLogDebug("isConferenceCallChanged == true");
1886                 return;
1887         }
1888
1889         //check if ended call was among the active call list and not a conference call
1890         AppCallInfo endCallInfo;
1891         result r = __pActiveCallList->GetValue(endCallHandle, endCallInfo);
1892         if (r == E_SUCCESS)
1893         {
1894                 bool isHandled = HandleEndNormalActiveCall(endCallInfo);
1895                 if (isHandled == true)
1896                 {
1897                         __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
1898                         return;
1899                 }
1900         }
1901
1902         //Check if dialed call is rejected by other party
1903         bool isDialedCallEnded = ((__pDialedCall != null)  && (__pDialedCall->GetCallHandle() != null) &&(((unsigned int)__pDialedCall->GetCallHandle()->ToLong()) == idleNotification.id));
1904         //Check if "missed" incoming call is ended
1905         bool isMissedIncomingCallEnded = (__pIncomingCall != null && ((unsigned int)__pIncomingCall->GetCallHandle()->ToLong() == idleNotification.id));
1906         if (isDialedCallEnded == true || isMissedIncomingCallEnded == true)
1907         {
1908                 //It comes here only if the ended call was either a "unconnected" dialed call or an "Missed" incoming call.
1909                 bool isLastCall = (__pActiveCallList->GetCount() == 0);
1910
1911                 ArrayListT<AppCallInfo>* pCallList = null;
1912                 //Check if dialed call was ended
1913                 if (isDialedCallEnded == true)
1914                 {
1915                         AppLogDebug("Dialed Call Ended");
1916                         //Call Ended is the dialed call
1917                         endCallInfo = *(__pDialedCall);
1918                         delete __pDialedCall;
1919                         __pDialedCall = null;
1920                 }
1921                 else
1922                 {
1923                         //Here, only "Missed" Incoming call ended by other caller is handled.
1924                         AppLogDebug("Missed Call Ended");
1925                         __pSoundManager->StopAlert();
1926                         endCallInfo = *(__pIncomingCall);
1927                         delete __pIncomingCall;
1928                         __pIncomingCall = null;
1929                         //update missed status
1930                         endCallInfo.SetCalllogType(CALL_LOG_TYPE_VOICE_MISSED_UNSEEN);
1931                         //save ended call to call log db.
1932                         //SaveCallInfoToLogsDb(endCallInfo);
1933                 }
1934                 //save ended call to call log db.
1935                 SaveCallInfoToLogsDb(endCallInfo);
1936
1937                 //notify listener that call is disconnected.
1938                 if (isLastCall == true)
1939                 {
1940                         __pSoundManager->StopSession();
1941                         pCallList = new (std::nothrow) ArrayListT<AppCallInfo>();
1942                         pCallList->Construct(1);
1943                 //This is done to show end call form in missed call case also
1944                 //this was done on request received from HQ to solve a bug in
1945                 //camera application. In which if a call comes when camera is
1946                 //running and user disconnects before the ui is shown the camera
1947                 //application hangs
1948                         //if (isMissedIncomingCallEnded == false)
1949                         {
1950                                 //save to list to show EndCallForm
1951                                 pCallList->Add(endCallInfo);
1952                         }
1953                         __pSoundManager->GetTimer()->Cancel();
1954
1955                 }
1956                 else
1957                 {
1958                         pCallList = static_cast<ArrayListT<AppCallInfo>*>(__pActiveCallList->GetValuesN());
1959                 }
1960                 __pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
1961                 delete pCallList;
1962                 pCallList = null;
1963         }
1964         __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
1965         AppLogDebug("EXIT");
1966 }
1967
1968 bool
1969 TelephonyManager::HandleEndNormalActiveCall(AppCallInfo& endCallInfo)
1970 {
1971         AppLogDebug("Enter");
1972         result r = E_FAILURE;
1973         AppCallInfo heldCall;
1974         // This function gets called only from HandleIdleCallback(),
1975         // to handle disconnection of normal active calls.
1976         if (endCallInfo.IsConferenceCall() == false)
1977         {
1978                 //remove the call handle from active call list
1979                 __pActiveCallList->Remove(endCallInfo.GetCallHandle()->ToLong());
1980                 //check if the ended call was the last call and show notification to user
1981                 bool isLastCall = (__pActiveCallList->GetCount() == 0);
1982                 ArrayListT<AppCallInfo>* pCallList = null;
1983                 if (isLastCall)
1984                 {
1985                         //stop sound session
1986                         __pSoundManager->StopSession();
1987                         //save "End" CallInfo to list to show EndCallForm
1988                         pCallList = new (std::nothrow) ArrayListT<AppCallInfo>();
1989                         pCallList->Construct(1);
1990                         pCallList->Add(endCallInfo);
1991                 }
1992                 else
1993                 {
1994                         if(__pIncomingCall == null)
1995                         {
1996                                 //fetch active calls to show appropriate scene
1997                                 pCallList = static_cast<ArrayListT<AppCallInfo>*>(__pActiveCallList->GetValuesN());
1998                                 //fetch the held call on disconnecting the active call and activate it.
1999                                 r = pCallList->GetAt(0, heldCall);
2000                                 if (r == E_SUCCESS)
2001                                 {
2002                                         HoldActiveCall(&heldCall, false);
2003                                         delete pCallList;
2004                                         pCallList = static_cast<ArrayListT<AppCallInfo>*>(__pActiveCallList->GetValuesN());
2005                                 }
2006                         }
2007                 }
2008
2009                 //Save "End" call info to call log database
2010                 SaveCallInfoToLogsDb(endCallInfo);
2011                 //notify listener that call is disconnected.
2012                 __pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
2013                 delete pCallList;
2014                 pCallList = null;
2015                 return true;
2016         }
2017         return false;
2018 }
2019
2020 void
2021 TelephonyManager::HandleDialingCallBack(void* pData)
2022 {
2023         AppLogDebug("Enter");
2024         unsigned int tempHandle = 0;
2025         TelCallStatusDialingNoti_t dialingNotification;
2026         memcpy(&tempHandle, pData, sizeof(TS_UINT));
2027         dialingNotification.id = tempHandle;
2028         //check if callback is for different dialed call
2029         //Dont check for call handle, since this is the first time, we get call handle for a dialed call.
2030         if (__pDialedCall == null)
2031         {
2032                 AppLogDebug("__pDialedCall == null");
2033                 //construct new dialed call
2034                 __pDialedCall = new (std::nothrow) AppCallInfo();
2035
2036                 TelCallStatus_t callStatus;
2037                 int res = tel_get_call_status(__pTapiHandle, dialingNotification.id, &callStatus);
2038                 if (res == TAPI_CAUSE_SUCCESS)
2039                 {
2040                         //save phone number
2041                         String contactNumber(callStatus.pNumber);
2042                         __pDialedCall->SetContactNumber(contactNumber);
2043                         //set emergency state
2044                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2045                         {
2046                                 __pDialedCall->SetEmergency(true);
2047                         }
2048                         else
2049                         {
2050                                 __pDialedCall->SetEmergency(false);
2051                         }
2052                         //save contact info
2053                         FetchContactInfoForNumber(__pDialedCall->GetContactNumber());
2054                         if (__pCachedContact != null)
2055                         {
2056                                 __pDialedCall->SetContactInfo(*(__pCachedContact));
2057                         }
2058                 }
2059         }
2060         //set call handle for dialed call
2061         __pDialedCall->SetCallHandle(dialingNotification.id);
2062         __pDialedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_OUTGOING);
2063
2064         //set call notification time.
2065         long long startTime = 0;
2066         SystemTime::GetTicks(startTime);
2067         __pDialedCall->SetCallNotificationTime(startTime);
2068         //SaveCallInfoToLogsDb(*__pDialedCall);
2069 }
2070
2071 void
2072 TelephonyManager::HandleActiveCallBack(void* pData)
2073 {
2074         // This callback comes whenever any new call is connected
2075         // Or, any "Held" call is activated (we ignore activation of "Held" calls).
2076         unsigned int newCallHandle = 0;
2077         TelCallStatusActiveNoti_t activeNotification;
2078         memcpy(&newCallHandle, pData, sizeof(TS_UINT));
2079         activeNotification.id = newCallHandle;
2080         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
2081
2082         //Check if the "Held" call was activated, i.e it is already present in already activated calls list.
2083         bool toHandleEvent = true;
2084         for (int callIndex = 0; (callIndex < pCallList->GetCount() && toHandleEvent == true); callIndex++ )
2085         {
2086                 AppCallInfo tempCallInfo;
2087                 pCallList->GetAt(callIndex, tempCallInfo);
2088                 unsigned int tempCallHandle = tempCallInfo.GetCallHandle()->ToLong();
2089                 //Check if active callback came for "HandleJoinCallbackResponse"
2090                 //or for "UnHold Conference Call or normal call".
2091                 if(tempCallInfo.IsConferenceCall() == true)
2092                 {
2093                         if (tempCallHandle == activeNotification.id)
2094                         {
2095                                 toHandleEvent = false;
2096                         }
2097                         else
2098                         {
2099                                 //check individual participants of conf call
2100                                 IListT<AppCallInfo>* pConfCallList = tempCallInfo.GetCallerList();
2101                                 int confCallCount  = pConfCallList->GetCount();
2102                                 for (int callIndex = 0; (callIndex < confCallCount && toHandleEvent == true); callIndex++)
2103                                 {
2104                                         AppCallInfo confCallerInfo;
2105                                         pConfCallList->GetAt(callIndex, confCallerInfo);
2106                                         unsigned int confCallerHandle = confCallerInfo.GetCallHandle()->ToLong();
2107                                         if (confCallerHandle == activeNotification.id)
2108                                         {
2109                                                 toHandleEvent = false;
2110                                         }
2111                                 }
2112                         }
2113                 }
2114                 else if(tempCallHandle == activeNotification.id)
2115                 {
2116                         //If normal call is UnHold
2117                         toHandleEvent = false;
2118                 }
2119         }
2120
2121         //check if we need to handle this event.
2122         if(toHandleEvent == true)
2123         {
2124                 //Here it comes, only if either new dialed or incoming call was connected.
2125                 HandleCallConnected( activeNotification.id);
2126         }
2127         delete pCallList;
2128         pCallList = null;
2129 }
2130
2131 void
2132 TelephonyManager::HandleCallConnected(unsigned int connectedCallHandle)
2133 {
2134         //Here it comes, only if either new dialed or incoming call was connected.
2135         //This function should be called only from "HandleActiveCallback()".
2136         AppCallInfo* pConnectedCall = null;
2137         //to check if incoming call was connected
2138         bool isIncomingCallConnected = false;
2139
2140         __pSoundManager->SetConnectTone();
2141         //Check if dialed call is connected.
2142         if ((__pDialedCall != null) && (connectedCallHandle == (unsigned int)__pDialedCall->GetCallHandle()->ToLong()))
2143         {
2144                 pConnectedCall = __pDialedCall;
2145                 __pDialedCall = null;
2146         }
2147         //Check if connected call is incoming call.
2148         else if (__pIncomingCall != null && (connectedCallHandle == (unsigned int)__pIncomingCall->GetCallHandle()->ToLong()))
2149         {
2150                 pConnectedCall = __pIncomingCall;
2151                 __pIncomingCall = null;
2152                 isIncomingCallConnected = true;
2153         }
2154         else
2155         {
2156                 // this is just for safety. This scenario should never come.
2157                 // Otherwise Correct the code in some other function, if it comes here.
2158                 AppLogDebug("Error - Connected call was neither one of active calls nor it was dialed or incoming call");
2159                 //Construct a new CallInfo object for call
2160                 pConnectedCall = new (std::nothrow) AppCallInfo();
2161                 pConnectedCall->SetCallHandle(connectedCallHandle);
2162
2163                 TelCallStatus_t callStatus;
2164                 int res = tel_get_call_status(__pTapiHandle, connectedCallHandle, &callStatus);
2165                 if (res == TAPI_CAUSE_SUCCESS)
2166                 {
2167                         String contactNumber(callStatus.pNumber);
2168                         pConnectedCall->SetContactNumber(contactNumber);
2169                         //set emergency state
2170                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2171                         {
2172                                 pConnectedCall->SetEmergency(true);
2173                         }
2174                         else
2175                         {
2176                                 pConnectedCall->SetEmergency(false);
2177                         }
2178                         //set call notification time
2179                         long long startTime = 0;
2180                         SystemTime::GetTicks(startTime);
2181                         pConnectedCall->SetCallNotificationTime(startTime);
2182                         if (callStatus.bMoCall == true)
2183                         {
2184                                 pConnectedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_OUTGOING);
2185                         }
2186                         else
2187                         {
2188                                 pConnectedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2189                                 isIncomingCallConnected = true;
2190                         }
2191                 }
2192                 //delete any dialed or incoming call objects
2193                 delete __pDialedCall;
2194                 __pDialedCall = null;
2195                 delete __pIncomingCall;
2196                 __pIncomingCall = null;
2197         }
2198
2199         //fetch contact info for connected call & it is not a hidden call
2200         if (pConnectedCall->GetContactInfo() == null && pConnectedCall->GetContactNumber().IsEmpty() == false)
2201         {
2202                 FetchContactInfoForNumber(pConnectedCall->GetContactNumber());
2203                 if (__pCachedContact != null)
2204                 {
2205                         pConnectedCall->SetContactInfo(*(__pCachedContact));
2206                 }
2207         }
2208         //set Call connect time for newly connected call
2209         long long startTime = 0;
2210         SystemTime::GetTicks(startTime);
2211         pConnectedCall->SetCallConnectTime(startTime);
2212         if(GetCurrentCallCount() == 0)
2213         {
2214                 __pSoundManager->SetMinuteReminderTone();
2215         }
2216
2217
2218         //transfer ownership to Active calls list
2219         __pActiveCallList->Add(connectedCallHandle, *(pConnectedCall));
2220 /*      if (pConnectedCall->GetCalllogType() == CALL_LOG_TYPE_VOICE_INCOMING)
2221         {
2222                 SaveCallInfoToLogsDb(*pConnectedCall);
2223         }*/
2224         pConnectedCall = null;
2225
2226         //notify listener that call is connected.
2227         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
2228         __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
2229         __pEventListener->HandleCallConnected(*pCallList);
2230         if (isIncomingCallConnected == true)
2231         {
2232                 __pSoundManager->StopAlert();
2233         }
2234         delete pCallList;
2235         pCallList = null;
2236 }
2237
2238 bool
2239 TelephonyManager::CheckIncomingCallToBeRejected(AppCallInfo* pIncomingCallInfo)
2240 {
2241         AppLogDebug("Enter");
2242         int callHandle = pIncomingCallInfo->GetCallHandle()->ToLong();
2243         String contactNumber(L"");
2244         contactNumber.Append(pIncomingCallInfo->GetContactNumber());
2245         //Check if "reject unknown calls" is set and contact number is not present in AddressBook
2246         //or if contact number is blacklisted
2247         if(__pSettingsManager != null)
2248         {
2249                 if (((__pSettingsManager->GetUnknownRejectStatus() == true) && (pIncomingCallInfo->GetContactInfo() == null))
2250                                 || (__pSettingsManager->IsCallToBeRejected(contactNumber) == true))
2251                 {
2252                         AnswerAutoRejectCall(callHandle);
2253                         return true;
2254                 }
2255         }
2256         return false;
2257 }
2258
2259 void
2260 TelephonyManager::HandleCallback(TapiHandle* pHandle, const char* pNotiId, void* pData, void* pUserData)
2261 {
2262         AppLogDebug("Enter");
2263         unsigned int tempHandle = 0;
2264         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
2265         if (pTelManager->__pSoundManager == null)
2266         {
2267                 AppLog("Creating Sound Manager");
2268                 pTelManager->__pSoundManager = new (std::nothrow) SoundManager();
2269         }
2270         //Handle telephony events
2271         if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0)
2272         {
2273                 pTelManager->HandleIdleCallBack(pData);
2274         }
2275         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE) == 0)
2276         {
2277                 pTelManager->__pSoundManager->StartSession();
2278                 pTelManager->HandleActiveCallBack(pData);
2279         }
2280         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_DIALING) == 0)
2281         {
2282                 pTelManager->HandleDialingCallBack(pData);
2283         }
2284         else
2285         {
2286                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2287         }
2288 }
2289
2290 AppCallInfo*
2291 TelephonyManager::GetConferenceCallInfoN(void)
2292 {
2293         AppCallInfo* pConfCallInfo = null;
2294
2295         IListT<AppCallInfo>* pCallList = __pActiveCallList->GetValuesN();
2296         int callCount = pCallList->GetCount();
2297         for (int index = 0; index < callCount; index++)
2298         {
2299                 AppCallInfo callInfo;
2300                 pCallList->GetAt(index, callInfo);
2301                 if (callInfo.IsConferenceCall() == true)
2302                 {
2303                         pConfCallInfo = new (std::nothrow) AppCallInfo();
2304                         *pConfCallInfo = callInfo;
2305                         //Found the Conference call
2306                         break;
2307                 }
2308         }
2309         delete pCallList;
2310         pCallList = null;
2311
2312         return pConfCallInfo;
2313 }
2314
2315 IListT<AppCallInfo>*
2316 TelephonyManager::GetCallListN(void)
2317 {
2318         ArrayListT<AppCallInfo>* pCallList = null;
2319         if (__pActiveCallList != null)
2320         {
2321                 pCallList = static_cast<ArrayListT<AppCallInfo>*>(__pActiveCallList->GetValuesN());
2322         }
2323         return pCallList;
2324 }
2325
2326 int
2327 TelephonyManager::GetCurrentCallCount(void)
2328 {
2329         if (__pActiveCallList != null)
2330         {
2331                 return __pActiveCallList->GetCount();
2332         }
2333         return 0;
2334 }
2335
2336 void
2337 TelephonyManager::StartAlert(AppCallInfo& incomingCallInfo)
2338 {
2339         String contactRingTone(L"");
2340         String contactNumber = incomingCallInfo.GetContactNumber();
2341         //check if not hidden call
2342         if(contactNumber.IsEmpty() == false)
2343         {
2344                 //fetch contact info from Db
2345                 Contact* foundContact = GetContactN(contactNumber);
2346                 if(foundContact != null)
2347                 {
2348                         //fetch custom ringtone for contact
2349                         result r = foundContact->GetValue(CONTACT_PROPERTY_ID_RINGTONE, contactRingTone);
2350                         //Now check if there is a group ring tone
2351                         if(contactRingTone.IsEmpty() == true)
2352                         {
2353                                 IList* pCategoryList = __pAddressBook->GetCategoriesByContactN(foundContact->GetRecordId());
2354                                 if(pCategoryList != null && pCategoryList->GetCount() > 0)
2355                                 {
2356                                         Category* pCategory = static_cast<Category*>(pCategoryList->GetAt(0));
2357                                         contactRingTone = pCategory->GetRingtonePath();
2358                                 }
2359                         }
2360                         AppLog("ringtone fetched - r = %d", r);
2361                         delete foundContact;
2362                         foundContact = null;
2363                 }
2364         }
2365         __pSoundManager->StartAlert(contactRingTone);
2366 }
2367
2368 void
2369 TelephonyManager::StopAlert(void)
2370 {
2371         __pSoundManager->StopAlert();
2372 }
2373
2374 result
2375 TelephonyManager::CheckValidTelePhoneNumber(const String& contactNumber)
2376 {
2377         result r = E_SUCCESS;
2378         if (contactNumber.GetLength() > TAPI_CALL_DIALDIGIT_LEN_MAX)
2379         {
2380                 r = E_FAILURE;
2381         }
2382
2383         //Pattern to compare all characters except 0-9 * # P ; , +
2384         String phoneNumberPattern(L"[^0-9*#P,p+;]");
2385         RegularExpression checkPhoneNumber;
2386         checkPhoneNumber.Construct(phoneNumberPattern);
2387         //If there is any character other than these listed above then display invalid number
2388         bool resultMatch = checkPhoneNumber.Match(contactNumber,false);
2389         //return false for patterns other than 0-9 * # P ; , +
2390         if(resultMatch == true)
2391         {
2392                 //return phone number is invalid
2393                 r = E_FAILURE;
2394         }
2395         //TODO: check if valid phone number else return error message
2396         return r;
2397 }
2398
2399 result
2400 TelephonyManager::CheckIfMOCallIsPossible()
2401 {
2402         result r = E_SUCCESS;
2403
2404         //Check modem power status
2405         int modemStatus = 0;
2406         int errorCode = tel_check_modem_power_status(__pTapiHandle, &modemStatus);
2407         if (errorCode != TAPI_API_SUCCESS || modemStatus == TAPI_PHONE_POWER_STATUS_OFF
2408                         || modemStatus == TAPI_PHONE_POWER_STATUS_ERROR)
2409         {
2410                 r = E_FAILURE;
2411         }
2412         else
2413         {
2414                 TelSimCardStatus_t simStatus;
2415                 int simChangedStatus;
2416                 //fetch sim initialization status
2417                 int errorCode = tel_get_sim_init_info(__pTapiHandle, &simStatus, &simChangedStatus);
2418                 if (errorCode != TAPI_API_SUCCESS)
2419                 {
2420                         r = E_FAILURE;
2421                 }
2422                 else
2423                 {
2424                         switch (simStatus)
2425                         {
2426                         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED: // Sim Initialization ok
2427                                 r = E_SUCCESS;
2428                                 break;
2429
2430                         case TAPI_SIM_STATUS_UNKNOWN: //initial state
2431                         case TAPI_SIM_STATUS_CARD_NOT_PRESENT: //Card not present
2432                         case TAPI_SIM_STATUS_CARD_REMOVED: //Card removed
2433                         case TAPI_SIM_STATUS_CARD_ERROR: // Bad card / On the fly, SIM gone bad
2434                                 //TODO: might want to set different error code, to give proper message to user
2435                                 r = E_FAILURE;
2436                                 break;
2437                         default:
2438                                 r = E_FAILURE;
2439                                 break;
2440                         }
2441                 }
2442         }
2443         return r;
2444 }
2445
2446 bool
2447 TelephonyManager::CheckIfMOCallIsEmergency(const String& contactNumber, bool isSimInitialized)
2448 {
2449         //TODO: extract actual telephone number from contactNumber
2450         //by deleting prefix,'P','W', etx.
2451
2452         bool isEmergency = false;
2453         //conversion "contactNumber" to char*
2454         const wchar_t* pContact = contactNumber.GetPointer();
2455         int len = contactNumber.GetLength() + 1;
2456         char* pNumber = new (std::nothrow) char[len];
2457         wcstombs(pNumber, pContact, len);
2458
2459         if(isSimInitialized)
2460         {
2461                 //used to get Ecc information for 2G and 3G.
2462                 TelSimEccList_t simEccList;
2463                 memset(&simEccList, 0x00, sizeof(TelSimEccList_t));
2464                 //Check if given number matches the sim card's emergency numbers
2465                 int errorCode = tel_get_sim_ecc(__pTapiHandle, &simEccList);
2466                 if (errorCode == TAPI_API_SUCCESS && simEccList.ecc_count > 0)
2467                 {
2468                         for (int index = 0; index < simEccList.ecc_count; index++)
2469                         {
2470                                 if ((strcmp(pNumber, simEccList.list[index].number) == 0))
2471                                 {
2472                                         isEmergency = true;
2473                                 }
2474                         }
2475                 }
2476         }
2477         else
2478         {
2479                 //TODO: check if we need to also check SOS call numbers, if sim not present.
2480         }
2481
2482         delete[] pNumber;
2483         pNumber = null;
2484         return isEmergency;
2485 }
2486
2487 result
2488 TelephonyManager::FetchContactInfoForNumber(const String& phoneNumberStr)
2489 {
2490         result r = E_FAILURE;
2491
2492         //delete previously cached data
2493         if (__pCachedContact != null)
2494         {
2495                 delete __pCachedContact;
2496                 __pCachedContact = null;
2497         }
2498
2499         //Searches contacts by phone number.
2500         IList* pContactList = __pAddressBook->SearchContactsByPhoneNumberN(phoneNumberStr);
2501         if (pContactList == null || IsFailed(GetLastResult()))
2502         {
2503                 return r;
2504         }
2505
2506         //Fetch the contact's info to be displayed
2507         IEnumerator* pContactEnum = pContactList->GetEnumeratorN();
2508         while ((E_SUCCESS == pContactEnum->MoveNext()) && (__pCachedContact == null))
2509         {
2510                 Contact* pContact = static_cast<Contact*>(pContactEnum->GetCurrent());
2511
2512                 IList* pPhoneNumberList = pContact->GetValuesN(CONTACT_MPROPERTY_ID_PHONE_NUMBERS);
2513                 if (pPhoneNumberList != null)
2514                 {
2515                         IEnumerator* pPhoneEnum = pPhoneNumberList->GetEnumeratorN();
2516                         while (E_SUCCESS == pPhoneEnum->MoveNext())
2517                         {
2518                                 PhoneNumber* pPhoneNumber = (PhoneNumber*) pPhoneEnum->GetCurrent();
2519                                 //Check if this is the correct contact
2520                                 if (pPhoneNumber->GetPhoneNumber().Equals(phoneNumberStr))
2521                                 {
2522                                         //save newly fetched contact info.
2523                                         __pCachedContact = new (std::nothrow) Contact(*pContact);
2524                                         r = E_SUCCESS;
2525                                         break;
2526                                 }
2527                         }
2528                         delete pPhoneEnum;
2529                         pPhoneNumberList->RemoveAll(true);
2530                         delete pPhoneNumberList;
2531                 }
2532         }
2533         delete pContactEnum;
2534         pContactList->RemoveAll(true);
2535         delete pContactList;
2536
2537         return r;
2538 }
2539
2540 Contact*
2541 TelephonyManager::GetContactN(const String& phoneNumber)
2542 {
2543         result r = FetchContactInfoForNumber(phoneNumber);
2544         if (!IsFailed(r))
2545         {
2546                 return new (std::nothrow) Contact(*__pCachedContact);
2547         }
2548         return null;
2549 }
2550
2551 AppCallInfo*
2552 TelephonyManager::FetchIncomingCallHandleN(const String& callHandle, const String& contactNumber)
2553 {
2554         if(__pIncomingCall != null)
2555         {
2556                 delete __pIncomingCall;
2557                 __pIncomingCall = null;
2558         }
2559
2560         if(callHandle.IsEmpty() == false)
2561         {
2562                 int incomingHandle;
2563                 Integer::Parse(callHandle,incomingHandle);
2564                 //This API call is synchronous
2565                 TelCallStatus_t callStatus;
2566                 int errCode = tel_get_call_status(__pTapiHandle, incomingHandle, &callStatus);
2567                 if (errCode != TAPI_API_SUCCESS)
2568                 {
2569                         AppLogDebug("tel_get_call_status failed");
2570                         return null;
2571                 }
2572                 //construct incoming call info object
2573                 __pIncomingCall = new (std::nothrow) AppCallInfo();
2574                 __pIncomingCall->SetCallHandle(incomingHandle);
2575
2576                 //contact number
2577                 String phoneNumber(contactNumber);
2578                 if(phoneNumber.IsEmpty() == true)
2579                 {
2580                         phoneNumber.Append(callStatus.pNumber);
2581                 }
2582                 __pIncomingCall->SetContactNumber(phoneNumber);
2583                 //set emergency state
2584                 if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2585                 {
2586                         __pIncomingCall->SetEmergency(true);
2587                 }
2588                 else
2589                 {
2590                         __pIncomingCall->SetEmergency(false);
2591                 }
2592                 //set start time, when call is connected
2593                 long long startTime = 0;
2594                 SystemTime::GetTicks(startTime);
2595                 __pIncomingCall->SetCallNotificationTime(startTime);
2596                 __pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2597         }
2598         else
2599         {
2600                 //TODO: This 'else' block can be removed once AppControl request API is stabilized.
2601                 //This API call is synchronous and 'HandleIncomingCallStatusCallBack' is called for each active call.
2602                 int errCode = tel_get_call_status_all(__pTapiHandle, &HandleIncomingCallStatusCallBack, this);
2603                 if (errCode != TAPI_API_SUCCESS)
2604                 {
2605                         return null;
2606                 }
2607         }
2608
2609         if(__pIncomingCall != null)
2610         {
2611                 //set call notification time
2612                 long long startTime = 0;
2613                 SystemTime::GetTicks(startTime);
2614                 __pIncomingCall->SetCallNotificationTime(startTime);
2615
2616                 if(__pIncomingCall->GetContactNumber().IsEmpty() == false)
2617                 {
2618                         //fetch contact info
2619                         FetchContactInfoForNumber(__pIncomingCall->GetContactNumber());
2620                         if (__pCachedContact != null)
2621                         {
2622                                 __pIncomingCall->SetContactInfo(*__pCachedContact);
2623                         }
2624                 }
2625
2626                 //construct a new callinfo object to pass its ownership to caller.
2627                 AppCallInfo* pNewIncomingCall = new (std::nothrow) AppCallInfo();
2628                 *pNewIncomingCall = *__pIncomingCall;
2629                 return pNewIncomingCall;
2630         }
2631         //return null, if no incoming call found
2632         return null;
2633 }
2634
2635 void
2636 TelephonyManager::HandleIncomingCallStatusCallBack(TelCallStatus_t* pCallStatus, void* pUserData)
2637 {
2638         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
2639         if (pCallStatus != null && pCallStatus->bMoCall == false
2640                         && ((pCallStatus->CallState == TAPI_CALL_STATE_INCOMING)
2641                                         || (pCallStatus->CallState == TAPI_CALL_STATE_WAITING)))
2642         {
2643                 //construct incoming call details
2644                 pTelManager->__pIncomingCall = new (std::nothrow) AppCallInfo();
2645                 pTelManager->__pIncomingCall->SetCallHandle(pCallStatus->CallHandle);
2646                 //contact number
2647                 String contactNumber(pCallStatus->pNumber);
2648                 pTelManager->__pIncomingCall->SetContactNumber(contactNumber);
2649                 //set emergency state
2650                 if(pCallStatus->CallType == TAPI_CALL_TYPE_E911)
2651                 {
2652                         pTelManager->__pIncomingCall->SetEmergency(true);
2653                 }
2654                 else
2655                 {
2656                         pTelManager->__pIncomingCall->SetEmergency(false);
2657                 }
2658
2659                 pTelManager->__pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2660         }
2661 }
2662
2663 void
2664 TelephonyManager::SaveCallInfoToLogsDb(AppCallInfo& endCallInfo)
2665 {
2666         if (endCallInfo.IsConferenceCall() == false)
2667         {
2668                 //single active call - Add call ended to call log database
2669                 __pCalllogMgr->AddCallogInfoToDatabase(&endCallInfo);
2670         }
2671         else
2672         {
2673                 //Conference call
2674                 int confCallCount = endCallInfo.GetCallerListCount();
2675                 IListT<AppCallInfo>* pParticipantList = endCallInfo.GetCallerList();
2676                 for (int index = 0; index < confCallCount; index++)
2677                 {
2678                         AppCallInfo participantInfo;
2679                         if (pParticipantList->GetAt(index, participantInfo) == E_SUCCESS)
2680                         {
2681                                 //Add call ended to call log database
2682                                 __pCalllogMgr->AddCallogInfoToDatabase(&participantInfo);
2683                         }
2684                 }
2685         }
2686 }
2687
2688 void
2689 TelephonyManager::OnTelephonyNetworkStatusChanged(const NetworkStatus& networkStatus)
2690 {
2691         if(networkStatus.IsCallServiceAvailable() == false)
2692         {
2693                 EndAllCalls();
2694         }
2695 }
2696
2697 bool
2698 TelephonyManager::IsIncomingorDialingCallPresent(void)
2699 {
2700         //returns false, if incoming call or dialed call is present.
2701         return ((__pIncomingCall != null) || (__pDialedCall != null));
2702 }