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