Tizen 2.0 Release
[apps/osp/Phone.git] / src / PhnEndCallForm.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file    PhnEndCallForm.cpp
19  * @brief       End Call form implementation
20  */
21 #include <FApp.h>
22 #include <FUi.h>
23 #include <FMedia.h>
24 #include "PhnPhoneApp.h"
25 #include "PhnAppUtility.h"
26 #include "PhnEndCallForm.h"
27 #include "PhnCallButtonsPanel.h"
28 #include "PhnCallPresentationModel.h"
29 #include "PhnSceneRegister.h"
30 #include "PhnTypes.h"
31
32 using namespace Tizen::App;
33 using namespace Tizen::Base;
34 using namespace Tizen::Base::Collection;
35 using namespace Tizen::Graphics;
36 using namespace Tizen::Media;
37 using namespace Tizen::Ui;
38 using namespace Tizen::Ui::Controls;
39 using namespace Tizen::Ui::Scenes;
40
41 //constants
42 const int IDI_APP_END_TIMER = 3000;
43 const int W_PHOTO_LABEL = 720;
44 const int H_PHOTO_LABEL = 720;
45 const int X_PHOTO_LBL = 166;
46 const int Y_PHOTO_LBL = 232;
47 const int W_PHOTO_LBL = 388;
48 const int H_PHOTO_LBL = 388;
49 static const wchar_t* IDL_END_CALL_FORM = L"IDL_END_CALL_FORM";
50 static const wchar_t* IDC_ADD_TO_CONTACT_BUTTON = L"IDC_ADD_TO_CONTACT_BUTTON";
51 static const wchar_t* IDC_NUMBER1_LABEL = L"IDC_NUMBER1_LABEL";
52 static const wchar_t* IDC_CALLER1_LABEL = L"IDC_CALLER1_LABEL";
53 static const wchar_t* IDC_CALLER1_BIGPHOTO_LABEL = L"IDC_CALLER1_BIGPHOTO_LABEL";
54 static const wchar_t* IDB_END_CALL_DEFAULT_ICON = L"C01-1_end call_default_caller ID_720x720.png";
55
56 EndCallForm::EndCallForm(void)
57 : BaseForm(FORMTYPE_ENDCALL)
58 {
59         __pCallButtonsPanel = null;
60         __pContactNumber = null;
61         __pEndCallEventTimer = null;
62         __pSmallPhotoLabel = null;
63         __isMsgAppControlLaunched = false;
64         __isContactAppControlLaunched = false;
65 }
66
67 EndCallForm::~EndCallForm(void)
68 {
69         if (__pEndCallEventTimer != null)
70         {
71                 __pEndCallEventTimer->Cancel();
72                 delete __pEndCallEventTimer;
73                 __pEndCallEventTimer = null;
74         }
75         if (__pSmallPhotoLabel != null)
76         {
77                 RemoveControl(*__pSmallPhotoLabel);
78                 __pSmallPhotoLabel = null;
79         }
80 }
81
82 void
83 EndCallForm::Initialize(void)
84 {
85         Construct(IDL_END_CALL_FORM);
86         //initialize keypad and buttons
87         InitializeCallButtonsPanel();
88         //set initial show state to false. Correct state set on OnSceneActivatedN
89         SetContactButtonState(false);
90 }
91
92 result
93 EndCallForm::OnInitializing(void)
94 {
95         result r = E_SUCCESS;
96
97         AddKeyPadActionListener(IDC_ADD_TO_CONTACT_BUTTON, IDA_ADD_TO_CONTACTS);
98
99         __pEndCallEventTimer = new (std::nothrow) Tizen::Base::Runtime::Timer();
100         r = __pEndCallEventTimer->Construct(*this);
101
102         __pCallPresentor = CallPresentationModel::GetInstance();
103         return r;
104 }
105
106 void
107 EndCallForm::InitializeCallButtonsPanel(void)
108 {
109         __pCallButtonsPanel = new (std::nothrow) CallButtonsPanel();
110         __pCallButtonsPanel->ConstructPanel(this, FORMTYPE_ENDCALL);
111         AddControl(*__pCallButtonsPanel);
112 }
113
114 void
115 EndCallForm::AddKeyPadActionListener(const String& keyName, CommandIds cmdId)
116 {
117         Button* pButton = static_cast<Button*>(GetControl(keyName));
118         if (pButton != null)
119         {
120                 pButton->SetActionId(cmdId);
121                 pButton->AddActionEventListener(*this);
122         }
123 }
124
125 result
126 EndCallForm::OnTerminating(void)
127 {
128         result r = E_SUCCESS;
129
130         if (__pCallPresentor)
131         {
132                 __pCallPresentor = null;
133         }
134         return r;
135 }
136
137 void
138 EndCallForm::OnActionPerformed(const Control& source, int actionId)
139 {
140         SceneManager* pSceneManager = SceneManager::GetInstance();
141         AppAssert(pSceneManager);
142
143         switch (actionId)
144         {
145         case IDA_VOICE_CALL:
146         {
147                 //check if EndCallTimer is running, then cancel it
148                 if(__pEndCallEventTimer != null)
149                 {
150                         __pEndCallEventTimer->Cancel();
151                 }
152                 //make an outgoing call with given number
153                 String* contactTxt = new (std::nothrow) String(*__pContactNumber);
154                 //switch to dialing outgoing call form
155                 ArrayList* pContact = new (std::nothrow) ArrayList(SingleObjectDeleter);
156                 pContact->Construct();
157                 pContact->Add(contactTxt);
158
159                 //Check if dialing a call is possible
160                 bool isSimInitialized = __pCallPresentor->CheckSimInitializationIsCompleted();
161                 if (isSimInitialized)
162                 {
163                         //Check if dialing an emergency call
164                         bool isEmergencyCall = __pCallPresentor->IsEmergencyNumber(*contactTxt, true);
165                         if (isEmergencyCall)
166                         {
167                                 pSceneManager->GoForward( ForwardSceneTransition( IDSCN_SCENE_OUT_EMERGENCYCALL), pContact);
168                         }
169                         else
170                         {
171                                 pSceneManager->GoForward( ForwardSceneTransition(IDSCN_SCENE_OUTCALL), pContact);
172                         }
173                 }
174                 else
175                 {
176                         //Show error message Popup
177                         HandleTelephonyError(ERROR_CODE_SIM_INITIALIZATION_FAILED);
178                 }
179         }
180         break;
181
182         case IDA_VIDEO_CALL:
183                 //Make Video Call
184                 break;
185
186         case IDA_MESSAGE:
187         {
188                 if (__isMsgAppControlLaunched == true)
189                 {
190                         //AppControl already launched.
191                         return;
192                 }
193                 //launch message AppControl
194                 __isMsgAppControlLaunched = true;
195                 result r = E_SUCCESS;
196                 HashMap extraData;
197                 extraData.Construct();
198
199                 extraData.Add(new (std::nothrow) String(MESSAGE_TYPE), new (std::nothrow) String(MESSAGE_SMS_TYPE));
200                 extraData.Add(new (std::nothrow) String(MESSAGE_TO), new (std::nothrow) String(*__pContactNumber));
201
202                 AppControl* pAc = AppManager::FindAppControlN(PROVIDER_ID_MESSAGE, OPERATION_ID_COMPOSE);
203                 if (pAc != null)
204                 {
205                         r = pAc->Start(null, null, &extraData, this);
206                         if(r != E_SUCCESS)
207                         {
208                                 //AppControl request failed, reset flag.
209                                 __isMsgAppControlLaunched = false;
210                         }
211                         else if (r == E_SUCCESS && __pEndCallEventTimer != null)
212                         {
213                                 //cancel EndCallTimer, if AppControl request was successful.
214                                 __pEndCallEventTimer->Cancel();
215                         }
216                         delete pAc;
217                 }
218
219                 extraData.RemoveAll(true);
220         }
221         break;
222
223         case IDA_ADD_TO_CONTACTS:
224         {
225                 if(__isContactAppControlLaunched == true)
226                 {
227                         //AppControl already launched.
228                         return;
229                 }
230                 //Launch Contact AppControl
231                 __isContactAppControlLaunched = true;
232                 result r = E_SUCCESS;
233                 HashMap extraData;
234                 extraData.Construct();
235
236                 extraData.Add(new (std::nothrow) String(INPUT_TYPE_PHONE), new (std::nothrow) String(*__pContactNumber));
237                 AppControl* pAc = AppManager::FindAppControlN(PROVIDER_ID_CONTACTS, OPERATION_ID_ADD);
238                 if (pAc != null)
239                 {
240                         r = pAc->Start(null, null, &extraData, this);
241                         if(r != E_SUCCESS)
242                         {
243                                 //AppControl request failed, reset flag.
244                                 __isContactAppControlLaunched = false;
245                         }
246                         else if (r == E_SUCCESS && __pEndCallEventTimer != null)
247                     {
248                         //cancel EndCallTimer, if AppControl request was success.
249                         __pEndCallEventTimer->Cancel();
250
251                         //NOTE:- goto next scene if present and is either Call log or Dialer,
252                         // Else forcefully goto Dialer scene.
253                         //Because we do not get any Appcontrol Completed response from Contacts in this case.
254                         SceneId nextScene = (static_cast<PhoneApp*>(UiApp::GetInstance()))->GetInitialScene();
255                         if(nextScene != IDSCN_CALL_LOG)
256                         {
257                                 nextScene = IDSCN_DIALER;
258                         }
259                                 pSceneManager->GoForward( ForwardSceneTransition(nextScene,
260                                                                 SCENE_TRANSITION_ANIMATION_TYPE_NONE,
261                                                                 SCENE_HISTORY_OPTION_NO_HISTORY));
262                     }
263                         delete pAc;
264                 }
265                 extraData.RemoveAll(true);
266         }
267         break;
268
269         default:
270                 break;
271         }
272 }
273
274 void
275 EndCallForm::OnSceneActivatedN(const SceneId& previousSceneId, const SceneId& currentSceneId, IList* pArgs)
276 {
277         //set itself as listener
278         __pCallPresentor->SetTelEventListener(this);
279         //listen to Foreground events
280         PhoneApp* pPhoneApp = static_cast<PhoneApp*>(PhoneApp::GetInstance());
281         pPhoneApp->AddAppStateChangeListener(*this);
282         __isMsgAppControlLaunched = false;
283         __isContactAppControlLaunched = false;
284
285         switch (__formType)
286         {
287         case FORMTYPE_ENDCALL:
288         {
289                 //fetch ended call details
290                 CallInfo* pEndCall = static_cast<CallInfo*>(pArgs->GetAt(0));
291
292                 //contact number
293                 __pContactNumber = new (std::nothrow) String();
294                 __pContactNumber->Append(pEndCall->GetContactNumber());
295
296                 //Fetch & show contact person details
297                 ShowPersonDetails(*__pContactNumber, IDC_CALLER1_LABEL, IDC_CALLER1_BIGPHOTO_LABEL,pEndCall);
298                 //If call is hidden means no contact number is present,
299                 //or if call is from known number, Then do NOT show "Add to Contact" button.
300                 if (pEndCall->IsNumberPresent() == true || pEndCall->GetContactNumber().IsEmpty() == true)
301                 {
302                         SetContactButtonState(false);
303                 }
304                 else
305                 {
306                         SetContactButtonState(true);
307                 }
308
309                 //Check if call is Emergency call or Hidden call,
310                 //then disable all button in Call button panel.
311                 if (pEndCall->IsEmergency() == true || pEndCall->GetContactNumber().IsEmpty() == true)
312                 {
313                         __pCallButtonsPanel->SetEndCallPanelState(false);
314                 }
315                 else
316                 {
317                         __pCallButtonsPanel->SetEndCallPanelState(true);
318                 }
319         }
320         break;
321
322         default:
323                 break;
324         }
325
326         if (__pEndCallEventTimer)
327         {
328                 __pEndCallEventTimer->Start(IDI_APP_END_TIMER);
329         }
330
331         if (pArgs)
332         {
333                 pArgs->RemoveAll();
334                 delete pArgs;
335                 pArgs = null;
336         }
337 }
338
339 void
340 EndCallForm::OnSceneDeactivated(const SceneId& currentSceneId, const SceneId& nextSceneId)
341 {
342         if (__pContactNumber)
343         {
344                 delete __pContactNumber;
345                 __pContactNumber = null;
346         }
347         if (__pSmallPhotoLabel != null)
348         {
349                 __pSmallPhotoLabel->SetShowState(false);
350         }
351         //remove itself as listener
352         PhoneApp* pPhoneApp = static_cast<PhoneApp*>(PhoneApp::GetInstance());
353         pPhoneApp->RemoveAppStateChangeListener(*this);
354 }
355
356 result
357 EndCallForm::OnDraw(void)
358 {
359         return E_SUCCESS;
360 }
361
362 void
363 EndCallForm::SetContactButtonState(bool showState)
364 {
365         Button* pButton = static_cast<Button*>(GetControl(IDC_ADD_TO_CONTACT_BUTTON));
366         if (pButton != null)
367         {
368                 pButton->SetShowState(showState);
369         }
370 }
371
372 void
373 EndCallForm::ShowPhoneNumber(const String& phoneNumber, const String& lblName)
374 {
375         String formattedNumber = phoneNumber;
376         Label* pContactLbl = static_cast<Label*>(GetControl(lblName));
377         pContactLbl->SetText(formattedNumber);
378 }
379
380 void
381 EndCallForm::ShowPersonDetails(const String& phoneNumber, const String& nameLblName, const String& photoLblName, CallInfo* pCallInfo)
382 {
383         //show phone number
384         ShowPhoneNumber(phoneNumber, IDC_NUMBER1_LABEL);
385
386         Label* pNameLbl = static_cast<Label*>(GetControl(nameLblName));
387         Label* pPhotoLbl = static_cast<Label*>(GetControl(photoLblName));
388
389         //fetch contact details based on phone number
390         String* pDisplayName = pCallInfo->FetchCallerNameN();
391         Bitmap* pPhotoBitmap = pCallInfo->FetchCallerPhotoN();
392
393         //passing an empty string to SetText fails in label,
394         //if previously valid text has been set
395         if (pDisplayName != null && pDisplayName->IsEmpty() == true && pNameLbl->GetText().IsEmpty() == false)
396         {
397                 pDisplayName->Append(L" ");
398         }
399
400         // show display name on name Label
401         if (pDisplayName != null)
402         {
403                 pNameLbl->SetText(*pDisplayName);
404         }
405
406         // If record not found or no photo id present for user,
407         //fetch default bitmap.
408         if (pPhotoBitmap != null)
409         {
410                 Canvas* pCanvas = new (std::nothrow) Canvas;
411                 Rectangle canvasRect(Rectangle(0, 0, pPhotoLbl->GetBounds().width, pPhotoLbl->GetBounds().height));
412                 pCanvas->Construct(canvasRect);
413                 //draw the contact bitmap
414                 pCanvas->DrawBitmap(canvasRect,*pPhotoBitmap);
415                 Bitmap* pNewPhotoId = new Bitmap();
416                 pNewPhotoId->Construct(*pCanvas, pCanvas->GetBounds());
417                 delete pCanvas;
418
419                 pPhotoLbl->SetBackgroundBitmap(*pNewPhotoId);
420                 pPhotoLbl->Invalidate(true);
421                 delete pNewPhotoId;
422         }
423         else
424         {
425                 //Set Default Photo
426                 Bitmap* pDefaultPhoto = AppUtility::GetBitmapFromResourcesN(IDB_END_CALL_DEFAULT_ICON,W_PHOTO_LABEL,H_PHOTO_LABEL);
427                 if (pDefaultPhoto != null)
428                 {
429                         pPhotoLbl->SetBackgroundBitmap(*pDefaultPhoto);
430                         pPhotoLbl->Invalidate(true);
431                         delete pDefaultPhoto;
432                 }
433         }
434         RequestRedraw(true);
435         //free resources
436         if (pDisplayName)
437         {
438                 delete pDisplayName;
439                 pDisplayName = null;
440         }
441         if (pPhotoBitmap)
442         {
443                 delete pPhotoBitmap;
444                 pPhotoBitmap = null;
445         }
446 }
447
448 void
449 EndCallForm::ShowCallersPhotoThumbnail(const Bitmap& pPhotoId)
450 {
451         if (__pSmallPhotoLabel != null)
452         {
453                 RemoveControl(*__pSmallPhotoLabel);
454                 __pSmallPhotoLabel = null;
455         }
456         //Draw Small Photo and show on small photo label
457         __pSmallPhotoLabel  = new (std::nothrow) Label();//static_cast<Label*>(GetControl(IDC_SMALL_PHOTO_LABEL));
458         __pSmallPhotoLabel->Construct(Rectangle(X_PHOTO_LBL, Y_PHOTO_LBL, W_PHOTO_LBL, H_PHOTO_LBL), L"");
459         __pSmallPhotoLabel->SetBackgroundColor(Color(0,0,0));
460         __pSmallPhotoLabel->SetBackgroundBitmap(pPhotoId);
461         // Add a Label to the Form
462         AddControl(*__pSmallPhotoLabel);
463         __pSmallPhotoLabel->Invalidate(true);
464 }
465
466 void
467 EndCallForm::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
468 {
469         //goto initial scene or close application, since this was last active call.
470         HandleLastCallCompletion();
471 }
472
473 void
474 EndCallForm::OnAppControlCompleteResponseReceived(const AppId& appId, const String& operationId, AppCtrlResult appControlResult, const IMap* pExtraData)
475 {
476         if (__isMsgAppControlLaunched == true)
477         {
478                 //Message AppControl request completed.
479                 __isMsgAppControlLaunched = false;
480         }
481         //AppControl completed, goto initial scene if present
482         //else exit.
483         HandleLastCallCompletion();
484 }
485
486 void
487 EndCallForm::HandleLastCallCompletion(void)
488 {
489         //switch back to Dialer tab, based on starting state of call.
490         SceneManager* pSceneManager = SceneManager::GetInstance();
491         PhoneApp* pPhoneApp = (static_cast<PhoneApp*>(UiApp::GetInstance()));
492         SceneId nextSceneId = pPhoneApp->GetInitialScene();
493         if (pSceneManager->GetCurrentScene()->GetSceneId() == IDSCN_SCENE_ENDCALL)
494         {
495                 if(nextSceneId == IDSCN_DIALER || nextSceneId == IDSCN_CALL_LOG)
496                 {
497                         pSceneManager->GoForward( ForwardSceneTransition(nextSceneId, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
498                                 SCENE_HISTORY_OPTION_NO_HISTORY));
499                 }
500                 else
501                 {
502                         pPhoneApp->Terminate();
503                 }
504         }
505 }
506
507 void
508 EndCallForm::OnForeground(void)
509 {
510         AppLogDebug("Enter");
511         //If Contact app control was launched
512         //as we do not know if it success or failed.
513         __isContactAppControlLaunched = false;
514 }
515
516 void
517 EndCallForm::OnBackground(void)
518 {
519         AppLogDebug("Enter");
520 }