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