Tizen 2.0 Release
[apps/osp/Phone.git] / src / PhnPhoneApp.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    PhnPhoneApp.cpp
19  * @brief   Phone Application UiApp file
20  */
21 #include <FUi.h>
22 #include "PhnCallInfo.h"
23 #include "PhnCallPresentationModel.h"
24 #include "PhnPhoneAppFrame.h"
25 #include "PhnPhoneApp.h"
26 #include "PhnSceneRegister.h"
27 #include "PhnSettingsPresentationModel.h"
28 #include "PhnTypes.h"
29 #include "PhnIAppStateChangeListner.h"
30
31 using namespace Tizen::App;
32 using namespace Tizen::Base;
33 using namespace Tizen::Base::Collection;
34 using namespace Tizen::Base::Utility;
35 using namespace Tizen::System;
36 using namespace Tizen::Ui;
37 using namespace Tizen::Ui::Controls;
38 using namespace Tizen::Ui::Scenes;
39
40 PhoneApp::PhoneApp(void) : __isOpenAsAppControl(false), __pLaunchArgs(null)
41                 , __initialSceneId(L"")
42 {
43         __listenerList.Construct();
44 }
45
46 PhoneApp::~PhoneApp(void)
47 {
48 }
49
50 UiApp*
51 PhoneApp::CreateInstance(void)
52 {
53         return new (std::nothrow) PhoneApp();
54 }
55
56 bool
57 PhoneApp::OnAppInitializing(AppRegistry& appRegistry)
58 {
59         AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
60         pProviderMgr->SetAppControlProviderEventListener(this);
61         return true;
62 }
63
64 bool
65 PhoneApp::OnAppInitialized(void)
66 {
67         AppLog("ENTER");
68         result r = E_FAILURE;
69         //Check if PhoneApp is opened as AppControl
70         if(__isOpenAsAppControl == false)
71         {
72                 //by default, initial scene is DIALER view
73                 __initialSceneId = IDSCN_DIALER;
74                 __pLaunchArgs = null;
75         }
76
77         // Initialize Frame and App specific data.
78         PhoneAppFrame* pPhoneAppFrame = new (std::nothrow) PhoneAppFrame();
79         pPhoneAppFrame->Construct();
80         pPhoneAppFrame->SetName(L"Phone");
81         r = AddFrame(*pPhoneAppFrame);
82         AppLog("EXIT");
83         return (!IsFailed(r));
84 }
85
86 bool
87 PhoneApp::OnAppWillTerminate(void)
88 {
89         return true;
90 }
91
92 bool
93 PhoneApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination)
94 {
95         return true;
96 }
97
98 void
99 PhoneApp::OnForeground(void)
100 {
101         IEnumerator* pEnum = __listenerList.GetEnumeratorN();
102         while (pEnum->MoveNext() == E_SUCCESS)
103         {
104                 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
105                 if (pInterface == null)
106                 {
107                         delete pEnum;
108
109                         return;
110                 }
111                 pInterface->OnForeground();
112         }
113         delete pEnum;
114 }
115
116 void
117 PhoneApp::OnBackground(void)
118 {
119         IEnumerator* pEnum = __listenerList.GetEnumeratorN();
120         while (pEnum->MoveNext() == E_SUCCESS)
121         {
122                 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
123                 if (pInterface == null)
124                 {
125                         delete pEnum;
126
127                         return;
128                 }
129                 pInterface->OnBackground();
130         }
131         delete pEnum;
132 }
133
134 void
135 PhoneApp::OnLowMemory(void)
136 {
137 }
138
139 void
140 PhoneApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
141 {
142 }
143
144 void
145 PhoneApp::OnScreenOn(void)
146 {
147 }
148
149 void
150 PhoneApp::OnScreenOff(void)
151 {
152 }
153
154 bool
155 PhoneApp::IsOpenAsAppControl(void)
156 {
157         return __isOpenAsAppControl;
158 }
159
160 SceneId
161 PhoneApp::GetInitialScene(void)
162 {
163         return __initialSceneId;
164 }
165
166 void
167 PhoneApp::SetInitialScene(SceneId initialSceneId)
168 {
169         __initialSceneId = initialSceneId;
170 }
171
172 IList*
173 PhoneApp::GetAppLaunchArguments(void)
174 {
175         return __pLaunchArgs;
176 }
177
178 void
179 PhoneApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
180                 const String* pMimeType, const IMap* pExtraData)
181 {
182         AppLogDebug("ENTER");
183         //process AppControl parameters
184         ProcessAppControlRequest(reqId, operationId, pExtraData);
185         AppLogDebug("EXIT");
186 }
187
188 void
189 PhoneApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap)
190 {
191         __pLaunchArgs = null;
192         if(operationId.Equals(OPERATION_ID_CALL,true))
193         {
194                 __isOpenAsAppControl = true;
195                 if(pArgsMap != null)
196                 {
197                         bool isIncomingCallRequest = false;
198                         String* pKey = new (std::nothrow) String(LAUNCHTYPE);
199                         if (pArgsMap->ContainsKey(*pKey) == true)
200                         {
201                                 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
202                                 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
203                                 {
204                                         isIncomingCallRequest = true;
205                                 }
206                         }
207                         //Check if incoming call request or outgoing call request
208                         if(isIncomingCallRequest == true)
209                         {
210                                 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
211                         }
212                         else
213                         {
214                                 HandleDialCallAppControlRequest(reqId, pArgsMap);
215                         }
216                 }
217         }
218         else if(operationId.Equals(OPERATION_ID_DIAL,true))
219         {
220                 __isOpenAsAppControl = true;
221                 HandleDialerAppControlRequest(reqId, pArgsMap);
222         }
223         else if (operationId.Equals(OPERATION_ID_CONFIGURE, true))
224         {
225                 __isOpenAsAppControl = true;
226                 HandleSettingsAppControlRequest(reqId, pArgsMap);
227         }
228 }
229
230 void
231 PhoneApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
232 {
233         SceneManager* pSceneManager = SceneManager::GetInstance();
234         //response message
235         AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
236
237         //call handle
238         String callHandle(L"");
239         String* pKey = new (std::nothrow) String(CALL_HANDLE);
240         if (pArgsMap->ContainsKey(*pKey) == true)
241         {
242                 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
243                 if (pValue != null)
244                 {
245                         callHandle.Append(*pValue);
246                 }
247         }
248         delete pKey;
249         //contact number
250         String contactNumber(L"");
251         pKey = new (std::nothrow) String(CONTACT_NUMBER);
252         if (pArgsMap->ContainsKey(*pKey) == true)
253         {
254                 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
255                 if (pContactValue != null)
256                 {
257                         contactNumber.Append(*pContactValue);
258                 }
259         }
260         delete pKey;
261         pKey = null;
262
263         //Fetch incoming call details
264         CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
265         CallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
266         if(pIncomingCall != null)
267         {
268                 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
269                 if(isCallRejected == false)
270                 {
271                         //save app launch argument list
272                         __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
273                         __pLaunchArgs->Construct(1);
274                         __pLaunchArgs->Add(pIncomingCall);
275                         if(__initialSceneId.IsEmpty() == true)
276                         {
277                                 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
278                         }
279                         else
280                         {
281                                 //App already initialized, goto incoming call form
282                                 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
283                                 __pLaunchArgs = null;
284                         }
285                 }
286                 else
287                 {
288                         //Show messageBox showing automatic call rejection
289                         MessageBox callRejectedInoMsgBox;
290                         String msg(L"Call From ");
291                         msg.Append(contactNumber);
292                         msg.Append(L" Rejected.");
293                         callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
294                         int modalResult = 0;
295                         // Calls ShowAndWait() : Draws and Shows itself and processes events
296                         callRejectedInoMsgBox.ShowAndWait(modalResult);
297
298                         //go back to previous scene if App was already running, else exit application.
299                         if(__initialSceneId.IsEmpty() == true)
300                         {
301                                 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
302                                 AppLog("Terminate Phone Application");
303                         }
304                         else if (pCallPresentor->GetCurrentCallCount() == 0)
305                         {
306                                 // NOTE: Let the user remain on whatever screen he/she is,
307                                 // but the framework will bring PhoneApp to foreground.
308                                 /*pSceneManager->GoForward(ForwardSceneTransition(__initialSceneId), null);*/
309                         }
310                 }
311                 //set success message
312                 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
313         }
314         else
315         {
316                 __isOpenAsAppControl = false;
317                 appControlResult = APP_CTRL_RESULT_FAILED;
318         }
319         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
320 }
321
322 void
323 PhoneApp::HandleDialerAppControlRequest(RequestId reqId,const IMap* pArgsMap)
324 {
325         //start Dial Form
326         if (pArgsMap != null)
327         {
328                 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
329                 if (pArgsMap->ContainsKey(*pKey) == true)
330                 {
331                         const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
332                         if (pPhoneValue != null)
333                         {
334                                 String* tmpStr = new (std::nothrow) String(*pPhoneValue);
335                                 __pLaunchArgs =  new (std::nothrow) ArrayList(SingleObjectDeleter);
336                                 __pLaunchArgs->Construct();
337                                 __pLaunchArgs->Add(tmpStr);
338                         }
339                 }
340                 delete pKey;
341         }
342
343         //Check if app is already launched
344         if(__initialSceneId.IsEmpty() == true)
345         {
346                 __initialSceneId = IDSCN_DIALER;
347         }
348         else
349         {
350                 SceneManager* pSceneManager = SceneManager::GetInstance();
351                 pSceneManager->GoForward( ForwardSceneTransition(IDSCN_DIALER, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
352                                 SCENE_HISTORY_OPTION_NO_HISTORY),__pLaunchArgs);
353                 __pLaunchArgs = null;
354         }
355         //response message
356         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, APP_CTRL_RESULT_SUCCEEDED, null);
357 }
358
359 void
360 PhoneApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
361 {
362         //response message
363         AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
364
365         if (pArgsMap != null)
366         {
367                 String callType(L"");
368                 String phoneNumber(L"");
369                 //phone number
370                 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
371                 if(pArgsMap->ContainsKey(*pKey) == true)
372                 {
373                         const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
374                         if(pPhoneValue != null)
375                         {
376                                 phoneNumber.Append(*pPhoneValue);
377                         }
378                 }
379                 delete pKey;
380                 //call type
381                 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
382                 if(pArgsMap->ContainsKey(*pKey) == true)
383                 {
384                         const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
385                         if(pCallTypeValue != null)
386                         {
387                                 callType.Append(*pCallTypeValue);
388                         }
389                 }
390                 delete pKey;
391                 pKey = null;
392
393                 //Fetch currently active call count
394                 if (callType.IsEmpty() == false
395                                 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
396                                 && phoneNumber.IsEmpty() == false)
397                 {
398                         CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
399                         int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
400                         if(currentActiveCallCount <= 1)
401                         {
402                                 //make an outgoing call with given number
403                                 String* contactTxt = new (std::nothrow) String(phoneNumber);
404                                 __pLaunchArgs =  new (std::nothrow) ArrayList(SingleObjectDeleter);
405                                 __pLaunchArgs->Construct();
406                                 __pLaunchArgs->Add(contactTxt);
407                                 bool isEmergencyCall = pCallPresentor->IsEmergencyNumber(*contactTxt, true);
408
409                                 SceneId nextScene = IDSCN_SCENE_OUTCALL;
410                                 if (isEmergencyCall)
411                                 {
412                                         nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
413                                 }
414
415                                 //Check if app was already running
416                                 if(__initialSceneId.IsEmpty() == true)
417                                 {
418                                         //phone App is not already launched
419                                         __initialSceneId = nextScene;
420                                 }
421                                 else
422                                 {
423                                         SceneManager* pSceneManager = SceneManager::GetInstance();
424                                         pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
425                                 }
426                                 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
427                         }
428                         else
429                         {
430                                 //already 2 active calls, 3rd call not allowed
431                                 appControlResult = APP_CTRL_RESULT_CANCELED;
432                         }
433                 }
434                 else
435                 {
436                         appControlResult = APP_CTRL_RESULT_FAILED;
437                 }
438         }
439         //send response message
440         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
441 }
442
443 void
444 PhoneApp::HandleSettingsAppControlRequest(RequestId reqId,const IMap* pArgsMap)
445 {
446         if(__initialSceneId.IsEmpty() == true)
447         {
448                 __initialSceneId = IDSCN_SCENE_MAIN_SETTING_MENU;
449         }
450         else
451         {
452                 SceneManager* pSceneManager = SceneManager::GetInstance();
453                 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_MAIN_SETTING_MENU), null);
454         }
455         //send response message
456         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, APP_CTRL_RESULT_SUCCEEDED, null);
457 }
458
459 void
460 PhoneApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
461 {
462         __listenerList.Add(listener);
463
464 }
465 void
466 PhoneApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
467 {
468         __listenerList.Remove(listener);
469 }
470
471