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