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                 // show Thumbnail bitmap on photo Label
411                 pPhotoLbl->SetBackgroundBitmap(*pPhotoBitmap);
412                 pPhotoLbl->Invalidate(true);
413                 delete pPhotoBitmap;
414         }
415         else
416         {
417                 //Set Default Photo
418                 Bitmap* pDefaultPhoto = AppUtility::GetBitmapFromResourcesN(IDB_END_CALL_DEFAULT_ICON,W_PHOTO_LABEL,H_PHOTO_LABEL);
419                 if (pDefaultPhoto != null)
420                 {
421                         pPhotoLbl->SetBackgroundBitmap(*pDefaultPhoto);
422                         pPhotoLbl->Invalidate(true);
423                         delete pDefaultPhoto;
424                 }
425         }
426         RequestRedraw(true);
427         //free resources
428         if (pDisplayName)
429         {
430                 delete pDisplayName;
431                 pDisplayName = null;
432         }
433 }
434
435 void
436 EndCallForm::ShowCallersPhotoThumbnail(const Bitmap& pPhotoId)
437 {
438         if (__pSmallPhotoLabel != null)
439         {
440                 RemoveControl(*__pSmallPhotoLabel);
441                 __pSmallPhotoLabel = null;
442         }
443         //Draw Small Photo and show on small photo label
444         __pSmallPhotoLabel  = new (std::nothrow) Label();//static_cast<Label*>(GetControl(IDC_SMALL_PHOTO_LABEL));
445         __pSmallPhotoLabel->Construct(Rectangle(X_PHOTO_LBL, Y_PHOTO_LBL, W_PHOTO_LBL, H_PHOTO_LBL), L"");
446         __pSmallPhotoLabel->SetBackgroundColor(Color(0,0,0));
447         __pSmallPhotoLabel->SetBackgroundBitmap(pPhotoId);
448         // Add a Label to the Form
449         AddControl(*__pSmallPhotoLabel);
450         __pSmallPhotoLabel->Invalidate(true);
451 }
452
453 void
454 EndCallForm::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
455 {
456         //goto initial scene or close application, since this was last active call.
457         HandleLastCallCompletion();
458 }
459
460 void
461 EndCallForm::OnAppControlCompleteResponseReceived(const AppId& appId, const String& operationId, AppCtrlResult appControlResult, const IMap* pExtraData)
462 {
463         if (__isMsgAppControlLaunched == true)
464         {
465                 //Message AppControl request completed.
466                 __isMsgAppControlLaunched = false;
467         }
468         //AppControl completed, goto initial scene if present
469         //else exit.
470         HandleLastCallCompletion();
471 }
472
473 void
474 EndCallForm::HandleLastCallCompletion(void)
475 {
476         //switch back to Dialer tab, based on starting state of call.
477         SceneManager* pSceneManager = SceneManager::GetInstance();
478         PhoneApp* pPhoneApp = (static_cast<PhoneApp*>(UiApp::GetInstance()));
479         SceneId nextSceneId = pPhoneApp->GetInitialScene();
480         if (pSceneManager->GetCurrentScene()->GetSceneId() == IDSCN_SCENE_ENDCALL)
481         {
482                 if(nextSceneId == IDSCN_DIALER || nextSceneId == IDSCN_CALL_LOG)
483                 {
484                         pSceneManager->GoForward( ForwardSceneTransition(nextSceneId, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
485                                 SCENE_HISTORY_OPTION_NO_HISTORY));
486                 }
487                 else
488                 {
489                         pPhoneApp->Terminate();
490                 }
491         }
492 }
493
494 void
495 EndCallForm::OnForeground(void)
496 {
497         AppLogDebug("Enter");
498         //If Contact app control was launched
499         //as we do not know if it success or failed.
500         __isContactAppControlLaunched = false;
501 }
502
503 void
504 EndCallForm::OnBackground(void)
505 {
506         AppLogDebug("Enter");
507 }