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